From: Stefan Hajnoczi <stefanha@redhat.com>
To: Zhang Chen <zhangckid@gmail.com>
Cc: qemu-devel <qemu-devel@nongnu.org>,
"Dr . David Alan Gilbert" <dave@treblig.org>,
Eric Blake <eblake@redhat.com>,
Markus Armbruster <armbru@redhat.com>,
"Michael S . Tsirkin" <mst@redhat.com>
Subject: Re: [PATCH V7 02/14] iothread: introduce iothread_ref/unref to track attached devices
Date: Mon, 11 May 2026 14:14:25 -0400 [thread overview]
Message-ID: <20260511181425.GD536999@fedora> (raw)
In-Reply-To: <20260511140416.28271-3-zhangckid@gmail.com>
[-- Attachment #1: Type: text/plain, Size: 6984 bytes --]
On Mon, May 11, 2026 at 10:04:04PM +0800, Zhang Chen wrote:
> Currently, IOThreads do not maintain a record of which devices are
> associated with them. This makes it difficult to monitor the
> workload distribution of IOThreads, especially in complex
> hotplug scenarios involving multiple virtio-blk or virtio-scsi devices.
>
> This patch introduces a reference counting and tracking mechanism
> within the IOThread object:
>
> - iothread_ref(): Prepends the device's QOM path to a list.
> - iothread_unref(): Searches for the device path using a custom
> string comparison (g_strcmp0), releases the associated memory
> upon a successful match.
> - holders: A GList storing the QOM paths of attached devices
> for runtime introspection.
>
> A later commit will add QMP commands to let management applications
> query the attachment status of IOThreads.
>
> Signed-off-by: Zhang Chen <zhangckid@gmail.com>
> ---
> include/system/iothread.h | 5 +++
> iothread.c | 67 +++++++++++++++++++++++++++++++++++++++
> qapi/misc.json | 48 ++++++++++++++++++++++++++++
> 3 files changed, 120 insertions(+)
>
> diff --git a/include/system/iothread.h b/include/system/iothread.h
> index a1ef7696cb..2871b06edc 100644
> --- a/include/system/iothread.h
> +++ b/include/system/iothread.h
> @@ -50,6 +50,11 @@ struct IOThread {
> bool stopping; /* has iothread_stop() been called? */
> bool running; /* should iothread_run() continue? */
> int thread_id;
> + /*
> + * The list elements are of type IoThreadHolder, which can
> + * represent either a QOM path or a block node name.
> + */
> + GList *holders;
>
> /* AioContext poll parameters */
> int64_t poll_max_ns;
> diff --git a/iothread.c b/iothread.c
> index 3558535b40..b805e4f97d 100644
> --- a/iothread.c
> +++ b/iothread.c
> @@ -25,6 +25,66 @@
> #include "qemu/rcu.h"
> #include "qemu/main-loop.h"
>
> +/*
> + * Add the @holder path to the iothread's tracking list.
> + * The @holder is a QOM path if it starts with '/', else a block node name.
> + */
It would be cleaner to use IoThreadHolder in the iothread_ref() and
iothread_unref() APIs instead of a string:
static void iothread_ref(IOThread *iothread, const IoThreadHolder *holder);
static void iothread_unref(IOThread *iothread, const IoThreadHolder *holder);
That way the caller already uses IO_THREAD_HOLDER_KIND_QOM_OBJECT or
IO_THREAD_HOLDER_KIND_BLOCK_NODE to clearly distinguish QOM paths from
block node names. No string parsing is necessary.
> +static void iothread_ref(IOThread *iothread, const char *holder)
> +{
> + IoThreadHolder *h = g_new0(IoThreadHolder, 1);
IoThreadHolder vs IOThread. Name it IOThreadHolder for consistency?
> +
> + assert(holder);
> +
> + if (holder[0] == '/') {
> + h->type = IO_THREAD_HOLDER_KIND_QOM_OBJECT;
> + h->u.qom_object.data = g_strdup(holder);
> + } else {
> + h->type = IO_THREAD_HOLDER_KIND_BLOCK_NODE;
> + h->u.block_node.data = g_strdup(holder);
> + }
> +
> + iothread->holders = g_list_prepend(iothread->holders, h);
> +}
> +
> +static int iothread_holder_compare(gconstpointer a, gconstpointer b)
> +{
> + const IoThreadHolder *holder_node = a;
> + const char *target_name = b;
> + const char *current_name;
> +
> + if (holder_node->type == IO_THREAD_HOLDER_KIND_QOM_OBJECT) {
> + current_name = holder_node->u.qom_object.data;
> + } else if (holder_node->type == IO_THREAD_HOLDER_KIND_BLOCK_NODE) {
> + current_name = holder_node->u.block_node.data;
> + } else {
> + /*
> + * This should not happen. If it does, current_name remains
> + * NULL and g_strcmp0 will handle it safely.
> + */
> + current_name = NULL;
> + }
> +
> + return g_strcmp0(current_name, target_name);
> +}
> +
> +/*
> + * This function removes the @holder from the @iothread's tracking list.
> + * The @holder string must match the one used previously in iothread_ref().
> + * It is a programming error to call this with a @holder that is not
> + * currently associated with the @iothread.
> + */
> +static void iothread_unref(IOThread *iothread, const char *holder)
> +{
> + GList *link = g_list_find_custom(iothread->holders, holder,
> + (GCompareFunc)iothread_holder_compare);
> +
> + assert(link);
> +
> + IoThreadHolder *h = (IoThreadHolder *)link->data;
> + qapi_free_IoThreadHolder(h);
> + iothread->holders = g_list_delete_link(iothread->holders, link);
> +}
> +
> static void *iothread_run(void *opaque)
> {
> IOThread *iothread = opaque;
> @@ -108,6 +168,9 @@ static void iothread_instance_finalize(Object *obj)
>
> iothread_stop(iothread);
>
> + /* We don't support finalize without holders */
The double-negative is confusing and the logic seems incorrect: we don't
support finalize while there are holders. A clearer comment would be:
/* All holders must have called iothread_unref() */
> + assert(iothread->holders == NULL);
> +
> /*
> * Before glib2 2.33.10, there is a glib2 bug that GSource context
> * pointer may not be cleared even if the context has already been
> @@ -356,6 +419,10 @@ char *iothread_get_id(IOThread *iothread)
>
> AioContext *iothread_get_aio_context(IOThread *iothread)
> {
> + /* Remove in next patch for build */
> + iothread_ref(iothread, "tmp");
> + iothread_unref(iothread, "tmp");
> +
> return iothread->ctx;
> }
>
> diff --git a/qapi/misc.json b/qapi/misc.json
> index c71a5fe657..5fb7dcfcad 100644
> --- a/qapi/misc.json
> +++ b/qapi/misc.json
> @@ -67,6 +67,54 @@
> ##
> { 'command': 'query-name', 'returns': 'NameInfo', 'allow-preconfig': true }
>
> +
> +##
> +# @IoThreadHolderBlockNode:
> +#
> +# @data: Block node name.
> +#
> +# Since: 11.1
> +#
> +##
> +{ 'struct': 'IoThreadHolderBlockNode',
> + 'data': { 'data': 'str' } }
> +
> +##
> +# @IoThreadHolderQomObject:
> +#
> +# @data: Absolute @qom-path.
> +#
> +# Since: 11.1
> +#
> +##
> +{ 'struct': 'IoThreadHolderQomObject',
> + 'data': { 'data': 'str' } }
> +
> +##
> +# @IoThreadHolderKind:
> +#
> +# @block-node: Block node name.
> +# @qom-object: Absolute @qom-path.
> +#
> +# Since: 11.1
> +##
> +{ 'enum': 'IoThreadHolderKind',
> + 'data': [ 'block-node', 'qom-object' ] }
> +
> +##
> +# @IoThreadHolder:
> +#
> +# @type: the kind of I/O thread holder.
> +#
> +# Since: 11.1
> +##
> +{ 'union': 'IoThreadHolder',
> + 'base': { 'type': 'IoThreadHolderKind' },
> + 'discriminator': 'type',
> + 'data': {
> + 'block-node': 'IoThreadHolderBlockNode',
> + 'qom-object': 'IoThreadHolderQomObject' } }
> +
> ##
> # @IOThreadInfo:
> #
> --
> 2.49.0
>
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]
next prev parent reply other threads:[~2026-05-11 18:15 UTC|newest]
Thread overview: 26+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-05-11 14:04 [PATCH V7 00/14] iothread: Support tracking and querying IOThread holders Zhang Chen
2026-05-11 14:04 ` [PATCH V7 01/14] qapi/misc: Fix missed query-iothreads items Zhang Chen
2026-05-11 14:04 ` [PATCH V7 02/14] iothread: introduce iothread_ref/unref to track attached devices Zhang Chen
2026-05-11 18:14 ` Stefan Hajnoczi [this message]
2026-05-11 19:15 ` Zhang Chen
2026-05-18 11:58 ` Markus Armbruster
2026-05-18 13:28 ` Zhang Chen
2026-05-18 11:44 ` Markus Armbruster
2026-05-11 14:04 ` [PATCH V7 03/14] iothread: tracking iothread users with holder name Zhang Chen
2026-05-11 18:54 ` Stefan Hajnoczi
2026-05-11 19:06 ` Zhang Chen
2026-05-11 14:04 ` [PATCH V7 04/14] blockdev: Update " Zhang Chen
2026-05-11 19:05 ` Stefan Hajnoczi
2026-05-11 19:25 ` Zhang Chen
2026-05-11 14:04 ` [PATCH V7 05/14] block/export: track IOThread reference in BlockExport Zhang Chen
2026-05-11 14:04 ` [PATCH V7 06/14] monitor: Update tracking iothread users with holder name Zhang Chen
2026-05-18 11:57 ` Markus Armbruster
2026-05-18 13:47 ` Zhang Chen
2026-05-11 14:04 ` [PATCH V7 07/14] virtio-vq-mapping: track iothread-vq-mapping references using device path Zhang Chen
2026-05-11 14:04 ` [PATCH V7 08/14] virtio: use iothread_get/put_aio_context for thread pinning Zhang Chen
2026-05-11 14:04 ` [PATCH V7 09/14] net/colo: track IOThread references using path-based holder Zhang Chen
2026-05-11 14:04 ` [PATCH V7 10/14] virtio-balloon: Update tracking iothread users with holder name Zhang Chen
2026-05-11 14:04 ` [PATCH V7 11/14] vfio-user/proxy: " Zhang Chen
2026-05-11 14:04 ` [PATCH V7 12/14] xen-block: " Zhang Chen
2026-05-11 14:04 ` [PATCH V7 13/14] qapi: examine IOThread attachment status via query-iothreads Zhang Chen
2026-05-11 14:04 ` [PATCH V7 14/14] iothread: simplify API by merging iothread_get_aio_context variants Zhang Chen
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260511181425.GD536999@fedora \
--to=stefanha@redhat.com \
--cc=armbru@redhat.com \
--cc=dave@treblig.org \
--cc=eblake@redhat.com \
--cc=mst@redhat.com \
--cc=qemu-devel@nongnu.org \
--cc=zhangckid@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.