All of lore.kernel.org
 help / color / mirror / Atom feed
From: Markus Armbruster <armbru@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>,
	 "Michael S . Tsirkin" <mst@redhat.com>,
	 Stefan Hajnoczi <stefanha@redhat.com>
Subject: Re: [PATCH V6 02/14] iothread: introduce iothread_ref/unref to track attached devices
Date: Tue, 21 Apr 2026 16:15:29 +0200	[thread overview]
Message-ID: <87bjfc4cxq.fsf@pond.sub.org> (raw)
In-Reply-To: <20260410150457.85190-3-zhangckid@gmail.com> (Zhang Chen's message of "Fri, 10 Apr 2026 23:04:45 +0800")

Zhang Chen <zhangckid@gmail.com> writes:

> 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.
>
> This infrastructure allows management tools and QMP commands to
> query the attachment status of IOThreads.

Suggest something like

  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 |  1 +
>  iothread.c                | 56 +++++++++++++++++++++++++++++++++++++++
>  qapi/misc.json            | 48 +++++++++++++++++++++++++++++++++
>  3 files changed, 105 insertions(+)
>
> diff --git a/include/system/iothread.h b/include/system/iothread.h
> index e26d13c6c7..21a76bd70d 100644
> --- a/include/system/iothread.h
> +++ b/include/system/iothread.h
> @@ -33,6 +33,7 @@ struct IOThread {
>      bool stopping;              /* has iothread_stop() been called? */
>      bool running;               /* should iothread_run() continue? */
>      int thread_id;
> +    GList *holders;             /* an array of QOM paths for attached devices */

The comment is mostly wrong.  A GList is not an array.  The list
elements are of type IoThreadHolder, which can represent either a QOM
path or a block node name.  Suggest

       GList *holders;             /* list of IoThreadHolder */

>  
>      /* AioContext poll parameters */
>      int64_t poll_max_ns;
> diff --git a/iothread.c b/iothread.c
> index caf68e0764..c43266b191 100644
> --- a/iothread.c
> +++ b/iothread.c
> @@ -36,6 +36,55 @@
>  #define IOTHREAD_POLL_MAX_NS_DEFAULT 0ULL
>  #endif
>  
> +/*
> + * Add holder device path to the list.

Please explain semantics of parameter @holder here, it's not obvious
that @holder is a QOM path if it starts with '/', else a block node
name.

Restriction: only absolute QOM paths work.  Relative ones get
misinterpreted as block node names.

> + */
> +static void iothread_ref(IOThread *iothread, const char *holder)
> +{
> +    IoThreadHolder *h = g_new0(IoThreadHolder, 1);
> +
> +    if (holder && 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 ? holder : "unknown");

No.  Nothing stops a user from naming a block node "unknown".

How can !holder happen?  If it's not supposed to happen, assert() it
doesn't!

> +    }
> +
> +    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 = NULL;

Superfluous initializer.

> +
> +    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;
> +    }
> +
> +    return g_strcmp0(current_name, target_name);

Why g_strcmp0()?  How can any of the arguments be null?

> +}
> +
> +/*
> + * Delete holder device path from the list.

Please explain semantics of @holder as for iothread_ref(), and state
that a it must be one of @io_thread's holders.

> + */
> +static void iothread_unref(IOThread *iothread, const char *holder)
> +{
> +    GList *link = g_list_find_custom(iothread->holders, holder,
> +                                     (GCompareFunc)iothread_holder_compare);
> +
> +    /* We don't support unref without a link */

I doubt this comment is useful.

> +    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;
> @@ -115,6 +164,9 @@ static void iothread_instance_finalize(Object *obj)
>  
>      iothread_stop(iothread);
>  
> +    /* We don't support finalize without holders */

Why?

> +    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
> @@ -336,6 +388,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 1f5062df2a..d65d8012b2 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.

These are commonly named @node-name.

> +#
> +# Since: 11.0
> +#
> +##
> +{ 'struct': 'IoThreadHolderBlockNode',
> +  'data': { 'data': 'str' } }
> +
> +##
> +# @IoThreadHolderQomObject:
> +#
> +# @data: QOM path.

These are commonly named @qom-path.

Should we use "Absolute QOM path" here?  Relative ones don't actually
work.

> +#
> +# Since: 11.0
> +#
> +##
> +{ 'struct': 'IoThreadHolderQomObject',
> +  'data': { 'data': 'str' } }
> +
> +##
> +# @IoThreadHolderKind:
> +#
> +# @block-node: Block node name.

The block node name is not the holder, the block node is.

> +# @qom-object: Standard QOM path.

What do you mean by "standard"?

> +#
> +# Since: 11.0
> +##
> +{ 'enum': 'IoThreadHolderKind',
> +  'data': [ 'block-node', 'qom-object' ] }
> +
> +##
> +# @IoThreadHolder:
> +#
> +# @type: Current IoThread holder type support QOM path and Block node.

Awkward English :)

   # @type: the kind of I/O thread holder

