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 <[email protected]> --- 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 9cb9f1fb2b..30e9fcf870 100644 --- a/hw/block/virtio-blk.c +++ b/hw/block/virtio-blk.c @@ -1487,9 +1487,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; @@ -1521,7 +1524,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
