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.
- 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) {
+        GList *link = g_list_find_custom(iothread->holders, holder,
+                                         (GCompareFunc)g_strcmp0);
+
+        if (link) {
+            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");
+    }
+}
+
 static void *iothread_run(void *opaque)
 {
     IOThread *iothread = opaque;
-- 
2.49.0


Reply via email to