Re: [PATCH v2 1/2] virtio-pci: add error_detected for PCI AER recovery

"Michael S. Tsirkin" <[email protected]> Sun, 2 Aug 2026 17:10:21 -0400
Newsgroups dev.linux.lists.virtualization,org.kernel.vger.linux-block,org.kernel.vger.linux-kernel
Message-ID <[email protected]>
On Fri, Jul 31, 2026 at 11:17:00AM +0800, Xixin Liu wrote:
> 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.

Maybe it should?

> 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 <[email protected]>
> ---
>  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).

block specifically? this is common code.

> +	 */
> +	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;

so I guess pci will do slot reset? but what will call driver reset later? confused.


> +	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;

here, too, and we didn't virtio_device_reset_prepare either.

> +}
> +
>  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