* [PATCH 0/1] virtio_ccw: exploit virtio_break_device()
@ 2014-04-25 12:35 Heinz Graalfs
2014-04-25 12:35 ` [PATCH 1/1] virtio_ccw: introduce device_lost in virtio_ccw_device Heinz Graalfs
0 siblings, 1 reply; 3+ messages in thread
From: Heinz Graalfs @ 2014-04-25 12:35 UTC (permalink / raw)
To: rusty; +Cc: borntraeger, virtualization
Rusty,
this patch exploits the new function virtio_break_device() as of your patch
set dated January 15th on linux-kernel@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
^ permalink raw reply [flat|nested] 3+ messages in thread
* [PATCH 1/1] virtio_ccw: introduce device_lost in virtio_ccw_device
2014-04-25 12:35 [PATCH 0/1] virtio_ccw: exploit virtio_break_device() Heinz Graalfs
@ 2014-04-25 12:35 ` Heinz Graalfs
2014-04-28 1:54 ` Rusty Russell
0 siblings, 1 reply; 3+ messages in thread
From: Heinz Graalfs @ 2014-04-25 12:35 UTC (permalink / raw)
To: rusty; +Cc: borntraeger, virtualization
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@linux.vnet.ibm.com>
Reviewed-by: Cornelia Huck <cornelia.huck@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
^ permalink raw reply related [flat|nested] 3+ messages in thread
* Re: [PATCH 1/1] virtio_ccw: introduce device_lost in virtio_ccw_device
2014-04-25 12:35 ` [PATCH 1/1] virtio_ccw: introduce device_lost in virtio_ccw_device Heinz Graalfs
@ 2014-04-28 1:54 ` Rusty Russell
0 siblings, 0 replies; 3+ messages in thread
From: Rusty Russell @ 2014-04-28 1:54 UTC (permalink / raw)
To: Heinz Graalfs; +Cc: borntraeger, virtualization
Heinz Graalfs <graalfs@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@linux.vnet.ibm.com>
> Reviewed-by: Cornelia Huck <cornelia.huck@de.ibm.com>
Thanks!
Applied,
Rusty.
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2014-04-28 1:54 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-04-25 12:35 [PATCH 0/1] virtio_ccw: exploit virtio_break_device() Heinz Graalfs
2014-04-25 12:35 ` [PATCH 1/1] virtio_ccw: introduce device_lost in virtio_ccw_device Heinz Graalfs
2014-04-28 1:54 ` Rusty Russell
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.