VSERPORT_CHANGE is emitted when the guest opens or closes a virtio-serial port. The event's member "id" identifies the port.
When several events arrive quickly, throttling drops all but the last of them. Because of that, a QMP client must assume that *any* port may have changed state when it receives a VSERPORT_CHANGE event and throttling may have happened. Make the event more useful by throttling it for each port separately. Marc-André recently posted 'monitor: throttle VSERPORT_CHANGED by "id"' to do the same thing. Why am I redoing his work? Let me explain. In master, event throttling works per QAPIEvent. Throttling state is kept in MonitorQAPIEventState monitor_qapi_event_state[]. Going from event to throttling state is a simple array subscript. Marc-André's series makes the code governing throttling pluggable per event. MonitorQAPIEventState gets two new members, the governor function and an opaque. It loses the actual throttling state. That one's now in new type MonitorQAPIEventPending. The standard governor has the opaque point to a single MonitorQAPIEventPending. The governor for VSERPORT_CHANGED has the opaque point to a hash table mapping "id" to MonitorQAPIEventPending. In my review, I challenged the complexity of this solution, but Marc-André thinks it's justified. That leaves me two choices: concede the point, or come up with something that's actually simpler. My solution doesn't make anything pluggable. Instead, I simply generalize the map from event to throttling state. Instead of using just the QAPIEvent as key for looking up state, I permit additional use of event-specific data. For VSERPORT_CHANGED, I additionally use "id". monitor_qapi_event_state[] becomes a hash table. No callbacks, no type-punning, less code, and fewer code paths to test. PATCH 1-3 clean up the code some before I start. PATCH 2 may fix bugs, but to be sure I'd have to think some more about the old code. PATCH 4-6 do the actual work. PATCH 7 fixes docs to mention throttling. Diffstat for monitor.c Marc-André's series: 201 insertions(+), 55 deletions(-) mine: 115 insertions(+), 78 deletions(-) Here's an easy way to test this: run QEMU with four virtserial ports: -device virtio-serial,id=vser \ -device virtserialport,id=vser1,nr=1 \ -device virtserialport,id=vser2,nr=2 \ -device virtserialport,id=vser3,nr=3 \ -device virtserialport,id=vser4,nr=4 Connect to QMP so you can observe events. Boot a Linux guest. Run something like # for ((i=0; i<100; i++)); do cat /dev/vport0p$((i % 4 + 1)); done You'll get four VSERPORT_CHANGED events (one for each of the four ports) immediately, and another four after a second. Before this series, you'll get only two. Markus Armbruster (7): monitor: Reduce casting of QAPI event QDict monitor: Simplify event throttling monitor: Switch from timer_new() to timer_new_ns() monitor: Split MonitorQAPIEventConf off MonitorQAPIEventState monitor: Turn monitor_qapi_event_state[] into a hash table monitor: Throttle event VSERPORT_CHANGE separately by "id" docs: Document QMP event rate limiting docs/qmp-events.txt | 12 ++++ docs/qmp-spec.txt | 5 ++ monitor.c | 192 ++++++++++++++++++++++++++++++---------------------- trace-events | 4 +- 4 files changed, 131 insertions(+), 82 deletions(-) -- 2.4.3