virtio: reset function
A reset function solves three problems:
1) It allows us to renegotiate features, eg. if we want to upgrade a
guest driver without rebooting the guest.
2) It gives us a clean way of shutting down virtqueues: after a reset,
we know that the buffers won't be used by the host, and
3) It helps the guest recover from messed-up drivers.
So we remove the ->shutdown hook, and the only way we now remove
feature bits is via reset.
We leave it to the driver to do the reset before it deletes queues:
the balloon driver, for example, needs to chat to the host in its
remove function.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c
index 54a8017..6143337 100644
--- a/drivers/block/virtio_blk.c
+++ b/drivers/block/virtio_blk.c
@@ -264,12 +264,16 @@
struct virtio_blk *vblk = vdev->priv;
int major = vblk->disk->major;
+ /* Nothing should be pending. */
BUG_ON(!list_empty(&vblk->reqs));
+
+ /* Stop all the virtqueues. */
+ vdev->config->reset(vdev);
+
blk_cleanup_queue(vblk->disk->queue);
put_disk(vblk->disk);
unregister_blkdev(major, "virtblk");
mempool_destroy(vblk->pool);
- /* There should be nothing in the queue now, so no need to shutdown */
vdev->config->del_vq(vblk->vq);
kfree(vblk);
}