aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/scsi_lib.c
diff options
context:
space:
mode:
authorJens Axboe <jens.axboe@oracle.com>2008-09-14 08:55:09 -0400
committerJens Axboe <jens.axboe@oracle.com>2008-10-09 02:56:13 -0400
commit242f9dcb8ba6f68fcd217a119a7648a4f69290e9 (patch)
tree1bfe245ffbc50d204d76665cd8f90d85100f86a1 /drivers/scsi/scsi_lib.c
parent608aeef17a91747d6303de4df5e2c2e6899a95e8 (diff)
block: unify request timeout handling
Right now SCSI and others do their own command timeout handling. Move those bits to the block layer. Instead of having a timer per command, we try to be a bit more clever and simply have one per-queue. This avoids the overhead of having to tear down and setup a timer for each command, so it will result in a lot less timer fiddling. Signed-off-by: Mike Anderson <andmike@linux.vnet.ibm.com> Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
Diffstat (limited to 'drivers/scsi/scsi_lib.c')
-rw-r--r--drivers/scsi/scsi_lib.c17
1 files changed, 13 insertions, 4 deletions
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
index 62307bd794a9..e7686500e9dd 100644
--- a/drivers/scsi/scsi_lib.c
+++ b/drivers/scsi/scsi_lib.c
@@ -1181,7 +1181,6 @@ int scsi_setup_blk_pc_cmnd(struct scsi_device *sdev, struct request *req)
1181 1181
1182 cmd->transfersize = req->data_len; 1182 cmd->transfersize = req->data_len;
1183 cmd->allowed = req->retries; 1183 cmd->allowed = req->retries;
1184 cmd->timeout_per_command = req->timeout;
1185 return BLKPREP_OK; 1184 return BLKPREP_OK;
1186} 1185}
1187EXPORT_SYMBOL(scsi_setup_blk_pc_cmnd); 1186EXPORT_SYMBOL(scsi_setup_blk_pc_cmnd);
@@ -1416,17 +1415,26 @@ static void scsi_kill_request(struct request *req, struct request_queue *q)
1416 spin_unlock(shost->host_lock); 1415 spin_unlock(shost->host_lock);
1417 spin_lock(sdev->request_queue->queue_lock); 1416 spin_lock(sdev->request_queue->queue_lock);
1418 1417
1419 __scsi_done(cmd); 1418 blk_complete_request(req);
1420} 1419}
1421 1420
1422static void scsi_softirq_done(struct request *rq) 1421static void scsi_softirq_done(struct request *rq)
1423{ 1422{
1424 struct scsi_cmnd *cmd = rq->completion_data; 1423 struct scsi_cmnd *cmd = rq->special;
1425 unsigned long wait_for = (cmd->allowed + 1) * cmd->timeout_per_command; 1424 unsigned long wait_for = (cmd->allowed + 1) * rq->timeout;
1426 int disposition; 1425 int disposition;
1427 1426
1428 INIT_LIST_HEAD(&cmd->eh_entry); 1427 INIT_LIST_HEAD(&cmd->eh_entry);
1429 1428
1429 /*
1430 * Set the serial numbers back to zero
1431 */
1432 cmd->serial_number = 0;
1433
1434 atomic_inc(&cmd->device->iodone_cnt);
1435 if (cmd->result)
1436 atomic_inc(&cmd->device->ioerr_cnt);
1437
1430 disposition = scsi_decide_disposition(cmd); 1438 disposition = scsi_decide_disposition(cmd);
1431 if (disposition != SUCCESS && 1439 if (disposition != SUCCESS &&
1432 time_before(cmd->jiffies_at_alloc + wait_for, jiffies)) { 1440 time_before(cmd->jiffies_at_alloc + wait_for, jiffies)) {
@@ -1675,6 +1683,7 @@ struct request_queue *scsi_alloc_queue(struct scsi_device *sdev)
1675 1683
1676 blk_queue_prep_rq(q, scsi_prep_fn); 1684 blk_queue_prep_rq(q, scsi_prep_fn);
1677 blk_queue_softirq_done(q, scsi_softirq_done); 1685 blk_queue_softirq_done(q, scsi_softirq_done);
1686 blk_queue_rq_timed_out(q, scsi_times_out);
1678 return q; 1687 return q;
1679} 1688}
1680 1689