mirror of
https://github.com/torvalds/linux.git
synced 2024-11-23 12:42:02 +00:00
NVMe: fix race condition in nvme_submit_sync_cmd()
If we have a race between the schedule timing out and the command completing, we could have the task issuing the command exit nvme_submit_sync_cmd() while the irq is running sync_completion(). If that happens, we could be corrupting memory, since the stack that held 'cmdinfo' is no longer valid. Fix this by always calling nvme_abort_cmd_info(). Once that call completes, we know that we have either run sync_completion() if the completion came in, or that we will never run it since we now have special_completion() as the command callback handler. Acked-by: Keith Busch <keith.busch@intel.com> Signed-off-by: Jens Axboe <axboe@fb.com>
This commit is contained in:
parent
fe54303ee2
commit
849c6e7746
@ -804,12 +804,19 @@ static int nvme_submit_sync_cmd(struct request *req, struct nvme_command *cmd,
|
||||
nvme_finish_cmd(nvmeq, req->tag, NULL);
|
||||
set_current_state(TASK_RUNNING);
|
||||
}
|
||||
schedule_timeout(timeout);
|
||||
ret = schedule_timeout(timeout);
|
||||
|
||||
if (cmdinfo.status == -EINTR) {
|
||||
nvme_abort_cmd_info(nvmeq, blk_mq_rq_to_pdu(req));
|
||||
/*
|
||||
* Ensure that sync_completion has either run, or that it will
|
||||
* never run.
|
||||
*/
|
||||
nvme_abort_cmd_info(nvmeq, blk_mq_rq_to_pdu(req));
|
||||
|
||||
/*
|
||||
* We never got the completion
|
||||
*/
|
||||
if (cmdinfo.status == -EINTR)
|
||||
return -EINTR;
|
||||
}
|
||||
|
||||
if (result)
|
||||
*result = cmdinfo.result;
|
||||
|
Loading…
Reference in New Issue
Block a user