mirror of
https://github.com/torvalds/linux.git
synced 2026-09-11 20:13:02 +02:00
vduse: do not take rwsem at reset work flush
Next patches need to check suspend flag at this work item, and the rwlock is used to protect the suspend flag update. If the work takes the rwlock too it will produce a deadlock. Make flushing work do nothing when called by de-initializing everything: vq->ready, vq->kickfd, vq->cb.callback. Signed-off-by: Eugenio Pérez <eperezma@redhat.com> Signed-off-by: Michael S. Tsirkin <mst@redhat.com> Message-ID: <20260707123344.244575-2-eperezma@redhat.com>
This commit is contained in:
parent
4c318d91cc
commit
675087c762
|
|
@ -502,46 +502,49 @@ static void vduse_dev_reset(struct vduse_dev *dev)
|
|||
vduse_domain_reset_bounce_map(domain);
|
||||
}
|
||||
|
||||
down_write(&dev->rwsem);
|
||||
scoped_guard(rwsem_write, &dev->rwsem) {
|
||||
dev->status = 0;
|
||||
dev->driver_features = 0;
|
||||
dev->generation++;
|
||||
spin_lock(&dev->irq_lock);
|
||||
dev->config_cb.callback = NULL;
|
||||
dev->config_cb.private = NULL;
|
||||
spin_unlock(&dev->irq_lock);
|
||||
|
||||
for (i = 0; i < dev->vq_num; i++) {
|
||||
struct vduse_virtqueue *vq = dev->vqs[i];
|
||||
|
||||
scoped_guard(spinlock_bh, &vq->ready_lock) {
|
||||
vq->ready = false;
|
||||
}
|
||||
vq->desc_addr = 0;
|
||||
vq->driver_addr = 0;
|
||||
vq->device_addr = 0;
|
||||
vq->num = 0;
|
||||
memset(&vq->state, 0, sizeof(vq->state));
|
||||
|
||||
spin_lock(&vq->kick_lock);
|
||||
vq->kicked = false;
|
||||
if (vq->kickfd)
|
||||
eventfd_ctx_put(vq->kickfd);
|
||||
vq->kickfd = NULL;
|
||||
spin_unlock(&vq->kick_lock);
|
||||
|
||||
spin_lock(&vq->irq_lock);
|
||||
vq->cb.callback = NULL;
|
||||
vq->cb.private = NULL;
|
||||
vq->cb.trigger = NULL;
|
||||
spin_unlock(&vq->irq_lock);
|
||||
}
|
||||
}
|
||||
|
||||
dev->status = 0;
|
||||
dev->driver_features = 0;
|
||||
dev->generation++;
|
||||
spin_lock(&dev->irq_lock);
|
||||
dev->config_cb.callback = NULL;
|
||||
dev->config_cb.private = NULL;
|
||||
spin_unlock(&dev->irq_lock);
|
||||
flush_work(&dev->inject);
|
||||
|
||||
for (i = 0; i < dev->vq_num; i++) {
|
||||
struct vduse_virtqueue *vq = dev->vqs[i];
|
||||
|
||||
scoped_guard(spinlock_bh, &vq->ready_lock) {
|
||||
vq->ready = false;
|
||||
}
|
||||
vq->desc_addr = 0;
|
||||
vq->driver_addr = 0;
|
||||
vq->device_addr = 0;
|
||||
vq->num = 0;
|
||||
memset(&vq->state, 0, sizeof(vq->state));
|
||||
|
||||
spin_lock(&vq->kick_lock);
|
||||
vq->kicked = false;
|
||||
if (vq->kickfd)
|
||||
eventfd_ctx_put(vq->kickfd);
|
||||
vq->kickfd = NULL;
|
||||
spin_unlock(&vq->kick_lock);
|
||||
|
||||
spin_lock(&vq->irq_lock);
|
||||
vq->cb.callback = NULL;
|
||||
vq->cb.private = NULL;
|
||||
vq->cb.trigger = NULL;
|
||||
spin_unlock(&vq->irq_lock);
|
||||
flush_work(&vq->inject);
|
||||
flush_work(&vq->kick);
|
||||
}
|
||||
|
||||
up_write(&dev->rwsem);
|
||||
}
|
||||
|
||||
static int vduse_vdpa_set_vq_address(struct vdpa_device *vdpa, u16 idx,
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user