From: Hans-Joachim Picht <hpicht@redhat.com> Date: Thu, 3 Apr 2008 15:39:22 +0200 Subject: [s390] zfcp: hold lock on port/unit handle for task cmd Message-id: 20080403133922.GH10542@redhat.com O-Subject: [RHEL5 U3 PATCH 6/7] s390 - zfcp: Hold queue lock when checking port/unit handle for task management cmd Bugzilla: 434959 RH-Acked-by: Pete Zaitcev <zaitcev@redhat.com> RH-Acked-by: Pete Zaitcev <zaitcev@redhat.com> RH-Acked-by: Pete Zaitcev <zaitcev@redhat.com> Description ============ We need to hold the queue-lock when checking whether we still have a valid unit/port handle for the task management command, i.e whether we can issue this request for this unit/port. If the error recovery is about to close this unit/port, then it competes for the queue-lock. If the close request issued by the error recovery wins, then it is guaranteed that this unit/port has been blocked for other requests. Bugzilla ========= BZ 434959 https://bugzilla.redhat.com/show_bug.cgi?id=434959 Upstream status of the patch: ============================= Patch included in linux-2.6 as git commit fdf234527a070f6fc89f3ec5ee4ae1b263e59939 Test status: ============ Kernel with patch was built and successfully tested Please ACK. With best regards, Hans diff --git a/drivers/s390/scsi/zfcp_fsf.c b/drivers/s390/scsi/zfcp_fsf.c index 9e160f4..09a405b 100644 --- a/drivers/s390/scsi/zfcp_fsf.c +++ b/drivers/s390/scsi/zfcp_fsf.c @@ -3682,6 +3682,10 @@ zfcp_fsf_send_fcp_command_task_management(struct zfcp_adapter *adapter, goto out; } + if (unlikely(!atomic_test_mask(ZFCP_STATUS_COMMON_UNBLOCKED, + &unit->status))) + goto unit_blocked; + /* * Used to decide on proper handler in the return path, * could be either zfcp_fsf_send_fcp_command_task_handler or @@ -3715,25 +3719,13 @@ zfcp_fsf_send_fcp_command_task_management(struct zfcp_adapter *adapter, zfcp_fsf_start_timer(fsf_req, ZFCP_SCSI_ER_TIMEOUT); retval = zfcp_fsf_req_send(fsf_req); - if (retval) { - ZFCP_LOG_INFO("error: Could not send an FCP-command (task " - "management) on adapter %s, port 0x%016Lx for " - "unit LUN 0x%016Lx\n", - zfcp_get_busid_by_adapter(adapter), - unit->port->wwpn, - unit->fcp_lun); - zfcp_fsf_req_free(fsf_req); - fsf_req = NULL; + if (!retval) goto out; - } - ZFCP_LOG_TRACE("Send FCP Command (task management function) initiated " - "(adapter %s, port 0x%016Lx, unit 0x%016Lx, " - "tm_flags=0x%x)\n", - zfcp_get_busid_by_adapter(adapter), - unit->port->wwpn, - unit->fcp_lun, - tm_flags); + unit_blocked: + zfcp_fsf_req_free(fsf_req); + fsf_req = NULL; + out: write_unlock_irqrestore(&adapter->request_queue.queue_lock, lock_flags); return fsf_req;