diff options
Diffstat (limited to 'drivers/scsi/scsi_error.c')
-rw-r--r-- | drivers/scsi/scsi_error.c | 22 |
1 files changed, 11 insertions, 11 deletions
diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c index dd338a8cd275..16eef068e9e9 100644 --- a/drivers/scsi/scsi_error.c +++ b/drivers/scsi/scsi_error.c | |||
@@ -297,19 +297,19 @@ enum blk_eh_timer_return scsi_times_out(struct request *req) | |||
297 | 297 | ||
298 | if (rtn == BLK_EH_DONE) { | 298 | if (rtn == BLK_EH_DONE) { |
299 | /* | 299 | /* |
300 | * For blk-mq, we must set the request state to complete now | 300 | * Set the command to complete first in order to prevent a real |
301 | * before sending the request to the scsi error handler. This | 301 | * completion from releasing the command while error handling |
302 | * will prevent a use-after-free in the event the LLD manages | 302 | * is using it. If the command was already completed, then the |
303 | * to complete the request before the error handler finishes | 303 | * lower level driver beat the timeout handler, and it is safe |
304 | * processing this timed out request. | 304 | * to return without escalating error recovery. |
305 | * | 305 | * |
306 | * If the request was already completed, then the LLD beat the | 306 | * If timeout handling lost the race to a real completion, the |
307 | * time out handler from transferring the request to the scsi | 307 | * block layer may ignore that due to a fake timeout injection, |
308 | * error handler. In that case we can return immediately as no | 308 | * so return RESET_TIMER to allow error handling another shot |
309 | * further action is required. | 309 | * at this command. |
310 | */ | 310 | */ |
311 | if (!blk_mq_mark_complete(req)) | 311 | if (test_and_set_bit(SCMD_STATE_COMPLETE, &scmd->state)) |
312 | return rtn; | 312 | return BLK_EH_RESET_TIMER; |
313 | if (scsi_abort_command(scmd) != SUCCESS) { | 313 | if (scsi_abort_command(scmd) != SUCCESS) { |
314 | set_host_byte(scmd, DID_TIME_OUT); | 314 | set_host_byte(scmd, DID_TIME_OUT); |
315 | scsi_eh_scmd_add(scmd); | 315 | scsi_eh_scmd_add(scmd); |