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(): Increments the attachment counter and prepends the device's QOM path to a list. Note: The IOThread takes ownership of the passed 'holder' string. - iothread_unref(): Searches for the device path using a custom string comparison (g_strcmp0), decrements the counter, and releases the associated memory upon a successful match. - attached_cnt: Tracks the number of active device attachments. - attached_dev: 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 | 4 ++++ iothread.c | 35 +++++++++++++++++++++++++++++++++++ 2 files changed, 39 insertions(+) diff --git a/include/system/iothread.h b/include/system/iothread.h index e26d13c6c7..4a2ffdb9bd 100644 --- a/include/system/iothread.h +++ b/include/system/iothread.h @@ -33,6 +33,8 @@ struct IOThread { bool stopping; /* has iothread_stop() been called? */ bool running; /* should iothread_run() continue? */ int thread_id; + int attached_cnt; + GList *attached_dev; /* AioContext poll parameters */ int64_t poll_max_ns; @@ -48,6 +50,8 @@ char *iothread_get_id(IOThread *iothread); IOThread *iothread_by_id(const char *id); AioContext *iothread_get_aio_context(IOThread *iothread); GMainContext *iothread_get_g_main_context(IOThread *iothread); +void iothread_ref(IOThread *iothread, const char* holder); +void iothread_unref(IOThread *iothread, const char* holder); /* * Helpers used to allocate iothreads for internal use. These diff --git a/iothread.c b/iothread.c index caf68e0764..b869637497 100644 --- a/iothread.c +++ b/iothread.c @@ -36,6 +36,41 @@ #define IOTHREAD_POLL_MAX_NS_DEFAULT 0ULL #endif +/* + * Increment iothread's reference count, + * and add holder device path to the list. + */ +void iothread_ref(IOThread *iothread, const char *holder) +{ + iothread->attached_cnt++; + iothread->attached_dev = g_list_prepend(iothread->attached_dev, + (gpointer)holder); +} + +/* + * Decrement iothread's reference count, + * and delete holder device path from the list. + */ +void iothread_unref(IOThread *iothread, const char *holder) +{ + if (iothread->attached_cnt > 0) { + GList *link = g_list_find_custom(iothread->attached_dev, + holder, (GCompareFunc)g_strcmp0); + + if (link) { + g_free(link->data); + iothread->attached_dev = g_list_delete_link(iothread->attached_dev, + link); + iothread->attached_cnt--; + } else { + error_report("iohtread_unref can't find device. attached_dev=%s", + holder); + } + } else { + error_report("iohtread_unref counter error. attached_dev=%s", holder); + } +} + static void *iothread_run(void *opaque) { IOThread *iothread = opaque; -- 2.49.0
