diff options
author | Jens Axboe <jens.axboe@oracle.com> | 2008-09-14 08:55:09 -0400 |
---|---|---|
committer | Jens Axboe <jens.axboe@oracle.com> | 2008-10-09 02:56:13 -0400 |
commit | 242f9dcb8ba6f68fcd217a119a7648a4f69290e9 (patch) | |
tree | 1bfe245ffbc50d204d76665cd8f90d85100f86a1 /drivers/scsi/scsi.c | |
parent | 608aeef17a91747d6303de4df5e2c2e6899a95e8 (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.c')
-rw-r--r-- | drivers/scsi/scsi.c | 92 |
1 files changed, 17 insertions, 75 deletions
diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c index ee6be596503d..dbeb86cafc0d 100644 --- a/drivers/scsi/scsi.c +++ b/drivers/scsi/scsi.c | |||
@@ -291,7 +291,6 @@ struct scsi_cmnd *scsi_get_command(struct scsi_device *dev, gfp_t gfp_mask) | |||
291 | unsigned long flags; | 291 | unsigned long flags; |
292 | 292 | ||
293 | cmd->device = dev; | 293 | cmd->device = dev; |
294 | init_timer(&cmd->eh_timeout); | ||
295 | INIT_LIST_HEAD(&cmd->list); | 294 | INIT_LIST_HEAD(&cmd->list); |
296 | spin_lock_irqsave(&dev->list_lock, flags); | 295 | spin_lock_irqsave(&dev->list_lock, flags); |
297 | list_add_tail(&cmd->list, &dev->cmd_list); | 296 | list_add_tail(&cmd->list, &dev->cmd_list); |
@@ -652,14 +651,19 @@ int scsi_dispatch_cmd(struct scsi_cmnd *cmd) | |||
652 | unsigned long timeout; | 651 | unsigned long timeout; |
653 | int rtn = 0; | 652 | int rtn = 0; |
654 | 653 | ||
654 | /* | ||
655 | * We will use a queued command if possible, otherwise we will | ||
656 | * emulate the queuing and calling of completion function ourselves. | ||
657 | */ | ||
658 | atomic_inc(&cmd->device->iorequest_cnt); | ||
659 | |||
655 | /* check if the device is still usable */ | 660 | /* check if the device is still usable */ |
656 | if (unlikely(cmd->device->sdev_state == SDEV_DEL)) { | 661 | if (unlikely(cmd->device->sdev_state == SDEV_DEL)) { |
657 | /* in SDEV_DEL we error all commands. DID_NO_CONNECT | 662 | /* in SDEV_DEL we error all commands. DID_NO_CONNECT |
658 | * returns an immediate error upwards, and signals | 663 | * returns an immediate error upwards, and signals |
659 | * that the device is no longer present */ | 664 | * that the device is no longer present */ |
660 | cmd->result = DID_NO_CONNECT << 16; | 665 | cmd->result = DID_NO_CONNECT << 16; |
661 | atomic_inc(&cmd->device->iorequest_cnt); | 666 | scsi_done(cmd); |
662 | __scsi_done(cmd); | ||
663 | /* return 0 (because the command has been processed) */ | 667 | /* return 0 (because the command has been processed) */ |
664 | goto out; | 668 | goto out; |
665 | } | 669 | } |
@@ -672,6 +676,7 @@ int scsi_dispatch_cmd(struct scsi_cmnd *cmd) | |||
672 | * future requests should not occur until the device | 676 | * future requests should not occur until the device |
673 | * transitions out of the suspend state. | 677 | * transitions out of the suspend state. |
674 | */ | 678 | */ |
679 | |||
675 | scsi_queue_insert(cmd, SCSI_MLQUEUE_DEVICE_BUSY); | 680 | scsi_queue_insert(cmd, SCSI_MLQUEUE_DEVICE_BUSY); |
676 | 681 | ||
677 | SCSI_LOG_MLQUEUE(3, printk("queuecommand : device blocked \n")); | 682 | SCSI_LOG_MLQUEUE(3, printk("queuecommand : device blocked \n")); |
@@ -714,21 +719,9 @@ int scsi_dispatch_cmd(struct scsi_cmnd *cmd) | |||
714 | host->resetting = 0; | 719 | host->resetting = 0; |
715 | } | 720 | } |
716 | 721 | ||
717 | /* | ||
718 | * AK: unlikely race here: for some reason the timer could | ||
719 | * expire before the serial number is set up below. | ||
720 | */ | ||
721 | scsi_add_timer(cmd, cmd->timeout_per_command, scsi_times_out); | ||
722 | |||
723 | scsi_log_send(cmd); | 722 | scsi_log_send(cmd); |
724 | 723 | ||
725 | /* | 724 | /* |
726 | * We will use a queued command if possible, otherwise we will | ||
727 | * emulate the queuing and calling of completion function ourselves. | ||
728 | */ | ||
729 | atomic_inc(&cmd->device->iorequest_cnt); | ||
730 | |||
731 | /* | ||
732 | * Before we queue this command, check if the command | 725 | * Before we queue this command, check if the command |
733 | * length exceeds what the host adapter can handle. | 726 | * length exceeds what the host adapter can handle. |
734 | */ | 727 | */ |
@@ -744,6 +737,12 @@ int scsi_dispatch_cmd(struct scsi_cmnd *cmd) | |||
744 | } | 737 | } |
745 | 738 | ||
746 | spin_lock_irqsave(host->host_lock, flags); | 739 | spin_lock_irqsave(host->host_lock, flags); |
740 | /* | ||
741 | * AK: unlikely race here: for some reason the timer could | ||
742 | * expire before the serial number is set up below. | ||
743 | * | ||
744 | * TODO: kill serial or move to blk layer | ||
745 | */ | ||
747 | scsi_cmd_get_serial(host, cmd); | 746 | scsi_cmd_get_serial(host, cmd); |
748 | 747 | ||
749 | if (unlikely(host->shost_state == SHOST_DEL)) { | 748 | if (unlikely(host->shost_state == SHOST_DEL)) { |
@@ -754,12 +753,8 @@ int scsi_dispatch_cmd(struct scsi_cmnd *cmd) | |||
754 | } | 753 | } |
755 | spin_unlock_irqrestore(host->host_lock, flags); | 754 | spin_unlock_irqrestore(host->host_lock, flags); |
756 | if (rtn) { | 755 | if (rtn) { |
757 | if (scsi_delete_timer(cmd)) { | 756 | scsi_queue_insert(cmd, (rtn == SCSI_MLQUEUE_DEVICE_BUSY) ? |
758 | atomic_inc(&cmd->device->iodone_cnt); | 757 | rtn : SCSI_MLQUEUE_HOST_BUSY); |
759 | scsi_queue_insert(cmd, | ||
760 | (rtn == SCSI_MLQUEUE_DEVICE_BUSY) ? | ||
761 | rtn : SCSI_MLQUEUE_HOST_BUSY); | ||
762 | } | ||
763 | SCSI_LOG_MLQUEUE(3, | 758 | SCSI_LOG_MLQUEUE(3, |
764 | printk("queuecommand : request rejected\n")); | 759 | printk("queuecommand : request rejected\n")); |
765 | } | 760 | } |
@@ -770,24 +765,6 @@ int scsi_dispatch_cmd(struct scsi_cmnd *cmd) | |||
770 | } | 765 | } |
771 | 766 | ||
772 | /** | 767 | /** |
773 | * scsi_req_abort_cmd -- Request command recovery for the specified command | ||
774 | * @cmd: pointer to the SCSI command of interest | ||
775 | * | ||
776 | * This function requests that SCSI Core start recovery for the | ||
777 | * command by deleting the timer and adding the command to the eh | ||
778 | * queue. It can be called by either LLDDs or SCSI Core. LLDDs who | ||
779 | * implement their own error recovery MAY ignore the timeout event if | ||
780 | * they generated scsi_req_abort_cmd. | ||
781 | */ | ||
782 | void scsi_req_abort_cmd(struct scsi_cmnd *cmd) | ||
783 | { | ||
784 | if (!scsi_delete_timer(cmd)) | ||
785 | return; | ||
786 | scsi_times_out(cmd); | ||
787 | } | ||
788 | EXPORT_SYMBOL(scsi_req_abort_cmd); | ||
789 | |||
790 | /** | ||
791 | * scsi_done - Enqueue the finished SCSI command into the done queue. | 768 | * scsi_done - Enqueue the finished SCSI command into the done queue. |
792 | * @cmd: The SCSI Command for which a low-level device driver (LLDD) gives | 769 | * @cmd: The SCSI Command for which a low-level device driver (LLDD) gives |
793 | * ownership back to SCSI Core -- i.e. the LLDD has finished with it. | 770 | * ownership back to SCSI Core -- i.e. the LLDD has finished with it. |
@@ -802,42 +779,7 @@ EXPORT_SYMBOL(scsi_req_abort_cmd); | |||
802 | */ | 779 | */ |
803 | static void scsi_done(struct scsi_cmnd *cmd) | 780 | static void scsi_done(struct scsi_cmnd *cmd) |
804 | { | 781 | { |
805 | /* | 782 | blk_complete_request(cmd->request); |
806 | * We don't have to worry about this one timing out anymore. | ||
807 | * If we are unable to remove the timer, then the command | ||
808 | * has already timed out. In which case, we have no choice but to | ||
809 | * let the timeout function run, as we have no idea where in fact | ||
810 | * that function could really be. It might be on another processor, | ||
811 | * etc, etc. | ||
812 | */ | ||
813 | if (!scsi_delete_timer(cmd)) | ||
814 | return; | ||
815 | __scsi_done(cmd); | ||
816 | } | ||
817 | |||
818 | /* Private entry to scsi_done() to complete a command when the timer | ||
819 | * isn't running --- used by scsi_times_out */ | ||
820 | void __scsi_done(struct scsi_cmnd *cmd) | ||
821 | { | ||
822 | struct request *rq = cmd->request; | ||
823 | |||
824 | /* | ||
825 | * Set the serial numbers back to zero | ||
826 | */ | ||
827 | cmd->serial_number = 0; | ||
828 | |||
829 | atomic_inc(&cmd->device->iodone_cnt); | ||
830 | if (cmd->result) | ||
831 | atomic_inc(&cmd->device->ioerr_cnt); | ||
832 | |||
833 | BUG_ON(!rq); | ||
834 | |||
835 | /* | ||
836 | * The uptodate/nbytes values don't matter, as we allow partial | ||
837 | * completes and thus will check this in the softirq callback | ||
838 | */ | ||
839 | rq->completion_data = cmd; | ||
840 | blk_complete_request(rq); | ||
841 | } | 783 | } |
842 | 784 | ||
843 | /* Move this to a header if it becomes more generally useful */ | 785 | /* Move this to a header if it becomes more generally useful */ |