Rusty, this patch exploits the new function virtio_break_device() as of your patch set dated January 15th on linux-kernel at vger.kernel.org. The patch avoids hang situations during device unregister, when a (block) device with active IO is hot-unplugged. Heinz Graalfs (1): virtio_ccw: introduce device_lost in virtio_ccw_device drivers/s390/kvm/virtio_ccw.c | 49 ++++++++++++++++++++++++++++++++----------- 1 file changed, 37 insertions(+), 12 deletions(-) -- 1.8.3.1
Heinz Graalfs
2014-Apr-25 12:35 UTC
[PATCH 1/1] virtio_ccw: introduce device_lost in virtio_ccw_device
When a device is lost, the common I/O layer calls the notification handler with CIO_GONE: In that event, flag device_lost as true. In case the device had been flagged as lost when the remove/offline callbacks are called, call the new virtio_break_device() function prior to invoking device_unregister(). This avoids hangs of I/O triggered via the device unregistration callbacks. Signed-off-by: Heinz Graalfs <graalfs at linux.vnet.ibm.com> Reviewed-by: Cornelia Huck <cornelia.huck at de.ibm.com> --- drivers/s390/kvm/virtio_ccw.c | 49 ++++++++++++++++++++++++++++++++----------- 1 file changed, 37 insertions(+), 12 deletions(-) diff --git a/drivers/s390/kvm/virtio_ccw.c b/drivers/s390/kvm/virtio_ccw.c index 1e1fc67..d2c0b44 100644 --- a/drivers/s390/kvm/virtio_ccw.c +++ b/drivers/s390/kvm/virtio_ccw.c @@ -27,6 +27,7 @@ #include <linux/module.h> #include <linux/io.h> #include <linux/kvm_para.h> +#include <linux/notifier.h> #include <asm/setup.h> #include <asm/irq.h> #include <asm/cio.h> @@ -62,6 +63,7 @@ struct virtio_ccw_device { struct vq_config_block *config_block; bool is_thinint; bool going_away; + bool device_lost; void *airq_info; }; @@ -1010,11 +1012,14 @@ static void virtio_ccw_remove(struct ccw_device *cdev) unsigned long flags; struct virtio_ccw_device *vcdev = virtio_grab_drvdata(cdev); - if (vcdev && cdev->online) + if (vcdev && cdev->online) { + if (vcdev->device_lost) + virtio_break_device(&vcdev->vdev); unregister_virtio_device(&vcdev->vdev); - spin_lock_irqsave(get_ccwdev_lock(cdev), flags); - dev_set_drvdata(&cdev->dev, NULL); - spin_unlock_irqrestore(get_ccwdev_lock(cdev), flags); + spin_lock_irqsave(get_ccwdev_lock(cdev), flags); + dev_set_drvdata(&cdev->dev, NULL); + spin_unlock_irqrestore(get_ccwdev_lock(cdev), flags); + } cdev->handler = NULL; } @@ -1023,12 +1028,14 @@ static int virtio_ccw_offline(struct ccw_device *cdev) unsigned long flags; struct virtio_ccw_device *vcdev = virtio_grab_drvdata(cdev); - if (vcdev) { - unregister_virtio_device(&vcdev->vdev); - spin_lock_irqsave(get_ccwdev_lock(cdev), flags); - dev_set_drvdata(&cdev->dev, NULL); - spin_unlock_irqrestore(get_ccwdev_lock(cdev), flags); - } + if (!vcdev) + return 0; + if (vcdev->device_lost) + virtio_break_device(&vcdev->vdev); + unregister_virtio_device(&vcdev->vdev); + spin_lock_irqsave(get_ccwdev_lock(cdev), flags); + dev_set_drvdata(&cdev->dev, NULL); + spin_unlock_irqrestore(get_ccwdev_lock(cdev), flags); return 0; } @@ -1096,8 +1103,26 @@ out_free: static int virtio_ccw_cio_notify(struct ccw_device *cdev, int event) { - /* TODO: Check whether we need special handling here. */ - return 0; + int rc; + struct virtio_ccw_device *vcdev = dev_get_drvdata(&cdev->dev); + + /* + * Make sure vcdev is set + * i.e. set_offline/remove callback not already running + */ + if (!vcdev) + return NOTIFY_DONE; + + switch (event) { + case CIO_GONE: + vcdev->device_lost = true; + rc = NOTIFY_DONE; + break; + default: + rc = NOTIFY_DONE; + break; + } + return rc; } static struct ccw_device_id virtio_ids[] = { -- 1.8.3.1
Rusty Russell
2014-Apr-28 01:54 UTC
[PATCH 1/1] virtio_ccw: introduce device_lost in virtio_ccw_device
Heinz Graalfs <graalfs at linux.vnet.ibm.com> writes:> When a device is lost, the common I/O layer calls the notification > handler with CIO_GONE: In that event, flag device_lost as true. > > In case the device had been flagged as lost when the remove/offline callbacks > are called, call the new virtio_break_device() function prior to invoking > device_unregister(). This avoids hangs of I/O triggered via the device > unregistration callbacks. > > Signed-off-by: Heinz Graalfs <graalfs at linux.vnet.ibm.com> > Reviewed-by: Cornelia Huck <cornelia.huck at de.ibm.com>Thanks! Applied, Rusty.
Reasonably Related Threads
- [PATCH 0/1] virtio_ccw: exploit virtio_break_device()
- [PATCH v4 RFC 0/3] virtio: add 'device_lost' to virtio_device
- [PATCH v4 RFC 0/3] virtio: add 'device_lost' to virtio_device
- [PATCH 1/1] virtio_ccw: introduce device_lost in virtio_ccw_device
- [PATCH v2 RFC 3/3] virtio_ccw: invoke virtio_driver's notify() on CIO_GONE notification