提交 6d4dcd4d 编写于 作者: D Darrick J. Wong 提交者: James Bottomley

[SCSI] libsas: Reset timer on taskless scsi_cmnds in sas_scsi_timed_out

Every so often, a scsi_cmnd will time out, and the libsas timeout handler
will discover that the scsi_cmnd does not have a sas_task attached to it.
This can happen in two cases: (1) the scsi_cmnd actually made it through
libsas to the HBA and is now going through scsi_done, or (2) the
scsi_cmnd has been held up (host lock, slab alloc, etc) and libsas has
not yet attached a sas_task.  In both cases, it is safe to ask SCSI for
more time to process the command via EH_RESET_TIMER; we cannot blindly
return EH_HANDLED because if (2) happens, we could end up calling
scsi_done while another CPU is heading towards sas_queuecommand, which
causes slab corruption when sas_task_done updates the freed scsi_cmnd.
Signed-off-by: NDarrick J. Wong <djwong@us.ibm.com>
Signed-off-by: NJames Bottomley <James.Bottomley@SteelEye.com>
上级 acbf167d
...@@ -524,9 +524,13 @@ enum scsi_eh_timer_return sas_scsi_timed_out(struct scsi_cmnd *cmd) ...@@ -524,9 +524,13 @@ enum scsi_eh_timer_return sas_scsi_timed_out(struct scsi_cmnd *cmd)
unsigned long flags; unsigned long flags;
if (!task) { if (!task) {
SAS_DPRINTK("command 0x%p, task 0x%p, gone: EH_HANDLED\n", cmd->timeout_per_command /= 2;
cmd, task); SAS_DPRINTK("command 0x%p, task 0x%p, gone: %s\n",
return EH_HANDLED; cmd, task, (cmd->timeout_per_command ?
"EH_RESET_TIMER" : "EH_NOT_HANDLED"));
if (!cmd->timeout_per_command)
return EH_NOT_HANDLED;
return EH_RESET_TIMER;
} }
spin_lock_irqsave(&task->task_state_lock, flags); spin_lock_irqsave(&task->task_state_lock, flags);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册