[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PULL 06/10] virtio-iommu: Use recursive lock to avoid deadlock
From: |
Michael S. Tsirkin |
Subject: |
[PULL 06/10] virtio-iommu: Use recursive lock to avoid deadlock |
Date: |
Thu, 16 Jun 2022 12:57:39 -0400 |
From: Zhenzhong Duan <zhenzhong.duan@intel.com>
When switching address space with mutex lock hold, mapping will be
replayed for assigned device. This will trigger relock deadlock.
Also release the mutex resource in unrealize routine.
Signed-off-by: Zhenzhong Duan <zhenzhong.duan@intel.com>
Message-Id: <20220613061010.2674054-3-zhenzhong.duan@intel.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
---
include/hw/virtio/virtio-iommu.h | 2 +-
hw/virtio/virtio-iommu.c | 20 +++++++++++---------
2 files changed, 12 insertions(+), 10 deletions(-)
diff --git a/include/hw/virtio/virtio-iommu.h b/include/hw/virtio/virtio-iommu.h
index 102eeefa73..2ad5ee320b 100644
--- a/include/hw/virtio/virtio-iommu.h
+++ b/include/hw/virtio/virtio-iommu.h
@@ -58,7 +58,7 @@ struct VirtIOIOMMU {
ReservedRegion *reserved_regions;
uint32_t nb_reserved_regions;
GTree *domains;
- QemuMutex mutex;
+ QemuRecMutex mutex;
GTree *endpoints;
bool boot_bypass;
};
diff --git a/hw/virtio/virtio-iommu.c b/hw/virtio/virtio-iommu.c
index ff718107ee..73d5bde9d1 100644
--- a/hw/virtio/virtio-iommu.c
+++ b/hw/virtio/virtio-iommu.c
@@ -78,7 +78,7 @@ static bool virtio_iommu_device_bypassed(IOMMUDevice *sdev)
sid = virtio_iommu_get_bdf(sdev);
- qemu_mutex_lock(&s->mutex);
+ qemu_rec_mutex_lock(&s->mutex);
/* need to check bypass before system reset */
if (!s->endpoints) {
bypassed = s->config.bypass;
@@ -93,7 +93,7 @@ static bool virtio_iommu_device_bypassed(IOMMUDevice *sdev)
}
unlock:
- qemu_mutex_unlock(&s->mutex);
+ qemu_rec_mutex_unlock(&s->mutex);
return bypassed;
}
@@ -745,7 +745,7 @@ static void virtio_iommu_handle_command(VirtIODevice *vdev,
VirtQueue *vq)
tail.status = VIRTIO_IOMMU_S_DEVERR;
goto out;
}
- qemu_mutex_lock(&s->mutex);
+ qemu_rec_mutex_lock(&s->mutex);
switch (head.type) {
case VIRTIO_IOMMU_T_ATTACH:
tail.status = virtio_iommu_handle_attach(s, iov, iov_cnt);
@@ -774,7 +774,7 @@ static void virtio_iommu_handle_command(VirtIODevice *vdev,
VirtQueue *vq)
default:
tail.status = VIRTIO_IOMMU_S_UNSUPP;
}
- qemu_mutex_unlock(&s->mutex);
+ qemu_rec_mutex_unlock(&s->mutex);
out:
sz = iov_from_buf(elem->in_sg, elem->in_num, 0,
@@ -862,7 +862,7 @@ static IOMMUTLBEntry
virtio_iommu_translate(IOMMUMemoryRegion *mr, hwaddr addr,
sid = virtio_iommu_get_bdf(sdev);
trace_virtio_iommu_translate(mr->parent_obj.name, sid, addr, flag);
- qemu_mutex_lock(&s->mutex);
+ qemu_rec_mutex_lock(&s->mutex);
ep = g_tree_lookup(s->endpoints, GUINT_TO_POINTER(sid));
if (!ep) {
@@ -946,7 +946,7 @@ static IOMMUTLBEntry
virtio_iommu_translate(IOMMUMemoryRegion *mr, hwaddr addr,
trace_virtio_iommu_translate_out(addr, entry.translated_addr, sid);
unlock:
- qemu_mutex_unlock(&s->mutex);
+ qemu_rec_mutex_unlock(&s->mutex);
return entry;
}
@@ -1035,7 +1035,7 @@ static void virtio_iommu_replay(IOMMUMemoryRegion *mr,
IOMMUNotifier *n)
sid = virtio_iommu_get_bdf(sdev);
- qemu_mutex_lock(&s->mutex);
+ qemu_rec_mutex_lock(&s->mutex);
if (!s->endpoints) {
goto unlock;
@@ -1049,7 +1049,7 @@ static void virtio_iommu_replay(IOMMUMemoryRegion *mr,
IOMMUNotifier *n)
g_tree_foreach(ep->domain->mappings, virtio_iommu_remap, mr);
unlock:
- qemu_mutex_unlock(&s->mutex);
+ qemu_rec_mutex_unlock(&s->mutex);
}
static int virtio_iommu_notify_flag_changed(IOMMUMemoryRegion *iommu_mr,
@@ -1167,7 +1167,7 @@ static void virtio_iommu_device_realize(DeviceState *dev,
Error **errp)
virtio_add_feature(&s->features, VIRTIO_IOMMU_F_PROBE);
virtio_add_feature(&s->features, VIRTIO_IOMMU_F_BYPASS_CONFIG);
- qemu_mutex_init(&s->mutex);
+ qemu_rec_mutex_init(&s->mutex);
s->as_by_busptr = g_hash_table_new_full(NULL, NULL, NULL, g_free);
@@ -1195,6 +1195,8 @@ static void virtio_iommu_device_unrealize(DeviceState
*dev)
g_tree_destroy(s->endpoints);
}
+ qemu_rec_mutex_destroy(&s->mutex);
+
virtio_delete_queue(s->req_vq);
virtio_delete_queue(s->event_vq);
virtio_cleanup(vdev);
--
MST
- [PULL 00/10] virtio,pc,pci: fixes,cleanups,features, Michael S. Tsirkin, 2022/06/16
- [PULL 01/10] pci-bridge/cxl_upstream: Add a CXL switch upstream port, Michael S. Tsirkin, 2022/06/16
- [PULL 02/10] pci-bridge/cxl_downstream: Add a CXL switch downstream port, Michael S. Tsirkin, 2022/06/16
- [PULL 03/10] docs/cxl: Add switch documentation, Michael S. Tsirkin, 2022/06/16
- [PULL 04/10] virtio/vhost-user: Fix wrong vhost notifier GPtrArray size, Michael S. Tsirkin, 2022/06/16
- [PULL 06/10] virtio-iommu: Use recursive lock to avoid deadlock,
Michael S. Tsirkin <=
- [PULL 05/10] virtio-iommu: Add bypass mode support to assigned device, Michael S. Tsirkin, 2022/06/16
- [PULL 07/10] virtio-iommu: Add an assert check in translate routine, Michael S. Tsirkin, 2022/06/16
- [PULL 10/10] acpi/erst: fix fallthrough code upon validation failure, Michael S. Tsirkin, 2022/06/16
- [PULL 09/10] vhost: also check queue state in the vhost_dev_set_log error routine, Michael S. Tsirkin, 2022/06/16
- [PULL 08/10] crypto: Introduce RSA algorithm, Michael S. Tsirkin, 2022/06/16
- Re: [PULL 00/10] virtio,pc,pci: fixes,cleanups,features, Richard Henderson, 2022/06/16