diff options
author | Swen Schillig <swen@vnet.ibm.com> | 2009-08-18 09:43:14 -0400 |
---|---|---|
committer | James Bottomley <James.Bottomley@suse.de> | 2009-09-05 09:49:18 -0400 |
commit | 058b8647892ed49ba6a0d2c0966a72e20e2e69ff (patch) | |
tree | ba8baad2244bbacc5974207fb2274fb6c355d385 /drivers/s390/scsi/zfcp_fsf.c | |
parent | bd63eaf4b8d783e6033930e377e516169abcadc4 (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/scsi/zfcp_fsf.c')
-rw-r--r-- | drivers/s390/scsi/zfcp_fsf.c | 26 |
1 files changed, 6 insertions, 20 deletions
diff --git a/drivers/s390/scsi/zfcp_fsf.c b/drivers/s390/scsi/zfcp_fsf.c index 7ca2995aaf68..ed06a1d17b73 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); |