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

Zhang Chen posted 13 patches 1 month, 1 week ago
Maintainers: Kevin Wolf <kwolf@redhat.com>, Hanna Reitz <hreitz@redhat.com>, Stefan Hajnoczi <stefanha@redhat.com>, Stefano Stabellini <sstabellini@kernel.org>, Anthony PERARD <anthony@xenproject.org>, "Edgar E. Iglesias" <edgar.iglesias@gmail.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>
There is a newer version of this series
[PATCH V5 13/13] qapi: examine IOThread attachment status via query-iothreads
Posted by Zhang Chen 1 month, 1 week 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: A string containing of QOM paths for the attached devices.

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         | 14 ++++++++++++++
 monitor/hmp-cmds.c | 13 +++++++++++++
 qapi/misc.json     | 13 +++++++++++++
 3 files changed, 40 insertions(+)

diff --git a/iothread.c b/iothread.c
index da98fbb9ad..ecd09f396e 100644
--- a/iothread.c
+++ b/iothread.c
@@ -64,6 +64,19 @@ static void iothread_unref(IOThread *iothread, const char *holder)
     }
 }
 
+static strList *iothread_get_holders_list(IOThread *iothread)
+{
+    strList *head = NULL;
+    strList **tail = &head;
+    GList *l;
+
+    for (l = iothread->holders; l != NULL; l = l->next) {
+        QAPI_LIST_APPEND(tail, g_strdup(l->data));
+    }
+
+    return head;
+}
+
 static void *iothread_run(void *opaque)
 {
     IOThread *iothread = opaque;
@@ -405,6 +418,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 bad034937a..d01ebba94d 100644
--- a/monitor/hmp-cmds.c
+++ b/monitor/hmp-cmds.c
@@ -203,6 +203,19 @@ void hmp_info_iothreads(Monitor *mon, const QDict *qdict)
         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) {
+            monitor_printf(mon, "\n");
+        } else {
+            strList *h;
+            bool first = true;
+            for (h = value->holders; h; h = h->next) {
+                monitor_printf(mon, "%s%s", first ? "" : "\n          ",
+                               h->value);
+                first = false;
+            }
+            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 1f5062df2a..a381074c04 100644
--- a/qapi/misc.json
+++ b/qapi/misc.json
@@ -76,6 +76,15 @@
 #
 # @thread-id: ID of the underlying host thread
 #
+# @holders: The parameter is an array of QOM paths indicating how many
+#     active devices are currently associated with this iothread
+#     (e.g. virtio-blk).  In hotplug scenarios, users can
+#     pre-allocate multiple iothread objects to serve as a persistent
+#     thread pool.  When a device is hot-unplugged, the corresponding
+#     IOThread is released but remains available, allowing subsequent
+#     hot-plugged devices to attach to and reuse the existing thread.
+#     Returns empty if no devices are attached.  (since 11.0)
+#
 # @poll-max-ns: maximum polling time in ns, 0 means polling is
 #     disabled (since 2.9)
 #
@@ -93,6 +102,7 @@
 { 'struct': 'IOThreadInfo',
   'data': {'id': 'str',
            'thread-id': 'int',
+           'holders': ['str'],
            'poll-max-ns': 'int',
            'poll-grow': 'int',
            'poll-shrink': 'int',
@@ -118,6 +128,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,
@@ -126,6 +138,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
Re: [PATCH V5 13/13] qapi: examine IOThread attachment status via query-iothreads
Posted by Markus Armbruster 3 weeks, 3 days ago
Zhang Chen <zhangckid@gmail.com> writes:

> 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: A string containing of QOM paths for the attached devices.
>
> 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>

[...]

> diff --git a/qapi/misc.json b/qapi/misc.json
> index 1f5062df2a..a381074c04 100644
> --- a/qapi/misc.json
> +++ b/qapi/misc.json
> @@ -76,6 +76,15 @@
>  #
>  # @thread-id: ID of the underlying host thread
>  #
> +# @holders: The parameter is an array of QOM paths indicating how many
> +#     active devices are currently associated with this iothread
> +#     (e.g. virtio-blk).  In hotplug scenarios, users can
> +#     pre-allocate multiple iothread objects to serve as a persistent
> +#     thread pool.  When a device is hot-unplugged, the corresponding
> +#     IOThread is released but remains available, allowing subsequent
> +#     hot-plugged devices to attach to and reuse the existing thread.
> +#     Returns empty if no devices are attached.  (since 11.0)

Let me try to polish this a bit:

   # @holders: QOM paths 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)
>  #
> @@ -93,6 +102,7 @@
>  { 'struct': 'IOThreadInfo',
>    'data': {'id': 'str',
>             'thread-id': 'int',
> +           'holders': ['str'],
>             'poll-max-ns': 'int',
>             'poll-grow': 'int',
>             'poll-shrink': 'int',
> @@ -118,6 +128,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,
> @@ -126,6 +138,7 @@
>  #              {
>  #                 "id":"iothread1",
>  #                 "thread-id":3135,
> +#                 "holders":["/machine/peripheral/blk2/virtio-backend"],
>  #                 "poll-max-ns":32768,
>  #                 "poll-grow":0,
>  #                 "poll-shrink":0,

With a bit of doc polish:
Acked-by: Markus Armbruster <armbru@redhat.com>
Re: [PATCH V5 13/13] qapi: examine IOThread attachment status via query-iothreads
Posted by Zhang Chen 3 weeks, 3 days ago
On Wed, Mar 18, 2026 at 2:09 PM Markus Armbruster <armbru@redhat.com> wrote:
>
> Zhang Chen <zhangckid@gmail.com> writes:
>
> > 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: A string containing of QOM paths for the attached devices.
> >
> > 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>
>
> [...]
>
> > diff --git a/qapi/misc.json b/qapi/misc.json
> > index 1f5062df2a..a381074c04 100644
> > --- a/qapi/misc.json
> > +++ b/qapi/misc.json
> > @@ -76,6 +76,15 @@
> >  #
> >  # @thread-id: ID of the underlying host thread
> >  #
> > +# @holders: The parameter is an array of QOM paths indicating how many
> > +#     active devices are currently associated with this iothread
> > +#     (e.g. virtio-blk).  In hotplug scenarios, users can
> > +#     pre-allocate multiple iothread objects to serve as a persistent
> > +#     thread pool.  When a device is hot-unplugged, the corresponding
> > +#     IOThread is released but remains available, allowing subsequent
> > +#     hot-plugged devices to attach to and reuse the existing thread.
> > +#     Returns empty if no devices are attached.  (since 11.0)
>
> Let me try to polish this a bit:
>
>    # @holders: QOM paths 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)
> >  #
> > @@ -93,6 +102,7 @@
> >  { 'struct': 'IOThreadInfo',
> >    'data': {'id': 'str',
> >             'thread-id': 'int',
> > +           'holders': ['str'],
> >             'poll-max-ns': 'int',
> >             'poll-grow': 'int',
> >             'poll-shrink': 'int',
> > @@ -118,6 +128,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,
> > @@ -126,6 +138,7 @@
> >  #              {
> >  #                 "id":"iothread1",
> >  #                 "thread-id":3135,
> > +#                 "holders":["/machine/peripheral/blk2/virtio-backend"],
> >  #                 "poll-max-ns":32768,
> >  #                 "poll-grow":0,
> >  #                 "poll-shrink":0,
>
> With a bit of doc polish:
> Acked-by: Markus Armbruster <armbru@redhat.com>

Thank you for your suggestion, I will update it next version.

Thanks
Chen

>