On Mon, Mar 9, 2026 at 3:49 PM Stefan Hajnoczi <[email protected]> wrote: > > On Thu, Mar 05, 2026 at 10:24:48PM +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. > > Note: The IOThread takes ownership of the passed 'holder' string. > > This is outdated, the patch duplicates the string and the caller still > owns the holder argument: > > iothread->holders = g_list_prepend(iothread->holders, g_strdup(holder)); >
Yes, will remove this "Note" comments. > > - 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. > > > > Signed-off-by: Zhang Chen <[email protected]> > > --- > > include/system/iothread.h | 1 + > > iothread.c | 28 ++++++++++++++++++++++++++++ > > 2 files changed, 29 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 */ > > > > /* AioContext poll parameters */ > > int64_t poll_max_ns; > > diff --git a/iothread.c b/iothread.c > > index caf68e0764..80a8cf4b32 100644 > > --- a/iothread.c > > +++ b/iothread.c > > @@ -36,6 +36,34 @@ > > #define IOTHREAD_POLL_MAX_NS_DEFAULT 0ULL > > #endif > > > > +/* > > + * Add holder device path to the list. > > + */ > > +static void iothread_ref(IOThread *iothread, const char *holder) > > +{ > > + iothread->holders = g_list_prepend(iothread->holders, > > g_strdup(holder)); > > +} > > + > > +/* > > + * Delete holder device path from the list. > > + */ > > +static void iothread_unref(IOThread *iothread, const char *holder) > > +{ > > + if (iothread->holders) { > > g_list_find_customer(NULL, ...) returns NULL rather than crashing, so > there is no need for if (iothread->holders). OK. > > > + GList *link = g_list_find_custom(iothread->holders, holder, > > + (GCompareFunc)g_strcmp0); > > + > > + if (link) { > > assert(link) is usually used in QEMU instead. If the reference has > already been released then the program is in an invalid state and it's > not safe to continue running. > > Please also add assert(iothread->holders == NULL) to > iothread_instance_finalize() so that leaked references are caught. OK. will update in next version. > > > + g_free(link->data); > > + iothread->holders = g_list_delete_link(iothread->holders, > > link); > > + } else { > > + error_report("iothread_unref can't find the holder %s", > > holder); > > + } > > + } else { > > + error_report("iohtread_unref iothread is not held by any devices"); > > iohtread -> iothread Thanks Chen
