summaryrefslogtreecommitdiffstats
path: root/drivers/scsi/ibmvscsi
diff options
context:
space:
mode:
authorBrian King <brking@linux.vnet.ibm.com>2010-06-17 20:56:03 +0200
committerJames Bottomley <James.Bottomley@suse.de>2010-07-27 19:03:47 +0200
commitf3a9c4d76a955e331e88992cd3b1e1498c231d52 (patch)
tree36b62ed69d733199b2a9aa5e864a58ada7a37aff /drivers/scsi/ibmvscsi
parent[SCSI] ibmvscsi: Fix error path deadlock (diff)
downloadlinux-f3a9c4d76a955e331e88992cd3b1e1498c231d52.tar.xz
linux-f3a9c4d76a955e331e88992cd3b1e1498c231d52.zip
[SCSI] ibmvscsi: Fix possible request_limit issue
If we encounter an error when sending a management datagram (i.e. non SCSI command, such as virtual adapter initialization command), we end up incrementing the request_limit, even though we don't decrement it for these commands. Fix this up by doing this increment in the error path for SRP commands only. Signed-off-by: Brian King <brking@linux.vnet.ibm.com> Signed-off-by: James Bottomley <James.Bottomley@suse.de>
Diffstat (limited to 'drivers/scsi/ibmvscsi')
-rw-r--r--drivers/scsi/ibmvscsi/ibmvscsi.c7
1 files changed, 5 insertions, 2 deletions
diff --git a/drivers/scsi/ibmvscsi/ibmvscsi.c b/drivers/scsi/ibmvscsi/ibmvscsi.c
index 83b5a174164c..4f906efb1519 100644
--- a/drivers/scsi/ibmvscsi/ibmvscsi.c
+++ b/drivers/scsi/ibmvscsi/ibmvscsi.c
@@ -548,6 +548,7 @@ static int ibmvscsi_send_srp_event(struct srp_event_struct *evt_struct,
u64 *crq_as_u64 = (u64 *) &evt_struct->crq;
int request_status = 0;
int rc;
+ int srp_req = 0;
/* If we have exhausted our request limit, just fail this request,
* unless it is for a reset or abort.
@@ -556,6 +557,7 @@ static int ibmvscsi_send_srp_event(struct srp_event_struct *evt_struct,
* can handle more requests (can_queue) when we actually can't
*/
if (evt_struct->crq.format == VIOSRP_SRP_FORMAT) {
+ srp_req = 1;
request_status =
atomic_dec_if_positive(&hostdata->request_limit);
/* If request limit was -1 when we started, it is now even
@@ -630,7 +632,8 @@ static int ibmvscsi_send_srp_event(struct srp_event_struct *evt_struct,
goto send_busy;
}
dev_err(hostdata->dev, "send error %d\n", rc);
- atomic_inc(&hostdata->request_limit);
+ if (srp_req)
+ atomic_inc(&hostdata->request_limit);
goto send_error;
}
@@ -640,7 +643,7 @@ static int ibmvscsi_send_srp_event(struct srp_event_struct *evt_struct,
unmap_cmd_data(&evt_struct->iu.srp.cmd, evt_struct, hostdata->dev);
free_event_struct(&hostdata->pool, evt_struct);
- if (request_status != -1)
+ if (srp_req && request_status != -1)
atomic_inc(&hostdata->request_limit);
return SCSI_MLQUEUE_HOST_BUSY;