Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S933498AbbFPJOn (ORCPT ); Tue, 16 Jun 2015 05:14:43 -0400 Received: from mail.kernel.org ([198.145.29.136]:55975 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1756846AbbFPIqA (ORCPT ); Tue, 16 Jun 2015 04:46:00 -0400 From: lizf@kernel.org To: stable@vger.kernel.org Cc: linux-kernel@vger.kernel.org, "Michael S. Tsirkin" , Rusty Russell , Zefan Li Subject: [PATCH 3.4 101/172] virtio_console: avoid config access from irq Date: Tue, 16 Jun 2015 16:35:55 +0800 Message-Id: <1434443826-4929-101-git-send-email-lizf@kernel.org> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1434443587-4599-1-git-send-email-lizf@kernel.org> References: <1434443587-4599-1-git-send-email-lizf@kernel.org> Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 2866 Lines: 90 From: "Michael S. Tsirkin" 3.4.108-rc1 review patch. If anyone has any objections, please let me know. ------------------ commit eeb8a7e8bb123e84daeef84f5a2eab99ad2839a2 upstream. when multiport is off, virtio console invokes config access from irq context, config access is blocking on s390. Fix this up by scheduling work from config irq - similar to what we do for multiport configs. Signed-off-by: Michael S. Tsirkin Reviewed-by: Amit Shah Signed-off-by: Rusty Russell [lizf: Backported to 3.4: adjust context] Signed-off-by: Zefan Li --- drivers/char/virtio_console.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/drivers/char/virtio_console.c b/drivers/char/virtio_console.c index 82650b4..96f4a50 100644 --- a/drivers/char/virtio_console.c +++ b/drivers/char/virtio_console.c @@ -124,6 +124,7 @@ struct ports_device { * notification */ struct work_struct control_work; + struct work_struct config_work; struct list_head ports; @@ -1555,10 +1556,21 @@ static void config_intr(struct virtio_device *vdev) portdev = vdev->priv; + if (!use_multiport(portdev)) + schedule_work(&portdev->config_work); +} + +static void config_work_handler(struct work_struct *work) +{ + struct ports_device *portdev; + + portdev = container_of(work, struct ports_device, control_work); if (!use_multiport(portdev)) { + struct virtio_device *vdev; struct port *port; u16 rows, cols; + vdev = portdev->vdev; vdev->config->get(vdev, offsetof(struct virtio_console_config, cols), &cols, sizeof(u16)); @@ -1752,6 +1764,7 @@ static int __devinit virtcons_probe(struct virtio_device *vdev) spin_lock_init(&portdev->ports_lock); INIT_LIST_HEAD(&portdev->ports); + INIT_WORK(&portdev->config_work, &config_work_handler); INIT_WORK(&portdev->control_work, &control_work_handler); if (multiport) { @@ -1826,6 +1839,8 @@ static void virtcons_remove(struct virtio_device *vdev) /* Finish up work that's lined up */ if (use_multiport(portdev)) cancel_work_sync(&portdev->control_work); + else + cancel_work_sync(&portdev->config_work); list_for_each_entry_safe(port, port2, &portdev->ports, list) unplug_port(port); @@ -1867,6 +1882,7 @@ static int virtcons_freeze(struct virtio_device *vdev) virtqueue_disable_cb(portdev->c_ivq); cancel_work_sync(&portdev->control_work); + cancel_work_sync(&portdev->config_work); /* * Once more: if control_work_handler() was running, it would * enable the cb as the last step. -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/