[PATCH V12 06/15] monitor: track IOThread users with QOM paths
Zhang Chen <[email protected]>
| Newsgroups | org.nongnu.qemu-devel |
|---|---|
| Message-ID | <[email protected]> |
Monitors that require an IOThread share the internal mon_iothread, but this relationship is not currently visible through query-iothreads. Management applications therefore cannot determine which monitors are using the IOThread. Acquire the shared monitor IOThread AioContext once, using the monitor QOM path as the holder, and reuse the stored context for later operations. Release the holder during global cleanup and dynamic QMP monitor deletion to provide an explicit acquire/release lifecycle and prevent query-iothreads from reporting stale monitor holders. Signed-off-by: Zhang Chen <[email protected]> --- monitor/monitor-internal.h | 3 +++ monitor/monitor.c | 26 +++++++++++++++++++++----- monitor/qmp.c | 16 ++++++++++++++-- 3 files changed, 38 insertions(+), 7 deletions(-) diff --git a/monitor/monitor-internal.h b/monitor/monitor-internal.h index 23829f32f9..caecceec93 100644 --- a/monitor/monitor-internal.h +++ b/monitor/monitor-internal.h @@ -153,6 +153,9 @@ struct Monitor { guint out_watch; int mux_out; int reset_seen; + + /* iothread context */ + AioContext *ctx; }; struct MonitorHMPClass { diff --git a/monitor/monitor.c b/monitor/monitor.c index ed195fd97b..40944caf9d 100644 --- a/monitor/monitor.c +++ b/monitor/monitor.c @@ -573,7 +573,7 @@ void monitor_suspend(Monitor *mon) * Kick I/O thread to make sure this takes effect. It'll be * evaluated again in prepare() of the watch object. */ - aio_notify(iothread_get_aio_context(mon_iothread)); + aio_notify(mon->ctx); } trace_monitor_suspend(mon, 1); @@ -668,6 +668,17 @@ void monitor_cleanup(void) qemu_mutex_unlock(&monitor_lock); monitor_flush(mon); qemu_mutex_lock(&monitor_lock); + + if (monitor_requires_iothread(mon)) { + g_autofree char *path = object_get_canonical_path(OBJECT(mon)); + const IOThreadHolder io_holder = { + .type = IO_THREAD_HOLDER_KIND_QOM_OBJECT, + .u.qom_object.qom_path = path, + }; + + iothread_unref_and_put_aio_context(mon_iothread, &io_holder); + mon->ctx = NULL; + } object_unparent(OBJECT(mon)); } qemu_mutex_unlock(&monitor_lock); @@ -713,7 +724,6 @@ char *monitor_compat_id(void) static void monitor_complete(UserCreatable *uc, Error **errp) { Monitor *mon = MONITOR(uc); - AioContext *ctx; if (mon->chardev_id) { Chardev *chr = qemu_chr_find(mon->chardev_id); @@ -732,11 +742,17 @@ static void monitor_complete(UserCreatable *uc, Error **errp) mon_iothread = iothread_create("mon_iothread", &error_abort); } - ctx = iothread_get_aio_context(mon_iothread); + g_autofree char *path = object_get_canonical_path(OBJECT(mon)); + const IOThreadHolder io_holder = { + .type = IO_THREAD_HOLDER_KIND_QOM_OBJECT, + .u.qom_object.qom_path = path, + }; + + mon->ctx = iothread_ref_and_get_aio_context(mon_iothread, &io_holder); } else { - ctx = qemu_get_aio_context(); + mon->ctx = qemu_get_aio_context(); } - mon->accept_input_bh = aio_bh_new(ctx, monitor_accept_input, mon); + mon->accept_input_bh = aio_bh_new(mon->ctx, monitor_accept_input, mon); } int monitor_new(MonitorOptions *opts, bool allow_hmp, Error **errp) diff --git a/monitor/qmp.c b/monitor/qmp.c index 338d37cb7e..245f54a3af 100644 --- a/monitor/qmp.c +++ b/monitor/qmp.c @@ -733,7 +733,8 @@ static void monitor_qmp_complete(UserCreatable *uc, Error **errp) * thread. Schedule a bottom half. */ mon->setup_pending = true; - aio_bh_schedule_oneshot(iothread_get_aio_context(mon_iothread), + + aio_bh_schedule_oneshot(MONITOR(mon)->ctx, monitor_qmp_setup_handlers_bh, mon); /* The bottom half will add @mon to @mon_list */ } else { @@ -788,7 +789,7 @@ static bool monitor_qmp_prepare_delete(UserCreatable *uc, Error **errp) /* Synchronize with in-flight iothread callbacks. */ if (monitor_requires_iothread(mon)) { - aio_wait_bh_oneshot(iothread_get_aio_context(mon_iothread), + aio_wait_bh_oneshot(MONITOR(mon)->ctx, monitor_qmp_iothread_quiesce, NULL); } @@ -796,6 +797,17 @@ static bool monitor_qmp_prepare_delete(UserCreatable *uc, Error **errp) monitor_qmp_drain_queue(qmp); monitor_fdsets_cleanup(); + if (monitor_requires_iothread(mon)) { + g_autofree char *path = object_get_canonical_path(OBJECT(mon)); + const IOThreadHolder io_holder = { + .type = IO_THREAD_HOLDER_KIND_QOM_OBJECT, + .u.qom_object.qom_path = path, + }; + + iothread_unref_and_put_aio_context(mon_iothread, &io_holder); + mon->ctx = NULL; + } + return true; } -- 2.54.0