[PATCH V6 06/14] monitor: Update tracking iothread users with holder name

Zhang Chen posted 14 patches 1 day, 2 hours ago
Maintainers: Kevin Wolf <kwolf@redhat.com>, Hanna Reitz <hreitz@redhat.com>, Stefano Stabellini <sstabellini@kernel.org>, Anthony PERARD <anthony@xenproject.org>, "Edgar E. Iglesias" <edgar.iglesias@gmail.com>, Stefan Hajnoczi <stefanha@redhat.com>, "Michael S. Tsirkin" <mst@redhat.com>, Paolo Bonzini <pbonzini@redhat.com>, Fam Zheng <fam@euphon.net>, John Levon <john.levon@nutanix.com>, Thanos Makatos <thanos.makatos@nutanix.com>, "Cédric Le Goater" <clg@redhat.com>, David Hildenbrand <david@kernel.org>, "Dr. David Alan Gilbert" <dave@treblig.org>, Markus Armbruster <armbru@redhat.com>, Zhang Chen <zhangckid@gmail.com>, Li Zhijian <lizhijian@fujitsu.com>, Jason Wang <jasowang@redhat.com>, Eric Blake <eblake@redhat.com>
[PATCH V6 06/14] monitor: Update tracking iothread users with holder name
Posted by Zhang Chen 1 day, 2 hours ago
Since the Monitor struct is not a QOM Object, we cannot use
object_get_canonical_path(). Instead, this patch uses the monitor's
name (or a default type-based name) as the holder identifier.

Cache the AioContext in the Monitor struct to avoid repeated calls to
iothread_get_aio_context() and ensure symmetrical ref/unref during
monitor lifecycle.

Signed-off-by: Zhang Chen <zhangckid@gmail.com>
---
 monitor/monitor-internal.h |  3 +++
 monitor/monitor.c          | 24 ++++++++++++++++++++++--
 monitor/qmp.c              |  3 ++-
 3 files changed, 27 insertions(+), 3 deletions(-)

diff --git a/monitor/monitor-internal.h b/monitor/monitor-internal.h
index feca111ae3..51cedf90e4 100644
--- a/monitor/monitor-internal.h
+++ b/monitor/monitor-internal.h
@@ -116,6 +116,9 @@ struct Monitor {
     guint out_watch;
     int mux_out;
     int reset_seen;
+
+    /* iothread context */
+    AioContext *ctx;
 };
 
 struct MonitorHMP {
diff --git a/monitor/monitor.c b/monitor/monitor.c
index 00b93ed612..b6efe776d6 100644
--- a/monitor/monitor.c
+++ b/monitor/monitor.c
@@ -529,7 +529,7 @@ int 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);
@@ -564,7 +564,7 @@ void monitor_resume(Monitor *mon)
         AioContext *ctx;
 
         if (mon->use_io_thread) {
-            ctx = iothread_get_aio_context(mon_iothread);
+            ctx = mon->ctx;
         } else {
             ctx = qemu_get_aio_context();
         }
@@ -612,6 +612,18 @@ void monitor_data_init(Monitor *mon, bool is_qmp, bool skip_flush,
 {
     if (use_io_thread && !mon_iothread) {
         monitor_iothread_init();
+        /*
+         * Because of current Monitor is not a QOM Object,
+         * so using OBJECT(mon) is undefined behavior and may crash.
+         * Try using a hard-coded future implementation of the qom path instead.
+         * (Like the name of the "mon_iothread").
+         * long-term solution would be making Monitor QOM, after that change
+         * here to:
+         * g_autofree path = object_get_canonical_path(OBJECT(mon));
+         */
+        g_autofree char *path = g_strdup(is_qmp ? "/monitor/qmp_mon0" :
+                                                  "/monitor/hmp_mon0");
+        mon->ctx = iothread_ref_and_get_aio_context(mon_iothread, path);
     }
     qemu_mutex_init(&mon->mon_lock);
     mon->is_qmp = is_qmp;
@@ -631,6 +643,14 @@ void monitor_data_destroy(Monitor *mon)
     }
     g_string_free(mon->outbuf, true);
     qemu_mutex_destroy(&mon->mon_lock);
+
+    if (mon->ctx && mon_iothread) {
+        g_autofree char *path = g_strdup(monitor_is_qmp(mon) ?
+                                        "/monitor/qmp_mon0" :
+                                        "/monitor/hmp_mon0");
+        iothread_put_aio_context(mon_iothread, path);
+        mon->ctx = NULL;
+    }
 }
 
 void monitor_cleanup(void)
diff --git a/monitor/qmp.c b/monitor/qmp.c
index 687019811f..8e4a775fac 100644
--- a/monitor/qmp.c
+++ b/monitor/qmp.c
@@ -549,7 +549,8 @@ void monitor_init_qmp(Chardev *chr, bool pretty, Error **errp)
          * since chardev might be running in the monitor I/O
          * thread.  Schedule a bottom half.
          */
-        aio_bh_schedule_oneshot(iothread_get_aio_context(mon_iothread),
+        Monitor *mon_p = &mon->common;
+        aio_bh_schedule_oneshot(mon_p->ctx,
                                 monitor_qmp_setup_handlers_bh, mon);
         /* The bottom half will add @mon to @mon_list */
     } else {
-- 
2.49.0