* [PATCH v1 1/2] virtio-pci: add error_detected for PCI AER recovery
2026-06-15 2:00 [PATCH v1 0/2] virtio: PCI ERS permanent failure teardown for virtio-blk Xixin Liu
@ 2026-06-10 6:20 ` Xixin Liu
2026-06-12 10:00 ` [PATCH v1 2/2] virtio-blk: mark disk dead on ERS permanent failure Xixin Liu
` (2 subsequent siblings)
3 siblings, 0 replies; 9+ messages in thread
From: Xixin Liu @ 2026-06-10 6:20 UTC (permalink / raw)
To: linux-block, virtualization
Cc: mst, jasowang, xuanzhuo, eperezma, pbonzini, stefanha, axboe,
linux-kernel, liuxixin
virtio-pci only registered reset_prepare/reset_done. The PCI error
recovery core treats devices without error_detected as NO_AER_DRIVER and
does not deliver pci_channel_io_perm_failure to the driver after a failed
recovery. Virtio devices therefore miss the normal ERS quiesce/teardown
sequence.
Register error_detected: quiesce on frozen (reset_prepare) before bus
reset; on perm_failure break virtqueues and return DISCONNECT. Block-layer
cleanup for virtio-blk is handled in the follow-up patch.
Signed-off-by: Xixin Liu <liuxixin@kylinos.cn>
---
drivers/virtio/virtio_pci_common.c | 30 +++++++++++++++++++++++++++++++
1 file changed, 30 insertions(+)
diff --git a/drivers/virtio/virtio_pci_common.c b/drivers/virtio/virtio_pci_common.c
index 164f480b18a6..e2dda946e70e 100644
--- a/drivers/virtio/virtio_pci_common.c
+++ b/drivers/virtio/virtio_pci_common.c
@@ -828,7 +828,37 @@ static void virtio_pci_reset_done(struct pci_dev *pci_dev)
dev_warn(&pci_dev->dev, "Reset done failure: %d", ret);
}
+static pci_ers_result_t virtio_pci_error_detected(struct pci_dev *pci_dev,
+ pci_channel_state_t state)
+{
+ struct virtio_pci_device *vp_dev = pci_get_drvdata(pci_dev);
+
+ /*
+ * PCI ERS error_detected: quiesce on frozen before bus reset; on
+ * permanent failure ask the virtio driver to shut down (virtio-blk
+ * marks the disk dead in its .shutdown handler).
+ */
+ switch (state) {
+ case pci_channel_io_normal:
+ return PCI_ERS_RESULT_CAN_RECOVER;
+ case pci_channel_io_frozen:
+ pci_info(pci_dev, "frozen error detected, quiesce device\n");
+ if (virtio_device_reset_prepare(&vp_dev->vdev))
+ dev_warn(&pci_dev->dev, "frozen: reset prepare failed\n");
+ return PCI_ERS_RESULT_NEED_RESET;
+ case pci_channel_io_perm_failure:
+ dev_warn(&pci_dev->dev,
+ "permanent failure, disconnecting device\n");
+ virtio_break_device(&vp_dev->vdev);
+ return PCI_ERS_RESULT_DISCONNECT;
+ default:
+ break;
+ }
+ return PCI_ERS_RESULT_NEED_RESET;
+}
+
static const struct pci_error_handlers virtio_pci_err_handler = {
+ .error_detected = virtio_pci_error_detected,
.reset_prepare = virtio_pci_reset_prepare,
.reset_done = virtio_pci_reset_done,
};
^ permalink raw reply related [flat|nested] 9+ messages in thread* [PATCH v1 2/2] virtio-blk: mark disk dead on ERS permanent failure
2026-06-15 2:00 [PATCH v1 0/2] virtio: PCI ERS permanent failure teardown for virtio-blk Xixin Liu
2026-06-10 6:20 ` [PATCH v1 1/2] virtio-pci: add error_detected for PCI AER recovery Xixin Liu
@ 2026-06-12 10:00 ` Xixin Liu
2026-07-30 23:13 ` Michael S. Tsirkin
2026-06-15 14:52 ` [PATCH v1 0/2] virtio: PCI ERS permanent failure teardown for virtio-blk Stefan Hajnoczi
2026-07-31 3:20 ` [PATCH v2 " Xixin Liu
3 siblings, 1 reply; 9+ messages in thread
From: Xixin Liu @ 2026-06-12 10:00 UTC (permalink / raw)
To: linux-block, virtualization
Cc: mst, jasowang, xuanzhuo, eperezma, pbonzini, stefanha, axboe,
linux-kernel, liuxixin
After ERS reports pci_channel_io_perm_failure, virtio-pci must ask the
virtio driver to tear down the block device — not only mark virtqueues
broken. Call the virtio driver shutdown hook from virtio-pci on
perm_failure; virtio-blk implements shutdown with blk_mark_disk_dead().
Fail new requests early in virtio_queue_rq when the disk is dead or
virtqueues were removed during frozen reset_prepare.
Signed-off-by: Xixin Liu <liuxixin@kylinos.cn>
---
drivers/block/virtio_blk.c | 39 +++++++++++++++++++++++++++++++++++++++
drivers/virtio/virtio_pci_common.c | 10 +++++++++-
2 files changed, 48 insertions(+), 1 deletion(-)
diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c
index 32bf3ba07a9d..4740ae91d5be 100644
--- a/drivers/block/virtio_blk.c
+++ b/drivers/block/virtio_blk.c
@@ -435,6 +435,12 @@ static blk_status_t virtio_queue_rq(struct blk_mq_hw_ctx *hctx,
blk_status_t status;
int err;
+ /* Fail fast if ERS frozen tore down VQs or the disk was marked dead. */
+ if (unlikely(!disk_live(vblk->disk) || !vblk->vqs || !vblk->vdev)) {
+ blk_mq_start_request(req);
+ return BLK_STS_IOERR;
+ }
+
status = virtblk_prep_rq(hctx, vblk, req, vbr);
if (unlikely(status))
return status;
@@ -1561,6 +1567,29 @@ static int virtblk_probe(struct virtio_device *vdev)
return err;
}
+/* Stop I/O and mark the gendisk dead (ERS perm_failure or system shutdown). */
+static void virtblk_shutdown(struct virtio_device *vdev)
+{
+ struct virtio_blk *vblk = vdev->priv;
+ struct request_queue *q;
+ unsigned int memflags;
+
+ if (!vblk || !vblk->disk)
+ return;
+
+ flush_work(&vblk->config_work);
+ virtio_break_device(vdev);
+
+ q = vblk->disk->queue;
+ memflags = blk_mq_freeze_queue(q);
+ blk_mq_quiesce_queue_nowait(q);
+
+ blk_mark_disk_dead(vblk->disk);
+
+ blk_mq_unquiesce_queue(q);
+ blk_mq_unfreeze_queue(q, memflags);
+}
+
static void virtblk_remove(struct virtio_device *vdev)
{
struct virtio_blk *vblk = vdev->priv;
@@ -1684,6 +1713,7 @@ static struct virtio_driver virtio_blk = {
.probe = virtblk_probe,
.remove = virtblk_remove,
.config_changed = virtblk_config_changed,
+ .shutdown = virtblk_shutdown,
#ifdef CONFIG_PM_SLEEP
.freeze = virtblk_freeze,
.restore = virtblk_restore,
diff --git a/drivers/virtio/virtio_pci_common.c b/drivers/virtio/virtio_pci_common.c
index e2dda946e70e..924ceead436b 100644
--- a/drivers/virtio/virtio_pci_common.c
+++ b/drivers/virtio/virtio_pci_common.c
@@ -845,7 +845,15 @@ static pci_ers_result_t virtio_pci_error_detected(struct pci_dev *pci_dev,
case pci_channel_io_perm_failure:
dev_warn(&pci_dev->dev,
"permanent failure, disconnecting device\n");
- virtio_break_device(&vp_dev->vdev);
+ {
+ struct virtio_driver *drv =
+ drv_to_virtio(vp_dev->vdev.dev.driver);
+
+ if (drv && drv->shutdown)
+ drv->shutdown(&vp_dev->vdev);
+ else
+ virtio_break_device(&vp_dev->vdev);
+ }
return PCI_ERS_RESULT_DISCONNECT;
default:
break;
^ permalink raw reply related [flat|nested] 9+ messages in thread* Re: [PATCH v1 2/2] virtio-blk: mark disk dead on ERS permanent failure
2026-06-12 10:00 ` [PATCH v1 2/2] virtio-blk: mark disk dead on ERS permanent failure Xixin Liu
@ 2026-07-30 23:13 ` Michael S. Tsirkin
2026-07-31 3:29 ` Xixin Liu
0 siblings, 1 reply; 9+ messages in thread
From: Michael S. Tsirkin @ 2026-07-30 23:13 UTC (permalink / raw)
To: Xixin Liu
Cc: linux-block, virtualization, jasowang, xuanzhuo, eperezma,
pbonzini, stefanha, axboe, linux-kernel
On Fri, Jun 12, 2026 at 06:00:00PM +0800, Xixin Liu wrote:
> After ERS reports pci_channel_io_perm_failure, virtio-pci must ask the
> virtio driver to tear down the block device — not only mark virtqueues
> broken.
Can you tell me was this written with use of AI? I ask because not many
people go out of their way to put in unicode dashes. Next step is what
emojis? Let's not go there pls.
And if yes pls disclose that as per Documentation.
> Call the virtio driver shutdown hook from virtio-pci on
> perm_failure; virtio-blk implements shutdown with blk_mark_disk_dead().
> Fail new requests early in virtio_queue_rq when the disk is dead or
> virtqueues were removed during frozen reset_prepare.
>
> Signed-off-by: Xixin Liu <liuxixin@kylinos.cn>
> ---
> drivers/block/virtio_blk.c | 39 +++++++++++++++++++++++++++++++++++++++
> drivers/virtio/virtio_pci_common.c | 10 +++++++++-
> 2 files changed, 48 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c
> index 32bf3ba07a9d..4740ae91d5be 100644
> --- a/drivers/block/virtio_blk.c
> +++ b/drivers/block/virtio_blk.c
> @@ -435,6 +435,12 @@ static blk_status_t virtio_queue_rq(struct blk_mq_hw_ctx *hctx,
> blk_status_t status;
> int err;
>
> + /* Fail fast if ERS frozen tore down VQs or the disk was marked dead. */
> + if (unlikely(!disk_live(vblk->disk) || !vblk->vqs || !vblk->vdev)) {
> + blk_mq_start_request(req);
> + return BLK_STS_IOERR;
> + }
> +
Do we need this? virtqueue add will fail anyway.
> status = virtblk_prep_rq(hctx, vblk, req, vbr);
> if (unlikely(status))
> return status;
> @@ -1561,6 +1567,29 @@ static int virtblk_probe(struct virtio_device *vdev)
> return err;
> }
>
> +/* Stop I/O and mark the gendisk dead (ERS perm_failure or system shutdown). */
> +static void virtblk_shutdown(struct virtio_device *vdev)
> +{
> + struct virtio_blk *vblk = vdev->priv;
> + struct request_queue *q;
> + unsigned int memflags;
> +
> + if (!vblk || !vblk->disk)
> + return;
> +
> + flush_work(&vblk->config_work);
> + virtio_break_device(vdev);
why not break first?
> + q = vblk->disk->queue;
> + memflags = blk_mq_freeze_queue(q);
> + blk_mq_quiesce_queue_nowait(q);
> +
> + blk_mark_disk_dead(vblk->disk);
> +
> + blk_mq_unquiesce_queue(q);
> + blk_mq_unfreeze_queue(q, memflags);
> +}
> +
> static void virtblk_remove(struct virtio_device *vdev)
> {
> struct virtio_blk *vblk = vdev->priv;
> @@ -1684,6 +1713,7 @@ static struct virtio_driver virtio_blk = {
> .probe = virtblk_probe,
> .remove = virtblk_remove,
> .config_changed = virtblk_config_changed,
> + .shutdown = virtblk_shutdown,
> #ifdef CONFIG_PM_SLEEP
> .freeze = virtblk_freeze,
> .restore = virtblk_restore,
> diff --git a/drivers/virtio/virtio_pci_common.c b/drivers/virtio/virtio_pci_common.c
> index e2dda946e70e..924ceead436b 100644
> --- a/drivers/virtio/virtio_pci_common.c
> +++ b/drivers/virtio/virtio_pci_common.c
> @@ -845,7 +845,15 @@ static pci_ers_result_t virtio_pci_error_detected(struct pci_dev *pci_dev,
> case pci_channel_io_perm_failure:
> dev_warn(&pci_dev->dev,
> "permanent failure, disconnecting device\n");
> - virtio_break_device(&vp_dev->vdev);
> + {
> + struct virtio_driver *drv =
> + drv_to_virtio(vp_dev->vdev.dev.driver);
> +
> + if (drv && drv->shutdown)
> + drv->shutdown(&vp_dev->vdev);
> + else
> + virtio_break_device(&vp_dev->vdev);
> + }
> return PCI_ERS_RESULT_DISCONNECT;
> default:
> break;
^ permalink raw reply [flat|nested] 9+ messages in thread* Re: [PATCH v1 2/2] virtio-blk: mark disk dead on ERS permanent failure
2026-07-30 23:13 ` Michael S. Tsirkin
@ 2026-07-31 3:29 ` Xixin Liu
0 siblings, 0 replies; 9+ messages in thread
From: Xixin Liu @ 2026-07-31 3:29 UTC (permalink / raw)
To: mst
Cc: linux-block, virtualization, jasowang, xuanzhuo, eperezma,
pbonzini, stefanha, axboe, linux-kernel, liuxixin
Hi,
On Thu, 30 Jul 2026, Michael S. Tsirkin wrote:
> Can you tell me was this written with use of AI? I ask because not many
> people go out of their way to put in unicode dashes. Next step is what
> emojis? Let's not go there pls.
> And if yes pls disclose that as per Documentation.
Yes. I will add Assisted-by for the LLM help in v2.
> Do we need this? virtqueue add will fail anyway.
For a broken vq, yes, virtqueue_add already fails. The useful part is
the !vblk->vqs check: after reset_prepare/freeze_priv the vqs pointer
can be NULL, and virtio_queue_rq would deref it before add. v2 drops
disk_live() and keeps only the NULL guards.
> why not break first?
Agreed. v2 calls virtio_break_device() before flush_work().
Thanks,
Xixin
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH v1 0/2] virtio: PCI ERS permanent failure teardown for virtio-blk
2026-06-15 2:00 [PATCH v1 0/2] virtio: PCI ERS permanent failure teardown for virtio-blk Xixin Liu
2026-06-10 6:20 ` [PATCH v1 1/2] virtio-pci: add error_detected for PCI AER recovery Xixin Liu
2026-06-12 10:00 ` [PATCH v1 2/2] virtio-blk: mark disk dead on ERS permanent failure Xixin Liu
@ 2026-06-15 14:52 ` Stefan Hajnoczi
2026-07-31 3:20 ` [PATCH v2 " Xixin Liu
3 siblings, 0 replies; 9+ messages in thread
From: Stefan Hajnoczi @ 2026-06-15 14:52 UTC (permalink / raw)
To: Xixin Liu
Cc: linux-block, virtualization, mst, jasowang, xuanzhuo, eperezma,
pbonzini, axboe, linux-kernel, Parav Pandit
[-- Attachment #1: Type: text/plain, Size: 1472 bytes --]
On Mon, Jun 15, 2026 at 10:00:00AM +0800, Xixin Liu wrote:
> Hi,
>
> This series adds proper PCI AER error recovery handling for virtio-pci and
> completes virtio-blk teardown when ERS reports pci_channel_io_perm_failure.
CCing Parav because he previously looked at surprise removal:
https://lore.kernel.org/virtualization/20250822091706.21170-1-parav@nvidia.com/
>
> virtio-pci only registered reset_prepare/reset_done. The recovery core
> treats devices without error_detected as NO_AER_DRIVER and does not
> deliver perm_failure to the driver after a failed recovery. When bus
> reset fails (reproduced on QEMU with DLLLA not set within 100 ms after
> secondary bus reset), virtio-blk disks stay live even though virtqueues
> may already have been torn down during the frozen phase.
>
> Patch 1 registers error_detected (frozen quiesce + perm_failure notify).
> Patch 2 calls the virtio driver shutdown hook from virtio-pci on
> perm_failure, implements virtio-blk shutdown with blk_mark_disk_dead(),
> and fail-fast guards in virtio_queue_rq.
>
> Thanks,
> Xixin Liu
>
> ---
>
> Xixin Liu (2):
> virtio-pci: add error_detected for PCI AER recovery
> virtio-blk: mark disk dead on ERS permanent failure
>
> drivers/block/virtio_blk.c | 39 +++++++++++++++++++++++++++++++
> drivers/virtio/virtio_pci_common.c | 47 ++++++++++++++++++++++++++++++++++
> 2 files changed, 85 insertions(+)
>
> --
> 2.43.0
>
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]
^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH v2 0/2] virtio: PCI ERS permanent failure teardown for virtio-blk
2026-06-15 2:00 [PATCH v1 0/2] virtio: PCI ERS permanent failure teardown for virtio-blk Xixin Liu
` (2 preceding siblings ...)
2026-06-15 14:52 ` [PATCH v1 0/2] virtio: PCI ERS permanent failure teardown for virtio-blk Stefan Hajnoczi
@ 2026-07-31 3:20 ` Xixin Liu
2026-07-31 3:17 ` [PATCH v2 1/2] virtio-pci: add error_detected for PCI AER recovery Xixin Liu
2026-07-31 3:19 ` [PATCH v2 2/2] virtio-blk: mark disk dead on ERS permanent failure Xixin Liu
3 siblings, 2 replies; 9+ messages in thread
From: Xixin Liu @ 2026-07-31 3:20 UTC (permalink / raw)
To: linux-block
Cc: virtualization, mst, jasowang, xuanzhuo, eperezma, pbonzini,
stefanha, axboe, linux-kernel, liuxixin
Hi,
This series adds PCI AER error_detected for virtio-pci and completes
virtio-blk teardown when ERS reports pci_channel_io_perm_failure.
virtio-pci only registered reset_prepare/reset_done. The recovery core
treats devices without error_detected as NO_AER_DRIVER and does not
deliver perm_failure to the driver after a failed recovery. When bus
reset fails (reproduced on QEMU with DLLLA not set within 100 ms after
secondary bus reset), virtio-blk disks stay live even though virtqueues
may already have been torn down during the frozen phase.
Patch 1 registers error_detected (frozen quiesce + perm_failure notify).
Patch 2 calls the virtio driver shutdown hook from virtio-pci on
perm_failure and implements virtio-blk shutdown with blk_mark_disk_dead().
Changes since v1 (thanks for the review on v1):
- Disclose LLM help on the commit message (Assisted-by); ASCII only
- virtblk_shutdown: virtio_break_device() before flush_work()
- virtio_queue_rq: drop disk_live(); keep NULL vqs/vdev guards only
(broken vq already fails in virtqueue_add)
Based on linux-next next-20260730.
Thanks,
Xixin Liu
---
Xixin Liu (2):
virtio-pci: add error_detected for PCI AER recovery
virtio-blk: mark disk dead on ERS permanent failure
drivers/block/virtio_blk.c | 31 ++++++++++++++++++++++++
drivers/virtio/virtio_pci_common.c | 38 ++++++++++++++++++++++++++++++
2 files changed, 69 insertions(+)
--
2.43.0
^ permalink raw reply [flat|nested] 9+ messages in thread* [PATCH v2 1/2] virtio-pci: add error_detected for PCI AER recovery
2026-07-31 3:20 ` [PATCH v2 " Xixin Liu
@ 2026-07-31 3:17 ` Xixin Liu
2026-07-31 3:19 ` [PATCH v2 2/2] virtio-blk: mark disk dead on ERS permanent failure Xixin Liu
1 sibling, 0 replies; 9+ messages in thread
From: Xixin Liu @ 2026-07-31 3:17 UTC (permalink / raw)
To: linux-block
Cc: virtualization, mst, jasowang, xuanzhuo, eperezma, pbonzini,
stefanha, axboe, linux-kernel, liuxixin
virtio-pci only registered reset_prepare/reset_done. The PCI error
recovery core treats devices without error_detected as NO_AER_DRIVER and
does not deliver pci_channel_io_perm_failure to the driver after a failed
recovery. Virtio devices therefore miss the normal ERS quiesce/teardown
sequence.
Register error_detected: quiesce on frozen (reset_prepare) before bus
reset; on perm_failure break virtqueues and return DISCONNECT. Block-layer
cleanup for virtio-blk is handled in the follow-up patch.
Assisted-by: DeepSeek:deepseek-v3
Signed-off-by: Xixin Liu <liuxixin@kylinos.cn>
---
drivers/virtio/virtio_pci_common.c | 30 ++++++++++++++++++++++++++++++
1 file changed, 30 insertions(+)
diff --git a/drivers/virtio/virtio_pci_common.c b/drivers/virtio/virtio_pci_common.c
index 164f480b18a6..fff6b6e2d0c5 100644
--- a/drivers/virtio/virtio_pci_common.c
+++ b/drivers/virtio/virtio_pci_common.c
@@ -828,7 +828,37 @@ static void virtio_pci_reset_done(struct pci_dev *pci_dev)
dev_warn(&pci_dev->dev, "Reset done failure: %d", ret);
}
+static pci_ers_result_t virtio_pci_error_detected(struct pci_dev *pci_dev,
+ pci_channel_state_t state)
+{
+ struct virtio_pci_device *vp_dev = pci_get_drvdata(pci_dev);
+
+ /*
+ * PCI ERS error_detected: quiesce on frozen before bus reset; on
+ * permanent failure break virtqueues (follow-up may call driver
+ * .shutdown for block teardown).
+ */
+ switch (state) {
+ case pci_channel_io_normal:
+ return PCI_ERS_RESULT_CAN_RECOVER;
+ case pci_channel_io_frozen:
+ pci_info(pci_dev, "frozen error detected, quiesce device\n");
+ if (virtio_device_reset_prepare(&vp_dev->vdev))
+ dev_warn(&pci_dev->dev, "frozen: reset prepare failed\n");
+ return PCI_ERS_RESULT_NEED_RESET;
+ case pci_channel_io_perm_failure:
+ dev_warn(&pci_dev->dev,
+ "permanent failure, disconnecting device\n");
+ virtio_break_device(&vp_dev->vdev);
+ return PCI_ERS_RESULT_DISCONNECT;
+ default:
+ break;
+ }
+ return PCI_ERS_RESULT_NEED_RESET;
+}
+
static const struct pci_error_handlers virtio_pci_err_handler = {
+ .error_detected = virtio_pci_error_detected,
.reset_prepare = virtio_pci_reset_prepare,
.reset_done = virtio_pci_reset_done,
};
--
2.43.0
^ permalink raw reply related [flat|nested] 9+ messages in thread* [PATCH v2 2/2] virtio-blk: mark disk dead on ERS permanent failure
2026-07-31 3:20 ` [PATCH v2 " Xixin Liu
2026-07-31 3:17 ` [PATCH v2 1/2] virtio-pci: add error_detected for PCI AER recovery Xixin Liu
@ 2026-07-31 3:19 ` Xixin Liu
1 sibling, 0 replies; 9+ messages in thread
From: Xixin Liu @ 2026-07-31 3:19 UTC (permalink / raw)
To: linux-block
Cc: virtualization, mst, jasowang, xuanzhuo, eperezma, pbonzini,
stefanha, axboe, linux-kernel, liuxixin
After ERS reports pci_channel_io_perm_failure, virtio-pci must ask the
virtio driver to tear down the block device, not only mark virtqueues
broken. Call the virtio driver shutdown hook from virtio-pci on
perm_failure; virtio-blk implements shutdown with blk_mark_disk_dead().
Fail new requests early in virtio_queue_rq when virtqueues were removed
during frozen reset_prepare (vqs == NULL). A broken vq already fails in
virtqueue_add; no separate disk_live() check is needed.
Assisted-by: DeepSeek:deepseek-v3
Signed-off-by: Xixin Liu <liuxixin@kylinos.cn>
---
drivers/block/virtio_blk.c | 31 ++++++++++++++++++++++++++++++
drivers/virtio/virtio_pci_common.c | 10 +++++++++-
2 files changed, 40 insertions(+), 1 deletion(-)
diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c
index 32bf3ba07a9d..fda2d4f3c7c6 100644
--- a/drivers/block/virtio_blk.c
+++ b/drivers/block/virtio_blk.c
@@ -435,6 +435,12 @@ static blk_status_t virtio_queue_rq(struct blk_mq_hw_ctx *hctx,
blk_status_t status;
int err;
+ /* VQs may be gone after frozen reset_prepare; avoid NULL deref. */
+ if (unlikely(!vblk->vqs || !vblk->vdev)) {
+ blk_mq_start_request(req);
+ return BLK_STS_IOERR;
+ }
+
status = virtblk_prep_rq(hctx, vblk, req, vbr);
if (unlikely(status))
return status;
@@ -1561,6 +1567,30 @@ static int virtblk_probe(struct virtio_device *vdev)
return err;
}
+
+/* Stop I/O and mark the gendisk dead (ERS perm_failure or system shutdown). */
+static void virtblk_shutdown(struct virtio_device *vdev)
+{
+ struct virtio_blk *vblk = vdev->priv;
+ struct request_queue *q;
+ unsigned int memflags;
+
+ if (!vblk || !vblk->disk)
+ return;
+
+ virtio_break_device(vdev);
+ flush_work(&vblk->config_work);
+
+ q = vblk->disk->queue;
+ memflags = blk_mq_freeze_queue(q);
+ blk_mq_quiesce_queue_nowait(q);
+
+ blk_mark_disk_dead(vblk->disk);
+
+ blk_mq_unquiesce_queue(q);
+ blk_mq_unfreeze_queue(q, memflags);
+}
+
static void virtblk_remove(struct virtio_device *vdev)
{
struct virtio_blk *vblk = vdev->priv;
@@ -1684,6 +1714,7 @@ static struct virtio_driver virtio_blk = {
.probe = virtblk_probe,
.remove = virtblk_remove,
.config_changed = virtblk_config_changed,
+ .shutdown = virtblk_shutdown,
#ifdef CONFIG_PM_SLEEP
.freeze = virtblk_freeze,
.restore = virtblk_restore,
diff --git a/drivers/virtio/virtio_pci_common.c b/drivers/virtio/virtio_pci_common.c
index fff6b6e2d0c5..957b3282865c 100644
--- a/drivers/virtio/virtio_pci_common.c
+++ b/drivers/virtio/virtio_pci_common.c
@@ -849,7 +849,15 @@ static pci_ers_result_t virtio_pci_error_detected(struct pci_dev *pci_dev,
case pci_channel_io_perm_failure:
dev_warn(&pci_dev->dev,
"permanent failure, disconnecting device\n");
- virtio_break_device(&vp_dev->vdev);
+ {
+ struct virtio_driver *drv =
+ drv_to_virtio(vp_dev->vdev.dev.driver);
+
+ if (drv && drv->shutdown)
+ drv->shutdown(&vp_dev->vdev);
+ else
+ virtio_break_device(&vp_dev->vdev);
+ }
return PCI_ERS_RESULT_DISCONNECT;
default:
break;
--
2.43.0
^ permalink raw reply related [flat|nested] 9+ messages in thread