The code lets us define event-specific rate limits. In more than a
decade, we've only ever used the same 1s limit for all rate-limited
events. Drop the ability and simplify.
Signed-off-by: Markus Armbruster <armbru@redhat.com>
---
monitor/monitor.c | 56 ++++++++++++++++++++------------------------
monitor/trace-events | 2 +-
2 files changed, 26 insertions(+), 32 deletions(-)
diff --git a/monitor/monitor.c b/monitor/monitor.c
index 87f6e4860b..5be2ec02c2 100644
--- a/monitor/monitor.c
+++ b/monitor/monitor.c
@@ -46,9 +46,8 @@ typedef struct MonitorQAPIEventState {
QDict *qdict; /* Delayed event (if any) */
} MonitorQAPIEventState;
-typedef struct {
- int64_t rate; /* Minimum time (in ns) between two events */
-} MonitorQAPIEventConf;
+/* Minimum time (in ns) between events if the event is rate-limited */
+#define EVENT_RATE (1000 * SCALE_MS)
/* Shared monitor I/O thread */
IOThread *mon_iothread;
@@ -268,19 +267,6 @@ void monitor_printc(Monitor *mon, int c)
monitor_printf(mon, "'");
}
-static MonitorQAPIEventConf monitor_qapi_event_conf[QAPI_EVENT__MAX] = {
- /* Limit guest-triggerable events to 1 per second */
- [QAPI_EVENT_RTC_CHANGE] = { 1000 * SCALE_MS },
- [QAPI_EVENT_BLOCK_IO_ERROR] = { 1000 * SCALE_MS },
- [QAPI_EVENT_WATCHDOG] = { 1000 * SCALE_MS },
- [QAPI_EVENT_BALLOON_CHANGE] = { 1000 * SCALE_MS },
- [QAPI_EVENT_QUORUM_REPORT_BAD] = { 1000 * SCALE_MS },
- [QAPI_EVENT_QUORUM_FAILURE] = { 1000 * SCALE_MS },
- [QAPI_EVENT_VSERPORT_CHANGE] = { 1000 * SCALE_MS },
- [QAPI_EVENT_MEMORY_DEVICE_SIZE_CHANGE] = { 1000 * SCALE_MS },
- [QAPI_EVENT_HV_BALLOON_STATUS_REPORT] = { 1000 * SCALE_MS },
-};
-
/*
* Return the clock to use for recording an event's time.
* It's QEMU_CLOCK_REALTIME, except for qtests it's
@@ -319,14 +305,23 @@ static void monitor_qapi_event_emit(QAPIEvent event, QDict *qdict)
}
}
-static int64_t monitor_event_rate_limit(QAPIEvent event, QDict *data)
+static bool monitor_event_is_rate_limited(QAPIEvent event, QDict *data)
{
- MonitorQAPIEventConf *evconf;
- int64_t rate_limit;
+ static bool event_is_ratelimited[QAPI_EVENT__MAX] = {
+ [QAPI_EVENT_RTC_CHANGE] = true,
+ [QAPI_EVENT_BLOCK_IO_ERROR] = true,
+ [QAPI_EVENT_WATCHDOG] = true,
+ [QAPI_EVENT_BALLOON_CHANGE] = true,
+ [QAPI_EVENT_QUORUM_REPORT_BAD] = true,
+ [QAPI_EVENT_QUORUM_FAILURE] = true,
+ [QAPI_EVENT_VSERPORT_CHANGE] = true,
+ [QAPI_EVENT_MEMORY_DEVICE_SIZE_CHANGE] = true,
+ [QAPI_EVENT_HV_BALLOON_STATUS_REPORT] = true,
+ };
+ bool rate_limited;
assert(event < QAPI_EVENT__MAX);
- evconf = &monitor_qapi_event_conf[event];
- rate_limit = evconf->rate;
+ rate_limited = event_is_ratelimited[event];
/*
* Rate limit BLOCK_IO_ERROR only for action != "stop".
@@ -340,11 +335,11 @@ static int64_t monitor_event_rate_limit(QAPIEvent event, QDict *data)
if (event == QAPI_EVENT_BLOCK_IO_ERROR) {
const char *action = qdict_get_str(data, "action");
if (!strcmp(action, "stop")) {
- rate_limit = 0;
+ rate_limited = false;
}
}
- return rate_limit;
+ return rate_limited;
}
static void monitor_qapi_event_handler(void *opaque);
@@ -357,14 +352,14 @@ static void
monitor_qapi_event_queue_no_reenter(QAPIEvent event, QDict *qdict)
{
QDict *data = qobject_to(QDict, qdict_get(qdict, "data"));
- int64_t rate_limit = monitor_event_rate_limit(event, data);
+ bool rate_limited = monitor_event_is_rate_limited(event, data);
MonitorQAPIEventState *evstate;
- trace_monitor_protocol_event_queue(event, qdict, rate_limit);
+ trace_monitor_protocol_event_queue(event, qdict, rate_limited);
QEMU_LOCK_GUARD(&monitor_lock);
- if (!rate_limit) {
+ if (!rate_limited) {
/* Unthrottled event */
monitor_qapi_event_emit(event, qdict);
} else {
@@ -375,7 +370,7 @@ monitor_qapi_event_queue_no_reenter(QAPIEvent event, QDict *qdict)
if (evstate) {
/*
- * Timer is pending for (at least) @rate_limit ns after
+ * Timer is pending for (at least) @EVENT_RATE ns after
* last send. Store event for sending when timer fires,
* replacing a prior stored event if any.
*/
@@ -385,7 +380,7 @@ monitor_qapi_event_queue_no_reenter(QAPIEvent event, QDict *qdict)
/*
* Last send was (at least) @rate_limit ns ago.
* Send immediately, and arm the timer to call
- * monitor_qapi_event_handler() in @rate_limit ns. Any
+ * monitor_qapi_event_handler() in @EVENT_RATE ns. Any
* events arriving before then will be delayed until then.
*/
int64_t now = qemu_clock_get_ns(monitor_get_event_clock());
@@ -400,7 +395,7 @@ monitor_qapi_event_queue_no_reenter(QAPIEvent event, QDict *qdict)
monitor_qapi_event_handler,
evstate);
g_hash_table_add(monitor_qapi_event_state, evstate);
- timer_mod_ns(evstate->timer, now + rate_limit);
+ timer_mod_ns(evstate->timer, now + EVENT_RATE);
}
}
}
@@ -454,7 +449,6 @@ void qapi_event_emit(QAPIEvent event, QDict *qdict)
static void monitor_qapi_event_handler(void *opaque)
{
MonitorQAPIEventState *evstate = opaque;
- MonitorQAPIEventConf *evconf = &monitor_qapi_event_conf[evstate->event];
trace_monitor_protocol_event_handler(evstate->event, evstate->qdict);
QEMU_LOCK_GUARD(&monitor_lock);
@@ -465,7 +459,7 @@ static void monitor_qapi_event_handler(void *opaque)
monitor_qapi_event_emit(evstate->event, evstate->qdict);
qobject_unref(evstate->qdict);
evstate->qdict = NULL;
- timer_mod_ns(evstate->timer, now + evconf->rate);
+ timer_mod_ns(evstate->timer, now + EVENT_RATE);
} else {
g_hash_table_remove(monitor_qapi_event_state, evstate);
qobject_unref(evstate->data);
diff --git a/monitor/trace-events b/monitor/trace-events
index 032d1220e1..7f0b4b9dd9 100644
--- a/monitor/trace-events
+++ b/monitor/trace-events
@@ -6,7 +6,7 @@ handle_hmp_command(void *mon, const char *cmdline) "mon %p cmdline: %s"
# monitor.c
monitor_protocol_event_handler(uint32_t event, void *qdict) "event=%d data=%p"
monitor_protocol_event_emit(uint32_t event, void *data) "event=%d data=%p"
-monitor_protocol_event_queue(uint32_t event, void *qdict, uint64_t rate) "event=%d data=%p rate=%" PRId64
+monitor_protocol_event_queue(uint32_t event, void *qdict, bool rate_limited) "event=%d data=%p rate_limited=%d"
monitor_suspend(void *ptr, int cnt) "mon %p: %d"
# qmp.c
--
2.53.0
© 2016 - 2026 Red Hat, Inc.