virtio_pmem_freeze() deletes virtqueues and resets the device without waking threads waiting for a virtqueue descriptor or a host completion.
Mark the request virtqueue broken and drain outstanding requests under pmem_lock before teardown so waiters can make progress and return -EIO. Signed-off-by: Li Chen <[email protected]> --- drivers/nvdimm/virtio_pmem.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/nvdimm/virtio_pmem.c b/drivers/nvdimm/virtio_pmem.c index aa07328e3ff9..5c60a7b459d4 100644 --- a/drivers/nvdimm/virtio_pmem.c +++ b/drivers/nvdimm/virtio_pmem.c @@ -152,6 +152,13 @@ static void virtio_pmem_remove(struct virtio_device *vdev) static int virtio_pmem_freeze(struct virtio_device *vdev) { + struct virtio_pmem *vpmem = vdev->priv; + unsigned long flags; + + spin_lock_irqsave(&vpmem->pmem_lock, flags); + virtio_pmem_mark_broken_and_drain(vpmem); + spin_unlock_irqrestore(&vpmem->pmem_lock, flags); + vdev->config->del_vqs(vdev); virtio_reset_device(vdev); -- 2.51.0

