[PATCH V6 13/14] qapi: examine IOThread attachment status via query-iothreads

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 13/14] qapi: examine IOThread attachment status via query-iothreads
Posted by Zhang Chen 1 day, 2 hours ago
Extend the 'IOThreadInfo' structure to include attachment metrics.
This allows users to monitor the associated devices by identify them
by their QOM paths.

New fields added to IOThreadInfo:
- @holders: IoThreadHolder(QOM path or block node name) of the devices
            currently associated with this iothread.

These fields are also exposed via the Human Monitor Interface (HMP)
command 'info iothreads' to assist with manual debugging and
performance tuning.

Signed-off-by: Zhang Chen <zhangckid@gmail.com>
---
 iothread.c         | 22 ++++++++++++++++++++++
 monitor/hmp-cmds.c | 22 ++++++++++++++++++++++
 qapi/misc.json     | 16 ++++++++++++++--
 3 files changed, 58 insertions(+), 2 deletions(-)

diff --git a/iothread.c b/iothread.c
index 60a024f770..70bc5fb62a 100644
--- a/iothread.c
+++ b/iothread.c
@@ -24,6 +24,8 @@
 #include "qemu/error-report.h"
 #include "qemu/rcu.h"
 #include "qemu/main-loop.h"
+#include "qapi/clone-visitor.h"
+#include "qapi/qapi-visit-misc.h"
 
 
 #ifdef CONFIG_POSIX
@@ -93,6 +95,25 @@ static void iothread_unref(IOThread *iothread, const char *holder)
     object_unref(OBJECT(iothread));
 }
 
+static IoThreadHolderList *iothread_get_holders_list(IOThread *iothread)
+{
+    IoThreadHolderList *head = NULL;
+    IoThreadHolderList **prev = &head;
+    GList *l;
+
+    for (l = iothread->holders; l; l = l->next) {
+        IoThreadHolder *src = l->data;
+        IoThreadHolderList *entry = g_new0(IoThreadHolderList, 1);
+
+        entry->value = QAPI_CLONE(IoThreadHolder, src);
+
+        *prev = entry;
+        prev = &entry->next;
+    }
+
+    return head;
+}
+
 static void *iothread_run(void *opaque)
 {
     IOThread *iothread = opaque;
@@ -434,6 +455,7 @@ static int query_one_iothread(Object *object, void *opaque)
     info = g_new0(IOThreadInfo, 1);
     info->id = iothread_get_id(iothread);
     info->thread_id = iothread->thread_id;
+    info->holders = iothread_get_holders_list(iothread);
     info->poll_max_ns = iothread->poll_max_ns;
     info->poll_grow = iothread->poll_grow;
     info->poll_shrink = iothread->poll_shrink;
diff --git a/monitor/hmp-cmds.c b/monitor/hmp-cmds.c
index bc26b39d70..344eaf330b 100644
--- a/monitor/hmp-cmds.c
+++ b/monitor/hmp-cmds.c
@@ -198,11 +198,33 @@ void hmp_info_iothreads(Monitor *mon, const QDict *qdict)
     IOThreadInfoList *info_list = qmp_query_iothreads(NULL);
     IOThreadInfoList *info;
     IOThreadInfo *value;
+    IoThreadHolderList *h;
 
     for (info = info_list; info; info = info->next) {
         value = info->value;
         monitor_printf(mon, "%s:\n", value->id);
         monitor_printf(mon, "  thread_id=%" PRId64 "\n", value->thread_id);
+        monitor_printf(mon, "  holders=");
+        if (value->holders) {
+            for (h = value->holders; h; h = h->next) {
+                IoThreadHolder *holder = h->value;
+
+                switch (holder->type) {
+                case IO_THREAD_HOLDER_KIND_BLOCK_NODE:
+                    monitor_printf(mon, "[block-node: %s]",
+                                   holder->u.block_node.data);
+                    break;
+                case IO_THREAD_HOLDER_KIND_QOM_OBJECT:
+                    monitor_printf(mon, "[qom: %s]",
+                                   holder->u.qom_object.data);
+                    break;
+                default:
+                    monitor_printf(mon, "[unknown]");
+                    break;
+                }
+            }
+            monitor_printf(mon, "\n");
+        }
         monitor_printf(mon, "  poll-max-ns=%" PRId64 "\n", value->poll_max_ns);
         monitor_printf(mon, "  poll-grow=%" PRId64 "\n", value->poll_grow);
         monitor_printf(mon, "  poll-shrink=%" PRId64 "\n", value->poll_shrink);
diff --git a/qapi/misc.json b/qapi/misc.json
index d65d8012b2..e173d54a5e 100644
--- a/qapi/misc.json
+++ b/qapi/misc.json
@@ -94,7 +94,8 @@
 # @IoThreadHolderKind:
 #
 # @block-node: Block node name.
-# @qom-object: Standard QOM path.
+#
+# @qom-object: QOM path.
 #
 # Since: 11.0
 ##
@@ -104,7 +105,7 @@
 ##
 # @IoThreadHolder:
 #
-# @type: Current IoThread holder type support QOM path and Block node.
+# @type: Current IoThread holder type support QOM path and block node.
 #
 # Since: 11.0
 ##
@@ -124,6 +125,13 @@
 #
 # @thread-id: ID of the underlying host thread
 #
+# @holders: IoThreadHolder(QOM path or block node name) of the devices
+#     currently associated with this iothread.  Users can pre-allocate
+#     multiple iothread objects to serve as a persistent thread pool.
+#     When a device is hot-unplugged, it is detached from its
+#     iothread, but the iothread remains available, allowing future
+#     hot-plugged devices to attach to it.
+#
 # @poll-max-ns: maximum polling time in ns, 0 means polling is
 #     disabled (since 2.9)
 #
@@ -141,6 +149,7 @@
 { 'struct': 'IOThreadInfo',
   'data': {'id': 'str',
            'thread-id': 'int',
+           'holders': ['IoThreadHolder'],
            'poll-max-ns': 'int',
            'poll-grow': 'int',
            'poll-shrink': 'int',
@@ -166,6 +175,8 @@
 #              {
 #                 "id":"iothread0",
 #                 "thread-id":3134,
+#                 "holders":["/machine/peripheral/blk1/virtio-backend",
+#                            "/machine/peripheral/blk0/virtio-backend"],
 #                 "poll-max-ns":32768,
 #                 "poll-grow":0,
 #                 "poll-shrink":0,
@@ -174,6 +185,7 @@
 #              {
 #                 "id":"iothread1",
 #                 "thread-id":3135,
+#                 "holders":["/machine/peripheral/blk2/virtio-backend"],
 #                 "poll-max-ns":32768,
 #                 "poll-grow":0,
 #                 "poll-shrink":0,
-- 
2.49.0