virtio_pmem_freeze() currently deletes virtqueues and resets the device without waking threads waiting for a virtqueue descriptor or a host completion.
Mark the request virtqueue broken before reset. This makes new submissions fail fast and lets -ENOSPC waiters leave the wait list. Reset the device before draining used and unused request tokens, then delete the virtqueues. This wakes waiters with -EIO. It also keeps the detach call on a quiesced device. Signed-off-by: Li Chen <[email protected]> --- Changes in v5: - Reset the device before draining used and unused request tokens. - Use the split broken-marking and post-reset drain helpers. v2->v3: - No change. v3->v4: - Rebased onto v7.1-rc7 and renumbered after the flush error patches. drivers/nvdimm/virtio_pmem.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/drivers/nvdimm/virtio_pmem.c b/drivers/nvdimm/virtio_pmem.c index 3bcc7b3671d21..9961bc2678d0f 100644 --- a/drivers/nvdimm/virtio_pmem.c +++ b/drivers/nvdimm/virtio_pmem.c @@ -158,9 +158,21 @@ static void virtio_pmem_remove(struct virtio_device *vdev) static int virtio_pmem_freeze(struct virtio_device *vdev) { - vdev->config->del_vqs(vdev); + struct virtio_pmem *vpmem = vdev->priv; + unsigned long flags; + + spin_lock_irqsave(&vpmem->pmem_lock, flags); + virtio_pmem_mark_broken(vpmem); + spin_unlock_irqrestore(&vpmem->pmem_lock, flags); + virtio_reset_device(vdev); + spin_lock_irqsave(&vpmem->pmem_lock, flags); + virtio_pmem_drain(vpmem); + spin_unlock_irqrestore(&vpmem->pmem_lock, flags); + + vdev->config->del_vqs(vdev); + return 0; } -- 2.52.0

