[PATCH v2] nvmet: implement valid sqhd values in completions
James Smart
jsmart2021 at gmail.com
Mon Sep 18 09:00:32 PDT 2017
On 9/16/2017 3:04 AM, Max Gurtovoy wrote:
>> diff --git a/drivers/nvme/target/core.c b/drivers/nvme/target/core.c
>> index 7c23eaf8e563..764d46698b03 100644
>> --- a/drivers/nvme/target/core.c
>> +++ b/drivers/nvme/target/core.c
>> @@ -390,8 +390,8 @@ static void __nvmet_req_complete(struct nvmet_req
>> *req, u16 status)
>> if (status)
>> nvmet_set_status(req, status);
>> - /* XXX: need to fill in something useful for sq_head */
>> - req->rsp->sq_head = 0;
>> + req->sq->sqhd = (req->sq->sqhd + 1) % req->sq->size;
>> + req->rsp->sq_head = cpu_to_le16(req->sq->sqhd);
>> if (likely(req->sq)) /* may happen during early failure */
>> req->rsp->sq_id = cpu_to_le16(req->sq->qid);
>> req->rsp->command_id = req->cmd->common.command_id;
>
> According to the "if (likely(req->sq)) /* may happen during early
> failure */" condition, we can get null deref here 2 lines above that...
I think the likely statement is erroneous. In order to get to this point
the transport has to call nvmet_req_init(), and the first thing it does
is assign the sq and there's never an unset. So any completion of the
routine, even if failure to nvmet_req_init() has sq set. There's also
several other cases in nvmet_req_init() where if the transport set it to
NULL an oops would occur.
I'll send a revised patch that also removes the "if (likely())" test.
-- james
More information about the Linux-nvme
mailing list