Replace raw object_ref/unref calls with iothread_get/put_aio_context
in iothread-vq-mapping. This allows tracking IOThread users via
the device's canonical QOM path, improving lifecycle traceability
for virtio-blk and virtio-scsi devices.
Signed-off-by: Zhang Chen <zhangckid@gmail.com>
---
hw/block/virtio-blk.c | 8 +++++++-
hw/scsi/virtio-scsi-dataplane.c | 9 +++++++--
hw/virtio/iothread-vq-mapping.c | 11 +++++------
include/hw/virtio/iothread-vq-mapping.h | 6 +++++-
4 files changed, 24 insertions(+), 10 deletions(-)
diff --git a/hw/block/virtio-blk.c b/hw/block/virtio-blk.c
index ddf0e9ee53..762714f4ba 100644
--- a/hw/block/virtio-blk.c
+++ b/hw/block/virtio-blk.c
@@ -1453,9 +1453,12 @@ static bool virtio_blk_vq_aio_context_init(VirtIOBlock *s, Error **errp)
s->vq_aio_context = g_new(AioContext *, conf->num_queues);
if (conf->iothread_vq_mapping_list) {
+ g_autofree char *path = object_get_canonical_path(OBJECT(vdev));
+
if (!iothread_vq_mapping_apply(conf->iothread_vq_mapping_list,
s->vq_aio_context,
conf->num_queues,
+ path,
errp)) {
g_free(s->vq_aio_context);
s->vq_aio_context = NULL;
@@ -1487,7 +1490,10 @@ static void virtio_blk_vq_aio_context_cleanup(VirtIOBlock *s)
assert(!s->ioeventfd_started);
if (conf->iothread_vq_mapping_list) {
- iothread_vq_mapping_cleanup(conf->iothread_vq_mapping_list);
+ g_autofree char *path = object_get_canonical_path(
+ OBJECT(VIRTIO_DEVICE(s)));
+
+ iothread_vq_mapping_cleanup(conf->iothread_vq_mapping_list, path);
}
if (conf->iothread) {
diff --git a/hw/scsi/virtio-scsi-dataplane.c b/hw/scsi/virtio-scsi-dataplane.c
index 95f13fb7c2..26ecefd547 100644
--- a/hw/scsi/virtio-scsi-dataplane.c
+++ b/hw/scsi/virtio-scsi-dataplane.c
@@ -65,9 +65,11 @@ void virtio_scsi_dataplane_setup(VirtIOSCSI *s, Error **errp)
s->vq_aio_context[1] = qemu_get_aio_context();
if (vs->conf.iothread_vq_mapping_list) {
+ g_autofree char *path = object_get_canonical_path(OBJECT(vdev));
+
if (!iothread_vq_mapping_apply(vs->conf.iothread_vq_mapping_list,
&s->vq_aio_context[VIRTIO_SCSI_VQ_NUM_FIXED],
- vs->conf.num_queues, errp)) {
+ vs->conf.num_queues, path, errp)) {
g_free(s->vq_aio_context);
s->vq_aio_context = NULL;
return;
@@ -94,7 +96,10 @@ void virtio_scsi_dataplane_cleanup(VirtIOSCSI *s)
VirtIOSCSICommon *vs = VIRTIO_SCSI_COMMON(s);
if (vs->conf.iothread_vq_mapping_list) {
- iothread_vq_mapping_cleanup(vs->conf.iothread_vq_mapping_list);
+ g_autofree char *path = object_get_canonical_path(
+ OBJECT(VIRTIO_DEVICE(s)));
+
+ iothread_vq_mapping_cleanup(vs->conf.iothread_vq_mapping_list, path);
}
if (vs->conf.iothread) {
diff --git a/hw/virtio/iothread-vq-mapping.c b/hw/virtio/iothread-vq-mapping.c
index 55ce62986c..c993281d7f 100644
--- a/hw/virtio/iothread-vq-mapping.c
+++ b/hw/virtio/iothread-vq-mapping.c
@@ -77,6 +77,7 @@ bool iothread_vq_mapping_apply(
IOThreadVirtQueueMappingList *list,
AioContext **vq_aio_context,
uint16_t num_queues,
+ const char *holder,
Error **errp)
{
IOThreadVirtQueueMappingList *node;
@@ -93,10 +94,7 @@ bool iothread_vq_mapping_apply(
for (node = list; node; node = node->next) {
IOThread *iothread = iothread_by_id(node->value->iothread);
- AioContext *ctx = iothread_get_aio_context(iothread);
-
- /* Released in virtio_blk_vq_aio_context_cleanup() */
- object_ref(OBJECT(iothread));
+ AioContext *ctx = iothread_ref_and_get_aio_context(iothread, holder);
if (node->value->vqs) {
uint16List *vq;
@@ -120,13 +118,14 @@ bool iothread_vq_mapping_apply(
return true;
}
-void iothread_vq_mapping_cleanup(IOThreadVirtQueueMappingList *list)
+void iothread_vq_mapping_cleanup(IOThreadVirtQueueMappingList *list,
+ const char *holder)
{
IOThreadVirtQueueMappingList *node;
for (node = list; node; node = node->next) {
IOThread *iothread = iothread_by_id(node->value->iothread);
- object_unref(OBJECT(iothread));
+ iothread_put_aio_context(iothread, holder);
}
}
diff --git a/include/hw/virtio/iothread-vq-mapping.h b/include/hw/virtio/iothread-vq-mapping.h
index 57335c3703..0d39caddf3 100644
--- a/include/hw/virtio/iothread-vq-mapping.h
+++ b/include/hw/virtio/iothread-vq-mapping.h
@@ -17,6 +17,7 @@
* @list: The mapping of virtqueues to IOThreads.
* @vq_aio_context: The array of AioContext pointers to fill in.
* @num_queues: The length of @vq_aio_context.
+ * @holder: The QOM paths for attached device.
* @errp: If an error occurs, a pointer to the area to store the error.
*
* Fill in the AioContext for each virtqueue in the @vq_aio_context array given
@@ -31,15 +32,18 @@ bool iothread_vq_mapping_apply(
IOThreadVirtQueueMappingList *list,
AioContext **vq_aio_context,
uint16_t num_queues,
+ const char *holder,
Error **errp);
/**
* iothread_vq_mapping_cleanup:
* @list: The mapping of virtqueues to IOThreads.
+ * @holder: The QOM paths for attached device.
*
* Release IOThread object references that were acquired by
* iothread_vq_mapping_apply().
*/
-void iothread_vq_mapping_cleanup(IOThreadVirtQueueMappingList *list);
+void iothread_vq_mapping_cleanup(IOThreadVirtQueueMappingList *list,
+ const char *holder);
#endif /* HW_VIRTIO_IOTHREAD_VQ_MAPPING_H */
--
2.49.0