aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorFinn Thain <fthain@telegraphics.com.au>2016-01-03 00:06:07 -0500
committerMartin K. Petersen <martin.petersen@oracle.com>2016-01-06 21:43:09 -0500
commit0a4e36125451165847c6d4e7d5633d92e53f5c69 (patch)
tree9512674edc9e8fbdd229e8d585d0228184fab8ac /drivers
parentcd46140a9a2f8fe0208262dc5f4d1fba15c93063 (diff)
ncr5380: Fix soft lockups
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 <fthain@telegraphics.com.au> Reviewed-by: Hannes Reinecke <hare@suse.com> Tested-by: Ondrej Zary <linux@rainbow-software.org> Tested-by: Michael Schmitz <schmitzmic@gmail.com> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/scsi/NCR5380.c6
-rw-r--r--drivers/scsi/arm/cumana_1.c1
-rw-r--r--drivers/scsi/arm/oak.c1
-rw-r--r--drivers/scsi/atari_NCR5380.c6
-rw-r--r--drivers/scsi/dmx3191d.c1
-rw-r--r--drivers/scsi/dtc.c1
-rw-r--r--drivers/scsi/g_NCR5380.c1
-rw-r--r--drivers/scsi/mac_scsi.c1
-rw-r--r--drivers/scsi/pas16.c1
-rw-r--r--drivers/scsi/t128.c1
10 files changed, 16 insertions, 4 deletions
diff --git a/drivers/scsi/NCR5380.c b/drivers/scsi/NCR5380.c
index 9616f397e134..38b03af36a6a 100644
--- a/drivers/scsi/NCR5380.c
+++ b/drivers/scsi/NCR5380.c
@@ -890,10 +890,10 @@ static void NCR5380_main(struct work_struct *work)
890 struct scsi_cmnd *cmd; 890 struct scsi_cmnd *cmd;
891 int done; 891 int done;
892 892
893 spin_lock_irq(&hostdata->lock);
894 do { 893 do {
895 done = 1; 894 done = 1;
896 895
896 spin_lock_irq(&hostdata->lock);
897 while (!hostdata->connected && 897 while (!hostdata->connected &&
898 (cmd = dequeue_next_cmd(instance))) { 898 (cmd = dequeue_next_cmd(instance))) {
899 899
@@ -930,8 +930,10 @@ static void NCR5380_main(struct work_struct *work)
930 NCR5380_information_transfer(instance); 930 NCR5380_information_transfer(instance);
931 done = 0; 931 done = 0;
932 } 932 }
933 spin_unlock_irq(&hostdata->lock);
934 if (!done)
935 cond_resched();
933 } while (!done); 936 } while (!done);
934 spin_unlock_irq(&hostdata->lock);
935} 937}
936 938
937#ifndef DONT_USE_INTR 939#ifndef DONT_USE_INTR
diff --git a/drivers/scsi/arm/cumana_1.c b/drivers/scsi/arm/cumana_1.c
index b526ba579ba3..221f18c5df93 100644
--- a/drivers/scsi/arm/cumana_1.c
+++ b/drivers/scsi/arm/cumana_1.c
@@ -209,6 +209,7 @@ static struct scsi_host_template cumanascsi_template = {
209 .use_clustering = DISABLE_CLUSTERING, 209 .use_clustering = DISABLE_CLUSTERING,
210 .proc_name = "CumanaSCSI-1", 210 .proc_name = "CumanaSCSI-1",
211 .cmd_size = NCR5380_CMD_SIZE, 211 .cmd_size = NCR5380_CMD_SIZE,
212 .max_sectors = 128,
212}; 213};
213 214
214static int cumanascsi1_probe(struct expansion_card *ec, 215static int cumanascsi1_probe(struct expansion_card *ec,
diff --git a/drivers/scsi/arm/oak.c b/drivers/scsi/arm/oak.c
index 70e648513275..1fab1d1896b1 100644
--- a/drivers/scsi/arm/oak.c
+++ b/drivers/scsi/arm/oak.c
@@ -115,6 +115,7 @@ static struct scsi_host_template oakscsi_template = {
115 .use_clustering = DISABLE_CLUSTERING, 115 .use_clustering = DISABLE_CLUSTERING,
116 .proc_name = "oakscsi", 116 .proc_name = "oakscsi",
117 .cmd_size = NCR5380_CMD_SIZE, 117 .cmd_size = NCR5380_CMD_SIZE,
118 .max_sectors = 128,
118}; 119};
119 120
120static int oakscsi_probe(struct expansion_card *ec, const struct ecard_id *id) 121static int oakscsi_probe(struct expansion_card *ec, const struct ecard_id *id)
diff --git a/drivers/scsi/atari_NCR5380.c b/drivers/scsi/atari_NCR5380.c
index b36fadab422b..a01921dfed0b 100644
--- a/drivers/scsi/atari_NCR5380.c
+++ b/drivers/scsi/atari_NCR5380.c
@@ -976,10 +976,10 @@ static void NCR5380_main(struct work_struct *work)
976 * alter queues and touch the Falcon lock. 976 * alter queues and touch the Falcon lock.
977 */ 977 */
978 978
979 spin_lock_irq(&hostdata->lock);
980 do { 979 do {
981 done = 1; 980 done = 1;
982 981
982 spin_lock_irq(&hostdata->lock);
983 while (!hostdata->connected && 983 while (!hostdata->connected &&
984 (cmd = dequeue_next_cmd(instance))) { 984 (cmd = dequeue_next_cmd(instance))) {
985 985
@@ -1026,8 +1026,10 @@ static void NCR5380_main(struct work_struct *work)
1026 NCR5380_information_transfer(instance); 1026 NCR5380_information_transfer(instance);
1027 done = 0; 1027 done = 0;
1028 } 1028 }
1029 spin_unlock_irq(&hostdata->lock);
1030 if (!done)
1031 cond_resched();
1029 } while (!done); 1032 } while (!done);
1030 spin_unlock_irq(&hostdata->lock);
1031} 1033}
1032 1034
1033 1035
diff --git a/drivers/scsi/dmx3191d.c b/drivers/scsi/dmx3191d.c
index ddb4e616bfed..6c14e68b9e1a 100644
--- a/drivers/scsi/dmx3191d.c
+++ b/drivers/scsi/dmx3191d.c
@@ -62,6 +62,7 @@ static struct scsi_host_template dmx3191d_driver_template = {
62 .cmd_per_lun = 2, 62 .cmd_per_lun = 2,
63 .use_clustering = DISABLE_CLUSTERING, 63 .use_clustering = DISABLE_CLUSTERING,
64 .cmd_size = NCR5380_CMD_SIZE, 64 .cmd_size = NCR5380_CMD_SIZE,
65 .max_sectors = 128,
65}; 66};
66 67
67static int dmx3191d_probe_one(struct pci_dev *pdev, 68static int dmx3191d_probe_one(struct pci_dev *pdev,
diff --git a/drivers/scsi/dtc.c b/drivers/scsi/dtc.c
index f6166e34e3b0..6c736b071cf4 100644
--- a/drivers/scsi/dtc.c
+++ b/drivers/scsi/dtc.c
@@ -453,5 +453,6 @@ static struct scsi_host_template driver_template = {
453 .cmd_per_lun = 2, 453 .cmd_per_lun = 2,
454 .use_clustering = DISABLE_CLUSTERING, 454 .use_clustering = DISABLE_CLUSTERING,
455 .cmd_size = NCR5380_CMD_SIZE, 455 .cmd_size = NCR5380_CMD_SIZE,
456 .max_sectors = 128,
456}; 457};
457#include "scsi_module.c" 458#include "scsi_module.c"
diff --git a/drivers/scsi/g_NCR5380.c b/drivers/scsi/g_NCR5380.c
index 30472064170e..cd79ef402d7a 100644
--- a/drivers/scsi/g_NCR5380.c
+++ b/drivers/scsi/g_NCR5380.c
@@ -729,6 +729,7 @@ static struct scsi_host_template driver_template = {
729 .cmd_per_lun = 2, 729 .cmd_per_lun = 2,
730 .use_clustering = DISABLE_CLUSTERING, 730 .use_clustering = DISABLE_CLUSTERING,
731 .cmd_size = NCR5380_CMD_SIZE, 731 .cmd_size = NCR5380_CMD_SIZE,
732 .max_sectors = 128,
732}; 733};
733 734
734#include "scsi_module.c" 735#include "scsi_module.c"
diff --git a/drivers/scsi/mac_scsi.c b/drivers/scsi/mac_scsi.c
index 18f74b4a0b95..bb2381314a2b 100644
--- a/drivers/scsi/mac_scsi.c
+++ b/drivers/scsi/mac_scsi.c
@@ -324,6 +324,7 @@ static struct scsi_host_template mac_scsi_template = {
324 .cmd_per_lun = 2, 324 .cmd_per_lun = 2,
325 .use_clustering = DISABLE_CLUSTERING, 325 .use_clustering = DISABLE_CLUSTERING,
326 .cmd_size = NCR5380_CMD_SIZE, 326 .cmd_size = NCR5380_CMD_SIZE,
327 .max_sectors = 128,
327}; 328};
328 329
329static int __init mac_scsi_probe(struct platform_device *pdev) 330static int __init mac_scsi_probe(struct platform_device *pdev)
diff --git a/drivers/scsi/pas16.c b/drivers/scsi/pas16.c
index 77789405f4a9..512037e27783 100644
--- a/drivers/scsi/pas16.c
+++ b/drivers/scsi/pas16.c
@@ -563,6 +563,7 @@ static struct scsi_host_template driver_template = {
563 .cmd_per_lun = 2, 563 .cmd_per_lun = 2,
564 .use_clustering = DISABLE_CLUSTERING, 564 .use_clustering = DISABLE_CLUSTERING,
565 .cmd_size = NCR5380_CMD_SIZE, 565 .cmd_size = NCR5380_CMD_SIZE,
566 .max_sectors = 128,
566}; 567};
567#include "scsi_module.c" 568#include "scsi_module.c"
568 569
diff --git a/drivers/scsi/t128.c b/drivers/scsi/t128.c
index e50881ab9eb4..4615fda60dbd 100644
--- a/drivers/scsi/t128.c
+++ b/drivers/scsi/t128.c
@@ -407,5 +407,6 @@ static struct scsi_host_template driver_template = {
407 .cmd_per_lun = 2, 407 .cmd_per_lun = 2,
408 .use_clustering = DISABLE_CLUSTERING, 408 .use_clustering = DISABLE_CLUSTERING,
409 .cmd_size = NCR5380_CMD_SIZE, 409 .cmd_size = NCR5380_CMD_SIZE,
410 .max_sectors = 128,
410}; 411};
411#include "scsi_module.c" 412#include "scsi_module.c"