From patchwork Sun Jan 3 05:06:07 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Finn Thain X-Patchwork-Id: 7941661 Return-Path: X-Original-To: patchwork-linux-arm@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 92FEABEEE5 for ; Sun, 3 Jan 2016 05:21:27 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 8D14720260 for ; Sun, 3 Jan 2016 05:21:26 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.9]) (using TLSv1.2 with cipher AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 590F5200F2 for ; Sun, 3 Jan 2016 05:21:25 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1aFb4Y-00033I-Sg; Sun, 03 Jan 2016 05:19:18 +0000 Received: from kvm5.telegraphics.com.au ([98.124.60.144]) by bombadil.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1aFb46-0002pz-T3 for linux-arm-kernel@lists.infradead.org; Sun, 03 Jan 2016 05:18:53 +0000 Received: by kvm5.telegraphics.com.au (Postfix, from userid 502) id 500C222CFC; Sun, 3 Jan 2016 00:18:11 -0500 (EST) Message-Id: <20160103050519.224002898@telegraphics.com.au> User-Agent: quilt/0.50-1 Date: Sun, 03 Jan 2016 16:06:07 +1100 From: Finn Thain To: "James E.J. Bottomley" , "Martin K. Petersen" , Michael Schmitz , , , , Russell King , linux-arm-kernel@lists.infradead.org Subject: [PATCH v4 66/78] ncr5380: Fix soft lockups References: <20160103050501.042035135@telegraphics.com.au> Content-Disposition: inline; filename=ncr5380-max_sectors X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20160102_211851_297821_16192497 X-CRM114-Status: GOOD ( 10.60 ) X-Spam-Score: -1.9 (-) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Spam-Status: No, score=-4.2 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_MED, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Because of the rudimentary design of the chip, it is necessary to poll the SCSI bus signals during PIO and this tends to hog the CPU. The driver will accept new commands while others execute, and this causes a soft lockup because the workqueue item will not terminate until the issue queue is emptied. When exercising dmx3191d using sequential IO from dd, the driver is sent 512 KiB WRITE commands and 128 KiB READs. For a PIO transfer, the rate is is only about 300 KiB/s, so these are long-running commands. And although PDMA may run at several MiB/s, interrupts are disabled for the duration of the transfer. Fix the unresponsiveness and soft lockup issues by calling cond_resched() after each command is completed and by limiting max_sectors for drivers that don't implement real DMA. Signed-off-by: Finn Thain Reviewed-by: Hannes Reinecke Tested-by: Ondrej Zary Tested-by: Michael Schmitz --- Changed since v2: - Moved max_sectors initialization to wrapper drivers. It isn't really relevant to the core driver and compile-time configuration using macros like REAL_DMA should be avoided. --- drivers/scsi/NCR5380.c | 6 ++++-- drivers/scsi/arm/cumana_1.c | 1 + drivers/scsi/arm/oak.c | 1 + drivers/scsi/atari_NCR5380.c | 6 ++++-- drivers/scsi/dmx3191d.c | 1 + drivers/scsi/dtc.c | 1 + drivers/scsi/g_NCR5380.c | 1 + drivers/scsi/mac_scsi.c | 1 + drivers/scsi/pas16.c | 1 + drivers/scsi/t128.c | 1 + 10 files changed, 16 insertions(+), 4 deletions(-) Index: linux/drivers/scsi/NCR5380.c =================================================================== --- linux.orig/drivers/scsi/NCR5380.c 2016-01-03 16:04:34.000000000 +1100 +++ linux/drivers/scsi/NCR5380.c 2016-01-03 16:04:38.000000000 +1100 @@ -890,10 +890,10 @@ static void NCR5380_main(struct work_str struct scsi_cmnd *cmd; int done; - spin_lock_irq(&hostdata->lock); do { done = 1; + spin_lock_irq(&hostdata->lock); while (!hostdata->connected && (cmd = dequeue_next_cmd(instance))) { @@ -930,8 +930,10 @@ static void NCR5380_main(struct work_str NCR5380_information_transfer(instance); done = 0; } + spin_unlock_irq(&hostdata->lock); + if (!done) + cond_resched(); } while (!done); - spin_unlock_irq(&hostdata->lock); } #ifndef DONT_USE_INTR Index: linux/drivers/scsi/atari_NCR5380.c =================================================================== --- linux.orig/drivers/scsi/atari_NCR5380.c 2016-01-03 16:04:36.000000000 +1100 +++ linux/drivers/scsi/atari_NCR5380.c 2016-01-03 16:04:38.000000000 +1100 @@ -976,10 +976,10 @@ static void NCR5380_main(struct work_str * alter queues and touch the Falcon lock. */ - spin_lock_irq(&hostdata->lock); do { done = 1; + spin_lock_irq(&hostdata->lock); while (!hostdata->connected && (cmd = dequeue_next_cmd(instance))) { @@ -1026,8 +1026,10 @@ static void NCR5380_main(struct work_str NCR5380_information_transfer(instance); done = 0; } + spin_unlock_irq(&hostdata->lock); + if (!done) + cond_resched(); } while (!done); - spin_unlock_irq(&hostdata->lock); } Index: linux/drivers/scsi/arm/cumana_1.c =================================================================== --- linux.orig/drivers/scsi/arm/cumana_1.c 2016-01-03 16:04:20.000000000 +1100 +++ linux/drivers/scsi/arm/cumana_1.c 2016-01-03 16:04:38.000000000 +1100 @@ -209,6 +209,7 @@ static struct scsi_host_template cumanas .use_clustering = DISABLE_CLUSTERING, .proc_name = "CumanaSCSI-1", .cmd_size = NCR5380_CMD_SIZE, + .max_sectors = 128, }; static int cumanascsi1_probe(struct expansion_card *ec, Index: linux/drivers/scsi/arm/oak.c =================================================================== --- linux.orig/drivers/scsi/arm/oak.c 2016-01-03 16:04:20.000000000 +1100 +++ linux/drivers/scsi/arm/oak.c 2016-01-03 16:04:38.000000000 +1100 @@ -115,6 +115,7 @@ static struct scsi_host_template oakscsi .use_clustering = DISABLE_CLUSTERING, .proc_name = "oakscsi", .cmd_size = NCR5380_CMD_SIZE, + .max_sectors = 128, }; static int oakscsi_probe(struct expansion_card *ec, const struct ecard_id *id) Index: linux/drivers/scsi/dmx3191d.c =================================================================== --- linux.orig/drivers/scsi/dmx3191d.c 2016-01-03 16:04:20.000000000 +1100 +++ linux/drivers/scsi/dmx3191d.c 2016-01-03 16:04:38.000000000 +1100 @@ -62,6 +62,7 @@ static struct scsi_host_template dmx3191 .cmd_per_lun = 2, .use_clustering = DISABLE_CLUSTERING, .cmd_size = NCR5380_CMD_SIZE, + .max_sectors = 128, }; static int dmx3191d_probe_one(struct pci_dev *pdev, Index: linux/drivers/scsi/dtc.c =================================================================== --- linux.orig/drivers/scsi/dtc.c 2016-01-03 16:04:20.000000000 +1100 +++ linux/drivers/scsi/dtc.c 2016-01-03 16:04:38.000000000 +1100 @@ -453,5 +453,6 @@ static struct scsi_host_template driver_ .cmd_per_lun = 2, .use_clustering = DISABLE_CLUSTERING, .cmd_size = NCR5380_CMD_SIZE, + .max_sectors = 128, }; #include "scsi_module.c" Index: linux/drivers/scsi/g_NCR5380.c =================================================================== --- linux.orig/drivers/scsi/g_NCR5380.c 2016-01-03 16:04:20.000000000 +1100 +++ linux/drivers/scsi/g_NCR5380.c 2016-01-03 16:04:38.000000000 +1100 @@ -729,6 +729,7 @@ static struct scsi_host_template driver_ .cmd_per_lun = 2, .use_clustering = DISABLE_CLUSTERING, .cmd_size = NCR5380_CMD_SIZE, + .max_sectors = 128, }; #include "scsi_module.c" Index: linux/drivers/scsi/mac_scsi.c =================================================================== --- linux.orig/drivers/scsi/mac_scsi.c 2016-01-03 16:04:20.000000000 +1100 +++ linux/drivers/scsi/mac_scsi.c 2016-01-03 16:04:38.000000000 +1100 @@ -324,6 +324,7 @@ static struct scsi_host_template mac_scs .cmd_per_lun = 2, .use_clustering = DISABLE_CLUSTERING, .cmd_size = NCR5380_CMD_SIZE, + .max_sectors = 128, }; static int __init mac_scsi_probe(struct platform_device *pdev) Index: linux/drivers/scsi/pas16.c =================================================================== --- linux.orig/drivers/scsi/pas16.c 2016-01-03 16:04:20.000000000 +1100 +++ linux/drivers/scsi/pas16.c 2016-01-03 16:04:38.000000000 +1100 @@ -563,6 +563,7 @@ static struct scsi_host_template driver_ .cmd_per_lun = 2, .use_clustering = DISABLE_CLUSTERING, .cmd_size = NCR5380_CMD_SIZE, + .max_sectors = 128, }; #include "scsi_module.c" Index: linux/drivers/scsi/t128.c =================================================================== --- linux.orig/drivers/scsi/t128.c 2016-01-03 16:04:20.000000000 +1100 +++ linux/drivers/scsi/t128.c 2016-01-03 16:04:38.000000000 +1100 @@ -407,5 +407,6 @@ static struct scsi_host_template driver_ .cmd_per_lun = 2, .use_clustering = DISABLE_CLUSTERING, .cmd_size = NCR5380_CMD_SIZE, + .max_sectors = 128, }; #include "scsi_module.c"