aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorSwen Schillig <swen@vnet.ibm.com>2009-04-17 09:08:06 -0400
committerJames Bottomley <James.Bottomley@HansenPartnership.com>2009-04-27 11:07:28 -0400
commit94ab4b38b2ab35a8ca955f4821c970a0ed7ec9ec (patch)
tree78b0d65b56e48a4753f39d277a13030f6d8b77d9 /drivers
parent828bc1212a685918bbdb5866504b63eea2c241f5 (diff)
[SCSI] zfcp: avoid false ERP complete due to sema race
The ERP thread is performing a task before it is executing the corresponding down on the semaphore. The response handler of the just started exchange config should wait for the completion by performing a down on this semaphore. Since this semaphore is still positive from the ERP enqueue the handler won't wait and therefore the exchange config will always fail leaving the adapter in error. The problem can be solved by performing the down on the semaphore before starting an ERP task. This is the logically correct order. Only walk the ERP loop if there is a task to perform. Signed-off-by: Swen Schillig <swen@vnet.ibm.com> Signed-off-by: Christof Schmitt <christof.schmitt@de.ibm.com> Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/s390/scsi/zfcp_erp.c9
1 files changed, 5 insertions, 4 deletions
diff --git a/drivers/s390/scsi/zfcp_erp.c b/drivers/s390/scsi/zfcp_erp.c
index b73e37027eb5..fdc9b4352a64 100644
--- a/drivers/s390/scsi/zfcp_erp.c
+++ b/drivers/s390/scsi/zfcp_erp.c
@@ -1311,6 +1311,11 @@ static int zfcp_erp_thread(void *data)
1311 1311
1312 while (!(atomic_read(&adapter->status) & 1312 while (!(atomic_read(&adapter->status) &
1313 ZFCP_STATUS_ADAPTER_ERP_THREAD_KILL)) { 1313 ZFCP_STATUS_ADAPTER_ERP_THREAD_KILL)) {
1314
1315 zfcp_rec_dbf_event_thread_lock("erthrd1", adapter);
1316 ignore = down_interruptible(&adapter->erp_ready_sem);
1317 zfcp_rec_dbf_event_thread_lock("erthrd2", adapter);
1318
1314 write_lock_irqsave(&adapter->erp_lock, flags); 1319 write_lock_irqsave(&adapter->erp_lock, flags);
1315 next = adapter->erp_ready_head.next; 1320 next = adapter->erp_ready_head.next;
1316 write_unlock_irqrestore(&adapter->erp_lock, flags); 1321 write_unlock_irqrestore(&adapter->erp_lock, flags);
@@ -1322,10 +1327,6 @@ static int zfcp_erp_thread(void *data)
1322 if (zfcp_erp_strategy(act) != ZFCP_ERP_DISMISSED) 1327 if (zfcp_erp_strategy(act) != ZFCP_ERP_DISMISSED)
1323 zfcp_erp_wakeup(adapter); 1328 zfcp_erp_wakeup(adapter);
1324 } 1329 }
1325
1326 zfcp_rec_dbf_event_thread_lock("erthrd1", adapter);
1327 ignore = down_interruptible(&adapter->erp_ready_sem);
1328 zfcp_rec_dbf_event_thread_lock("erthrd2", adapter);
1329 } 1330 }
1330 1331
1331 atomic_clear_mask(ZFCP_STATUS_ADAPTER_ERP_THREAD_UP, &adapter->status); 1332 atomic_clear_mask(ZFCP_STATUS_ADAPTER_ERP_THREAD_UP, &adapter->status);