isn't exactly great, either.  But I'm out of time for today.

> +#
> +# Since: 11.0
> +##
> +{ 'union': 'IoThreadHolder',
> +  'base': { 'type': 'IoThreadHolderKind' },
> +  'discriminator': 'type',
> +  'data': {
> +    'block-node': 'IoThreadHolderBlockNode',
> +    'qom-object': 'IoThreadHolderQomObject' } }
> +
>  ##
>  # @IOThreadInfo:
>  #



  reply	other threads:[~2026-04-21 14:16 UTC|newest]

Thread overview: 23+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-04-10 15:04 [PATCH V6 00/14] iothread: Support tracking and querying IOThread holders Zhang Chen
2026-04-10 15:04 ` [PATCH V6 01/14] qapi/misc: Fix missed query-iothreads items Zhang Chen
2026-04-10 15:04 ` [PATCH V6 02/14] iothread: introduce iothread_ref/unref to track attached devices Zhang Chen
2026-04-21 14:15   ` Markus Armbruster [this message]
2026-04-27 14:55     ` Zhang Chen
2026-04-10 15:04 ` [PATCH V6 03/14] iothread: tracking iothread users with holder name Zhang Chen
2026-04-10 15:04 ` [PATCH V6 04/14] blockdev: Update " Zhang Chen
2026-04-10 15:04 ` [PATCH V6 05/14] block/export: track IOThread reference in BlockExport Zhang Chen
2026-04-10 15:04 ` [PATCH V6 06/14] monitor: Update tracking iothread users with holder name Zhang Chen
2026-04-23 12:44   ` Markus Armbruster
2026-04-27 14:55     ` Zhang Chen
2026-04-28  7:26       ` Markus Armbruster
2026-04-29  5:34         ` Zhang Chen
2026-04-10 15:04 ` [PATCH V6 07/14] virtio-vq-mapping: track iothread-vq-mapping references using device path Zhang Chen
2026-04-10 15:04 ` [PATCH V6 08/14] virtio: use iothread_get/put_aio_context for thread pinning Zhang Chen
2026-04-10 15:04 ` [PATCH V6 09/14] net/colo: track IOThread references using path-based holder Zhang Chen
2026-04-10 15:04 ` [PATCH V6 10/14] virtio-balloon: Update tracking iothread users with holder name Zhang Chen
2026-04-10 15:04 ` [PATCH V6 11/14] vfio-user/proxy: " Zhang Chen
2026-04-10 15:04 ` [PATCH V6 12/14] xen-block: " Zhang Chen
2026-04-10 15:04 ` [PATCH V6 13/14] qapi: examine IOThread attachment status via query-iothreads Zhang Chen
2026-04-23 13:09   ` Markus Armbruster
2026-04-27 15:10     ` Zhang Chen
2026-04-10 15:04 ` [PATCH V6 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=87bjfc4cxq.fsf@pond.sub.org \
    --to=armbru@redhat.com \
    --cc=dave@treblig.org \
    --cc=eblake@redhat.com \
    --cc=mst@redhat.com \
    --cc=qemu-devel@nongnu.org \
    --cc=stefanha@redhat.com \
    --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.