[PATCH 12/13] virtio: Delete vqs when removing a device

Simon Glass sjg at chromium.org
Wed May 27 18:10:22 CEST 2026


The rng, net, blk and scsi drivers all use virtio_reset() as their
remove() method.

virtio_reset() only uses the transport's reset() operation, leaving the
virtual queues still allocated (12 KB per virtqueue). Every probe/remove
cycle of a virtio device therefore fails to free its queues.

Add a remove() method to delete the queues before resetting. Update the
four drivers to use it.

Signed-off-by: Simon Glass <sjg at chromium.org>
---

 drivers/virtio/virtio-uclass.c | 7 +++++++
 drivers/virtio/virtio_blk.c    | 2 +-
 drivers/virtio/virtio_net.c    | 2 +-
 drivers/virtio/virtio_rng.c    | 2 +-
 include/virtio.h               | 8 ++++++++
 5 files changed, 18 insertions(+), 3 deletions(-)

diff --git a/drivers/virtio/virtio-uclass.c b/drivers/virtio/virtio-uclass.c
index 7003f30cb85..532d50ea088 100644
--- a/drivers/virtio/virtio-uclass.c
+++ b/drivers/virtio/virtio-uclass.c
@@ -90,6 +90,13 @@ int virtio_reset(struct udevice *vdev)
 	return ops->reset(vdev->parent);
 }
 
+int virtio_remove(struct udevice *vdev)
+{
+	virtio_del_vqs(vdev);
+
+	return virtio_reset(vdev);
+}
+
 int virtio_get_features(struct udevice *vdev, u64 *features)
 {
 	struct dm_virtio_ops *ops;
diff --git a/drivers/virtio/virtio_blk.c b/drivers/virtio/virtio_blk.c
index 404d9140cb2..fe06135a7ac 100644
--- a/drivers/virtio/virtio_blk.c
+++ b/drivers/virtio/virtio_blk.c
@@ -296,7 +296,7 @@ U_BOOT_DRIVER(virtio_blk) = {
 	.ops	= &virtio_blk_ops,
 	.bind	= virtio_blk_bind,
 	.probe	= virtio_blk_probe,
-	.remove	= virtio_reset,
+	.remove	= virtio_remove,
 	.priv_auto	= sizeof(struct virtio_blk_priv),
 	.flags	= DM_FLAG_ACTIVE_DMA,
 };
diff --git a/drivers/virtio/virtio_net.c b/drivers/virtio/virtio_net.c
index 7a94c8a528f..d49dab3a6ed 100644
--- a/drivers/virtio/virtio_net.c
+++ b/drivers/virtio/virtio_net.c
@@ -233,7 +233,7 @@ U_BOOT_DRIVER(virtio_net) = {
 	.id	= UCLASS_ETH,
 	.bind	= virtio_net_bind,
 	.probe	= virtio_net_probe,
-	.remove = virtio_reset,
+	.remove = virtio_remove,
 	.ops	= &virtio_net_ops,
 	.priv_auto	= sizeof(struct virtio_net_priv),
 	.plat_auto	= sizeof(struct eth_pdata),
diff --git a/drivers/virtio/virtio_rng.c b/drivers/virtio/virtio_rng.c
index c6de62142bb..9a5db5f3930 100644
--- a/drivers/virtio/virtio_rng.c
+++ b/drivers/virtio/virtio_rng.c
@@ -89,7 +89,7 @@ U_BOOT_DRIVER(virtio_rng) = {
 	.id	= UCLASS_RNG,
 	.bind	= virtio_rng_bind,
 	.probe	= virtio_rng_probe,
-	.remove = virtio_reset,
+	.remove = virtio_remove,
 	.ops	= &virtio_rng_ops,
 	.priv_auto	= sizeof(struct virtio_rng_priv),
 	.flags	= DM_FLAG_ACTIVE_DMA,
diff --git a/include/virtio.h b/include/virtio.h
index 3edf023463d..5c580e59779 100644
--- a/include/virtio.h
+++ b/include/virtio.h
@@ -285,6 +285,14 @@ int virtio_set_status(struct udevice *vdev, u8 status);
  */
 int virtio_reset(struct udevice *vdev);
 
+/**
+ * virtio_remove() - remove a virtio device by deleting its vqs and resetting it
+ *
+ * @vdev:	the real virtio device
+ * Return: 0 if OK, -ve on error
+ */
+int virtio_remove(struct udevice *vdev);
+
 /**
  * virtio_get_features() - get the array of feature bits for this device
  *
-- 
2.43.0



More information about the U-Boot mailing list