aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390
diff options
context:
space:
mode:
authorSwen Schillig <swen@vnet.ibm.com>2009-08-18 09:43:14 -0400
committerJames Bottomley <James.Bottomley@suse.de>2009-09-05 09:49:18 -0400
commit058b8647892ed49ba6a0d2c0966a72e20e2e69ff (patch)
treeba8baad2244bbacc5974207fb2274fb6c355d385 /drivers/s390
parentbd63eaf4b8d783e6033930e377e516169abcadc4 (diff)
[SCSI] zfcp: Replace fsf_req wait_queue with completion
The combination wait_queue/wakeup in conjunction with the flag ZFCP_STATUS_FSFREQ_COMPLETED to signal the completion of an fsfreq was not race-safe and can be better solved by a completion. 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@suse.de>
Diffstat (limited to 'drivers/s390')
-rw-r--r--drivers/s390/scsi/zfcp_def.h3
-rw-r--r--drivers/s390/scsi/zfcp_erp.c3
-rw-r--r--drivers/s390/scsi/zfcp_fsf.c26
-rw-r--r--drivers/s390/scsi/zfcp_scsi.c6
4 files changed, 10 insertions, 28 deletions
diff --git a/drivers/s390/scsi/zfcp_def.h b/drivers/s390/scsi/zfcp_def.h
index c1becfc1e7f..944f67754ee 100644
--- a/drivers/s390/scsi/zfcp_def.h
+++ b/drivers/s390/scsi/zfcp_def.h
@@ -248,7 +248,6 @@ enum zfcp_wka_status {
248 248
249/* FSF request status (this does not have a common part) */ 249/* FSF request status (this does not have a common part) */
250#define ZFCP_STATUS_FSFREQ_TASK_MANAGEMENT 0x00000002 250#define ZFCP_STATUS_FSFREQ_TASK_MANAGEMENT 0x00000002
251#define ZFCP_STATUS_FSFREQ_COMPLETED 0x00000004
252#define ZFCP_STATUS_FSFREQ_ERROR 0x00000008 251#define ZFCP_STATUS_FSFREQ_ERROR 0x00000008
253#define ZFCP_STATUS_FSFREQ_CLEANUP 0x00000010 252#define ZFCP_STATUS_FSFREQ_CLEANUP 0x00000010
254#define ZFCP_STATUS_FSFREQ_ABORTSUCCEEDED 0x00000040 253#define ZFCP_STATUS_FSFREQ_ABORTSUCCEEDED 0x00000040
@@ -532,7 +531,7 @@ struct zfcp_fsf_req {
532 u8 sbale_curr; /* current SBALE during creation 531 u8 sbale_curr; /* current SBALE during creation
533 of request */ 532 of request */
534 u8 sbal_response; /* SBAL used in interrupt */ 533 u8 sbal_response; /* SBAL used in interrupt */
535 wait_queue_head_t completion_wq; /* can be used by a routine 534 struct completion completion; /* can be used by a routine
536 to wait for completion */ 535 to wait for completion */
537 u32 status; /* status of this request */ 536 u32 status; /* status of this request */
538 u32 fsf_command; /* FSF Command copy */ 537 u32 fsf_command; /* FSF Command copy */
diff --git a/drivers/s390/scsi/zfcp_erp.c b/drivers/s390/scsi/zfcp_erp.c
index 39e4dd15453..a377e2f9125 100644
--- a/drivers/s390/scsi/zfcp_erp.c
+++ b/drivers/s390/scsi/zfcp_erp.c
@@ -485,8 +485,7 @@ static void zfcp_erp_strategy_check_fsfreq(struct zfcp_erp_action *act)
485 } 485 }
486 if (act->status & ZFCP_STATUS_ERP_TIMEDOUT) 486 if (act->status & ZFCP_STATUS_ERP_TIMEDOUT)
487 zfcp_rec_dbf_event_action("erscf_2", act); 487 zfcp_rec_dbf_event_action("erscf_2", act);
488 if (act->fsf_req->status & (ZFCP_STATUS_FSFREQ_COMPLETED | 488 if (act->fsf_req->status & ZFCP_STATUS_FSFREQ_DISMISSED)
489 ZFCP_STATUS_FSFREQ_DISMISSED))
490 act->fsf_req = NULL; 489 act->fsf_req = NULL;
491 } else 490 } else
492 act->fsf_req = NULL; 491 act->fsf_req = NULL;
diff --git a/drivers/s390/scsi/zfcp_fsf.c b/drivers/s390/scsi/zfcp_fsf.c
index 7ca2995aaf6..ed06a1d17b7 100644
--- a/drivers/s390/scsi/zfcp_fsf.c
+++ b/drivers/s390/scsi/zfcp_fsf.c
@@ -444,23 +444,11 @@ static void zfcp_fsf_req_complete(struct zfcp_fsf_req *req)
444 444
445 if (req->erp_action) 445 if (req->erp_action)
446 zfcp_erp_notify(req->erp_action, 0); 446 zfcp_erp_notify(req->erp_action, 0);
447 req->status |= ZFCP_STATUS_FSFREQ_COMPLETED;
448 447
449 if (likely(req->status & ZFCP_STATUS_FSFREQ_CLEANUP)) 448 if (likely(req->status & ZFCP_STATUS_FSFREQ_CLEANUP))
450 zfcp_fsf_req_free(req); 449 zfcp_fsf_req_free(req);
451 else 450 else
452 /* notify initiator waiting for the requests completion */ 451 complete(&req->completion);
453 /*
454 * FIXME: Race! We must not access fsf_req here as it might have been
455 * cleaned up already due to the set ZFCP_STATUS_FSFREQ_COMPLETED
456 * flag. It's an improbable case. But, we have the same paranoia for
457 * the cleanup flag already.
458 * Might better be handled using complete()?
459 * (setting the flag and doing wakeup ought to be atomic
460 * with regard to checking the flag as long as waitqueue is
461 * part of the to be released structure)
462 */
463 wake_up(&req->completion_wq);
464} 452}
465 453
466/** 454/**
@@ -733,7 +721,7 @@ static struct zfcp_fsf_req *zfcp_fsf_req_create(struct zfcp_adapter *adapter,
733 721
734 INIT_LIST_HEAD(&req->list); 722 INIT_LIST_HEAD(&req->list);
735 init_timer(&req->timer); 723 init_timer(&req->timer);
736 init_waitqueue_head(&req->completion_wq); 724 init_completion(&req->completion);
737 725
738 req->adapter = adapter; 726 req->adapter = adapter;
739 req->fsf_command = fsf_cmd; 727 req->fsf_command = fsf_cmd;
@@ -1309,8 +1297,7 @@ int zfcp_fsf_exchange_config_data_sync(struct zfcp_adapter *adapter,
1309 retval = zfcp_fsf_req_send(req); 1297 retval = zfcp_fsf_req_send(req);
1310 spin_unlock_bh(&adapter->req_q_lock); 1298 spin_unlock_bh(&adapter->req_q_lock);
1311 if (!retval) 1299 if (!retval)
1312 wait_event(req->completion_wq, 1300 wait_for_completion(&req->completion);
1313 req->status & ZFCP_STATUS_FSFREQ_COMPLETED);
1314 1301
1315 zfcp_fsf_req_free(req); 1302 zfcp_fsf_req_free(req);
1316 return retval; 1303 return retval;
@@ -1405,8 +1392,8 @@ int zfcp_fsf_exchange_port_data_sync(struct zfcp_adapter *adapter,
1405 spin_unlock_bh(&adapter->req_q_lock); 1392 spin_unlock_bh(&adapter->req_q_lock);
1406 1393
1407 if (!retval) 1394 if (!retval)
1408 wait_event(req->completion_wq, 1395 wait_for_completion(&req->completion);
1409 req->status & ZFCP_STATUS_FSFREQ_COMPLETED); 1396
1410 zfcp_fsf_req_free(req); 1397 zfcp_fsf_req_free(req);
1411 1398
1412 return retval; 1399 return retval;
@@ -2572,8 +2559,7 @@ out:
2572 spin_unlock_bh(&adapter->req_q_lock); 2559 spin_unlock_bh(&adapter->req_q_lock);
2573 2560
2574 if (!retval) { 2561 if (!retval) {
2575 wait_event(req->completion_wq, 2562 wait_for_completion(&req->completion);
2576 req->status & ZFCP_STATUS_FSFREQ_COMPLETED);
2577 return req; 2563 return req;
2578 } 2564 }
2579 return ERR_PTR(retval); 2565 return ERR_PTR(retval);
diff --git a/drivers/s390/scsi/zfcp_scsi.c b/drivers/s390/scsi/zfcp_scsi.c
index 0bd80a90426..0de059161b3 100644
--- a/drivers/s390/scsi/zfcp_scsi.c
+++ b/drivers/s390/scsi/zfcp_scsi.c
@@ -206,8 +206,7 @@ static int zfcp_scsi_eh_abort_handler(struct scsi_cmnd *scpnt)
206 if (!abrt_req) 206 if (!abrt_req)
207 return FAILED; 207 return FAILED;
208 208
209 wait_event(abrt_req->completion_wq, 209 wait_for_completion(&abrt_req->completion);
210 abrt_req->status & ZFCP_STATUS_FSFREQ_COMPLETED);
211 210
212 if (abrt_req->status & ZFCP_STATUS_FSFREQ_ABORTSUCCEEDED) 211 if (abrt_req->status & ZFCP_STATUS_FSFREQ_ABORTSUCCEEDED)
213 dbf_tag = "okay"; 212 dbf_tag = "okay";
@@ -246,8 +245,7 @@ static int zfcp_task_mgmt_function(struct scsi_cmnd *scpnt, u8 tm_flags)
246 if (!fsf_req) 245 if (!fsf_req)
247 return FAILED; 246 return FAILED;
248 247
249 wait_event(fsf_req->completion_wq, 248 wait_for_completion(&fsf_req->completion);
250 fsf_req->status & ZFCP_STATUS_FSFREQ_COMPLETED);
251 249
252 if (fsf_req->status & ZFCP_STATUS_FSFREQ_TMFUNCFAILED) { 250 if (fsf_req->status & ZFCP_STATUS_FSFREQ_TMFUNCFAILED) {
253 zfcp_scsi_dbf_event_devreset("fail", tm_flags, unit, scpnt); 251 zfcp_scsi_dbf_event_devreset("fail", tm_flags, unit, scpnt);