From 5f389360559bcb99f1efd4fef772d3755c97d24f Mon Sep 17 00:00:00 2001 From: "Stephen M. Cameron" Date: Tue, 18 Feb 2014 13:55:48 -0600 Subject: [PATCH] [SCSI] hpsa: do not rescan controllers known to be locked up * Do not check event bits on locked up controllers to see if they need to be rescanned. * Do not initiate any device rescans on controllers which are known to be locked up. Signed-off-by: Stephen M. Cameron Signed-off-by: James Bottomley --- drivers/scsi/hpsa.c | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c index ee17556058c2..67e059cd9e57 100644 --- a/drivers/scsi/hpsa.c +++ b/drivers/scsi/hpsa.c @@ -2868,11 +2868,38 @@ static int hpsa_scsi_queue_command_lck(struct scsi_cmnd *cmd, static DEF_SCSI_QCMD(hpsa_scsi_queue_command) +static int do_not_scan_if_controller_locked_up(struct ctlr_info *h) +{ + unsigned long flags; + + /* + * Don't let rescans be initiated on a controller known + * to be locked up. If the controller locks up *during* + * a rescan, that thread is probably hosed, but at least + * we can prevent new rescan threads from piling up on a + * locked up controller. + */ + spin_lock_irqsave(&h->lock, flags); + if (unlikely(h->lockup_detected)) { + spin_unlock_irqrestore(&h->lock, flags); + spin_lock_irqsave(&h->scan_lock, flags); + h->scan_finished = 1; + wake_up_all(&h->scan_wait_queue); + spin_unlock_irqrestore(&h->scan_lock, flags); + return 1; + } + spin_unlock_irqrestore(&h->lock, flags); + return 0; +} + static void hpsa_scan_start(struct Scsi_Host *sh) { struct ctlr_info *h = shost_to_hba(sh); unsigned long flags; + if (do_not_scan_if_controller_locked_up(h)) + return; + /* wait until any scan already in progress is finished. */ while (1) { spin_lock_irqsave(&h->scan_lock, flags); @@ -2889,6 +2916,9 @@ static void hpsa_scan_start(struct Scsi_Host *sh) h->scan_finished = 0; /* mark scan as in progress */ spin_unlock_irqrestore(&h->scan_lock, flags); + if (do_not_scan_if_controller_locked_up(h)) + return; + hpsa_update_scsi_devices(h, h->scsi_host->host_no); spin_lock_irqsave(&h->scan_lock, flags); -- 2.34.1