diff options
author | Sagi Grimberg <sagi@grimberg.me> | 2017-02-27 19:28:25 +0300 |
---|---|---|
committer | Jens Axboe <axboe@fb.com> | 2017-04-04 18:48:23 +0300 |
commit | 3b068376306bf44de6fdc0f3bff6072d8cdc8481 (patch) | |
tree | 5a08b0b27cf018b171481ced8b1ad16ea44d1ee1 /drivers/nvme/target/loop.c | |
parent | d89a39be5fbf8d5bc441a8442df228fb050ad1c2 (diff) | |
download | linux-3b068376306bf44de6fdc0f3bff6072d8cdc8481.tar.xz |
nvme-loop: retrieve iod from the cqe command_id
useful to validate that the we didn't mess up
the command_id.
Signed-off-by: Sagi Grimberg <sagi@grimberg.me>
Signed-off-by: Jens Axboe <axboe@fb.com>
Diffstat (limited to 'drivers/nvme/target/loop.c')
-rw-r--r-- | drivers/nvme/target/loop.c | 31 |
1 files changed, 25 insertions, 6 deletions
diff --git a/drivers/nvme/target/loop.c b/drivers/nvme/target/loop.c index ac828af16c34..35314d96b4db 100644 --- a/drivers/nvme/target/loop.c +++ b/drivers/nvme/target/loop.c @@ -111,11 +111,20 @@ static void nvme_loop_complete_rq(struct request *req) blk_mq_end_request(req, error); } +static struct blk_mq_tags *nvme_loop_tagset(struct nvme_loop_queue *queue) +{ + u32 queue_idx = nvme_loop_queue_idx(queue); + + if (queue_idx == 0) + return queue->ctrl->admin_tag_set.tags[queue_idx]; + return queue->ctrl->tag_set.tags[queue_idx - 1]; +} + static void nvme_loop_queue_response(struct nvmet_req *req) { - struct nvme_loop_iod *iod = - container_of(req, struct nvme_loop_iod, req); - struct nvme_completion *cqe = &iod->rsp; + struct nvme_loop_queue *queue = + container_of(req->sq, struct nvme_loop_queue, nvme_sq); + struct nvme_completion *cqe = req->rsp; /* * AEN requests are special as they don't time out and can @@ -123,13 +132,23 @@ static void nvme_loop_queue_response(struct nvmet_req *req) * aborts. We don't even bother to allocate a struct request * for them but rather special case them here. */ - if (unlikely(nvme_loop_queue_idx(iod->queue) == 0 && + if (unlikely(nvme_loop_queue_idx(queue) == 0 && cqe->command_id >= NVME_LOOP_AQ_BLKMQ_DEPTH)) { - nvme_complete_async_event(&iod->queue->ctrl->ctrl, cqe->status, + nvme_complete_async_event(&queue->ctrl->ctrl, cqe->status, &cqe->result); } else { - struct request *rq = blk_mq_rq_from_pdu(iod); + struct request *rq; + struct nvme_loop_iod *iod; + + rq = blk_mq_tag_to_rq(nvme_loop_tagset(queue), cqe->command_id); + if (!rq) { + dev_err(queue->ctrl->ctrl.device, + "tag 0x%x on queue %d not found\n", + cqe->command_id, nvme_loop_queue_idx(queue)); + return; + } + iod = blk_mq_rq_to_pdu(rq); iod->nvme_req.result = cqe->result; blk_mq_complete_request(rq, le16_to_cpu(cqe->status) >> 1); } |