aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi
diff options
context:
space:
mode:
authorMike Christie <michaelc@cs.wisc.edu>2008-07-11 20:50:35 -0400
committerJames Bottomley <James.Bottomley@HansenPartnership.com>2008-07-26 15:14:50 -0400
commitecefe8a97577d6c1a68d14ab6fb19bce99448af2 (patch)
tree966860cc4ac9069b98f1b441f3d8b12675b9087a /drivers/scsi
parent5d90027fb579eee41ec1b61f23195ed2fdd51da2 (diff)
[SCSI] fix shared tag map tag allocation
When drivers use a shared tag map we can end up with more requests than tags, because the tag map is shost->can_queue tags and there can be sdevs * sdev->queue_depth requests. In scsi_request_fn if tag allocation fails we just drop down to just dequeueing the tag without a tag. The problem is that drivers using the shared tag map rely on a valid tag always being set, because it will use the tag number to lookup commands later. This patch has us check if we got a valid tag when the host lock is held right before we check if the host queue is ready. We do the check here because to allocate the tag we need the q lock, but if the tag is bad we want to add the device/q onto the starved list which requires the host lock. Signed-off-by: Mike Christie <michaelc@cs.wisc.edu> Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
Diffstat (limited to 'drivers/scsi')
-rw-r--r--drivers/scsi/scsi_lib.c15
1 files changed, 15 insertions, 0 deletions
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
index 88d1b5f44e5..fe77ccacf31 100644
--- a/drivers/scsi/scsi_lib.c
+++ b/drivers/scsi/scsi_lib.c
@@ -1497,6 +1497,21 @@ static void scsi_request_fn(struct request_queue *q)
1497 } 1497 }
1498 spin_lock(shost->host_lock); 1498 spin_lock(shost->host_lock);
1499 1499
1500 /*
1501 * We hit this when the driver is using a host wide
1502 * tag map. For device level tag maps the queue_depth check
1503 * in the device ready fn would prevent us from trying
1504 * to allocate a tag. Since the map is a shared host resource
1505 * we add the dev to the starved list so it eventually gets
1506 * a run when a tag is freed.
1507 */
1508 if (blk_queue_tagged(q) && (req->tag == -1)) {
1509 if (list_empty(&sdev->starved_entry))
1510 list_add_tail(&sdev->starved_entry,
1511 &shost->starved_list);
1512 goto not_ready;
1513 }
1514
1500 if (!scsi_host_queue_ready(q, shost, sdev)) 1515 if (!scsi_host_queue_ready(q, shost, sdev))
1501 goto not_ready; 1516 goto not_ready;
1502 if (scsi_target(sdev)->single_lun) { 1517 if (scsi_target(sdev)->single_lun) {