Skip to content

Commit 50b7c24

Browse files
Xianting TianChristoph Hellwig
authored andcommitted
nvme-pci: fix NULL req in completion handler
Currently, we use nvmeq->q_depth as the upper limit for a valid tag in nvme_handle_cqe(), it is not correct. Because the available tag number is recorded in tagset, which is not equal to nvmeq->q_depth. The nvme driver registers interrupts for queues before initializing the tagset, because it uses the number of successful request_irq() calls to configure the tagset parameters. This allows a race condition with the current tag validity check if the controller happens to produce an interrupt with a corrupted CQE before the tagset is initialized. Replace the driver's indirect tag check with the one already provided by the block layer. Signed-off-by: Xianting Tian <[email protected]> Reviewed-by: Keith Busch <[email protected]> Signed-off-by: Christoph Hellwig <[email protected]>
1 parent 59e330f commit 50b7c24

File tree

1 file changed

+7
-7
lines changed

1 file changed

+7
-7
lines changed

drivers/nvme/host/pci.c

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -940,13 +940,6 @@ static inline void nvme_handle_cqe(struct nvme_queue *nvmeq, u16 idx)
940940
struct nvme_completion *cqe = &nvmeq->cqes[idx];
941941
struct request *req;
942942

943-
if (unlikely(cqe->command_id >= nvmeq->q_depth)) {
944-
dev_warn(nvmeq->dev->ctrl.device,
945-
"invalid id %d completed on queue %d\n",
946-
cqe->command_id, le16_to_cpu(cqe->sq_id));
947-
return;
948-
}
949-
950943
/*
951944
* AEN requests are special as they don't time out and can
952945
* survive any kind of queue freeze and often don't respond to
@@ -960,6 +953,13 @@ static inline void nvme_handle_cqe(struct nvme_queue *nvmeq, u16 idx)
960953
}
961954

962955
req = blk_mq_tag_to_rq(nvme_queue_tagset(nvmeq), cqe->command_id);
956+
if (unlikely(!req)) {
957+
dev_warn(nvmeq->dev->ctrl.device,
958+
"invalid id %d completed on queue %d\n",
959+
cqe->command_id, le16_to_cpu(cqe->sq_id));
960+
return;
961+
}
962+
963963
trace_nvme_sq(req, cqe->sq_head, nvmeq->sq_tail);
964964
if (!nvme_try_complete_req(req, cqe->status, cqe->result))
965965
nvme_pci_complete_rq(req);

0 commit comments

Comments
 (0)