diff options
author | Don Brace <don.brace@microsemi.com> | 2017-03-10 15:35:17 -0500 |
---|---|---|
committer | Martin K. Petersen <martin.petersen@oracle.com> | 2017-03-15 13:37:10 -0400 |
commit | 87b9e6aa87d9411f1059aa245c0c79976bc557ac (patch) | |
tree | 3f60cdf9d91ad830cf75f47e5980c3bb7f68dab9 | |
parent | 85b29008d8af6d94a0723aaa8d93cfb6e041158b (diff) |
scsi: hpsa: limit outstanding rescans
Avoid rescan storms. No need to queue another if one is pending.
Reviewed-by: Scott Benesh <scott.benesh@microsemi.com>
Reviewed-by: Scott Teel <scott.teel@microsemi.com>
Reviewed-by: Tomas Henzl <thenzl@redhat.com>
Signed-off-by: Don Brace <don.brace@microsemi.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
-rw-r--r-- | drivers/scsi/hpsa.c | 16 | ||||
-rw-r--r-- | drivers/scsi/hpsa.h | 1 |
2 files changed, 16 insertions, 1 deletions
diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c index 90b76c4c6d36..0a8ac68f4ca1 100644 --- a/drivers/scsi/hpsa.c +++ b/drivers/scsi/hpsa.c | |||
@@ -5555,7 +5555,7 @@ static void hpsa_scan_complete(struct ctlr_info *h) | |||
5555 | 5555 | ||
5556 | spin_lock_irqsave(&h->scan_lock, flags); | 5556 | spin_lock_irqsave(&h->scan_lock, flags); |
5557 | h->scan_finished = 1; | 5557 | h->scan_finished = 1; |
5558 | wake_up_all(&h->scan_wait_queue); | 5558 | wake_up(&h->scan_wait_queue); |
5559 | spin_unlock_irqrestore(&h->scan_lock, flags); | 5559 | spin_unlock_irqrestore(&h->scan_lock, flags); |
5560 | } | 5560 | } |
5561 | 5561 | ||
@@ -5573,11 +5573,23 @@ static void hpsa_scan_start(struct Scsi_Host *sh) | |||
5573 | if (unlikely(lockup_detected(h))) | 5573 | if (unlikely(lockup_detected(h))) |
5574 | return hpsa_scan_complete(h); | 5574 | return hpsa_scan_complete(h); |
5575 | 5575 | ||
5576 | /* | ||
5577 | * If a scan is already waiting to run, no need to add another | ||
5578 | */ | ||
5579 | spin_lock_irqsave(&h->scan_lock, flags); | ||
5580 | if (h->scan_waiting) { | ||
5581 | spin_unlock_irqrestore(&h->scan_lock, flags); | ||
5582 | return; | ||
5583 | } | ||
5584 | |||
5585 | spin_unlock_irqrestore(&h->scan_lock, flags); | ||
5586 | |||
5576 | /* wait until any scan already in progress is finished. */ | 5587 | /* wait until any scan already in progress is finished. */ |
5577 | while (1) { | 5588 | while (1) { |
5578 | spin_lock_irqsave(&h->scan_lock, flags); | 5589 | spin_lock_irqsave(&h->scan_lock, flags); |
5579 | if (h->scan_finished) | 5590 | if (h->scan_finished) |
5580 | break; | 5591 | break; |
5592 | h->scan_waiting = 1; | ||
5581 | spin_unlock_irqrestore(&h->scan_lock, flags); | 5593 | spin_unlock_irqrestore(&h->scan_lock, flags); |
5582 | wait_event(h->scan_wait_queue, h->scan_finished); | 5594 | wait_event(h->scan_wait_queue, h->scan_finished); |
5583 | /* Note: We don't need to worry about a race between this | 5595 | /* Note: We don't need to worry about a race between this |
@@ -5587,6 +5599,7 @@ static void hpsa_scan_start(struct Scsi_Host *sh) | |||
5587 | */ | 5599 | */ |
5588 | } | 5600 | } |
5589 | h->scan_finished = 0; /* mark scan as in progress */ | 5601 | h->scan_finished = 0; /* mark scan as in progress */ |
5602 | h->scan_waiting = 0; | ||
5590 | spin_unlock_irqrestore(&h->scan_lock, flags); | 5603 | spin_unlock_irqrestore(&h->scan_lock, flags); |
5591 | 5604 | ||
5592 | if (unlikely(lockup_detected(h))) | 5605 | if (unlikely(lockup_detected(h))) |
@@ -8789,6 +8802,7 @@ reinit_after_soft_reset: | |||
8789 | init_waitqueue_head(&h->event_sync_wait_queue); | 8802 | init_waitqueue_head(&h->event_sync_wait_queue); |
8790 | mutex_init(&h->reset_mutex); | 8803 | mutex_init(&h->reset_mutex); |
8791 | h->scan_finished = 1; /* no scan currently in progress */ | 8804 | h->scan_finished = 1; /* no scan currently in progress */ |
8805 | h->scan_waiting = 0; | ||
8792 | 8806 | ||
8793 | pci_set_drvdata(pdev, h); | 8807 | pci_set_drvdata(pdev, h); |
8794 | h->ndevices = 0; | 8808 | h->ndevices = 0; |
diff --git a/drivers/scsi/hpsa.h b/drivers/scsi/hpsa.h index bf6cdc106654..6f04f2ad4125 100644 --- a/drivers/scsi/hpsa.h +++ b/drivers/scsi/hpsa.h | |||
@@ -201,6 +201,7 @@ struct ctlr_info { | |||
201 | dma_addr_t errinfo_pool_dhandle; | 201 | dma_addr_t errinfo_pool_dhandle; |
202 | unsigned long *cmd_pool_bits; | 202 | unsigned long *cmd_pool_bits; |
203 | int scan_finished; | 203 | int scan_finished; |
204 | u8 scan_waiting : 1; | ||
204 | spinlock_t scan_lock; | 205 | spinlock_t scan_lock; |
205 | wait_queue_head_t scan_wait_queue; | 206 | wait_queue_head_t scan_wait_queue; |
206 | 207 | ||