We currently allow multiple instances of the control work handler to run in parallel. This isn't expected to work; serialise access by disabling interrupts on new packets from the Host and enable them when all the existing ones are consumed. Testcase: hot-plug/unplug a port in a loop. Without this patch, some sysfs warnings are seen along with freezes. With the patch, all works fine. Reported-by: Miche Baker-Harvey <miche@xxxxxxxxxx> Signed-off-by: Amit Shah <amit.shah@xxxxxxxxxx> --- drivers/char/virtio_console.c | 6 ++++++ 1 files changed, 6 insertions(+), 0 deletions(-) diff --git a/drivers/char/virtio_console.c b/drivers/char/virtio_console.c index fd2fd6f..fc54a79 100644 --- a/drivers/char/virtio_console.c +++ b/drivers/char/virtio_console.c @@ -1471,6 +1471,7 @@ static void control_work_handler(struct work_struct *work) portdev = container_of(work, struct ports_device, control_work); vq = portdev->c_ivq; + start: spin_lock(&portdev->cvq_lock); while ((buf = virtqueue_get_buf(vq, &len))) { spin_unlock(&portdev->cvq_lock); @@ -1488,6 +1489,10 @@ static void control_work_handler(struct work_struct *work) } } spin_unlock(&portdev->cvq_lock); + if (unlikely(!virtqueue_enable_cb(vq))) { + virtqueue_disable_cb(vq); + goto start; + } } static void out_intr(struct virtqueue *vq) @@ -1538,6 +1543,7 @@ static void control_intr(struct virtqueue *vq) { struct ports_device *portdev; + virtqueue_disable_cb(vq); portdev = vq->vdev->priv; schedule_work(&portdev->control_work); } -- 1.7.7.4 _______________________________________________ Virtualization mailing list Virtualization@xxxxxxxxxxxxxxxxxxxxxxxxxx https://lists.linuxfoundation.org/mailman/listinfo/virtualization