diff options
Diffstat (limited to 'drivers/scsi/scsi.c')
-rw-r--r-- | drivers/scsi/scsi.c | 15 |
1 files changed, 15 insertions, 0 deletions
diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c index d1aa95d45a70..4befbc275f94 100644 --- a/drivers/scsi/scsi.c +++ b/drivers/scsi/scsi.c | |||
@@ -268,6 +268,7 @@ struct scsi_cmnd *scsi_get_command(struct scsi_device *dev, int gfp_mask) | |||
268 | } else | 268 | } else |
269 | put_device(&dev->sdev_gendev); | 269 | put_device(&dev->sdev_gendev); |
270 | 270 | ||
271 | cmd->jiffies_at_alloc = jiffies; | ||
271 | return cmd; | 272 | return cmd; |
272 | } | 273 | } |
273 | EXPORT_SYMBOL(scsi_get_command); | 274 | EXPORT_SYMBOL(scsi_get_command); |
@@ -798,9 +799,23 @@ static void scsi_softirq(struct softirq_action *h) | |||
798 | while (!list_empty(&local_q)) { | 799 | while (!list_empty(&local_q)) { |
799 | struct scsi_cmnd *cmd = list_entry(local_q.next, | 800 | struct scsi_cmnd *cmd = list_entry(local_q.next, |
800 | struct scsi_cmnd, eh_entry); | 801 | struct scsi_cmnd, eh_entry); |
802 | /* The longest time any command should be outstanding is the | ||
803 | * per command timeout multiplied by the number of retries. | ||
804 | * | ||
805 | * For a typical command, this is 2.5 minutes */ | ||
806 | unsigned long wait_for | ||
807 | = cmd->allowed * cmd->timeout_per_command; | ||
801 | list_del_init(&cmd->eh_entry); | 808 | list_del_init(&cmd->eh_entry); |
802 | 809 | ||
803 | disposition = scsi_decide_disposition(cmd); | 810 | disposition = scsi_decide_disposition(cmd); |
811 | if (disposition != SUCCESS && | ||
812 | time_before(cmd->jiffies_at_alloc + wait_for, jiffies)) { | ||
813 | dev_printk(KERN_ERR, &cmd->device->sdev_gendev, | ||
814 | "timing out command, waited %ds\n", | ||
815 | wait_for/HZ); | ||
816 | disposition = SUCCESS; | ||
817 | } | ||
818 | |||
804 | scsi_log_completion(cmd, disposition); | 819 | scsi_log_completion(cmd, disposition); |
805 | switch (disposition) { | 820 | switch (disposition) { |
806 | case SUCCESS: | 821 | case SUCCESS: |