From 299fce881a2edcc90d6b1ae21f170d935489c654 Mon Sep 17 00:00:00 2001 From: Shuhei Matsumoto Date: Fri, 12 Jun 2020 08:42:09 +0900 Subject: [PATCH] nvme/pcie: Dequeue request from outstanding list before calling completion Each request has a callback context as cb_arg, and the callback to nvme_complete_request() for the completed request may reuse the context to the new request. On the other hand, nvme_pcie_qpair_complete_tracker() dequeues tr from pqpair->outstanding_tr after calling nvme_complete_request() for the request pointed by tr. Hence while nvme_complete_request() is executed, pqpair->outstanding_tr may have two requests which has the same callback context, the completed request and the new submitted request. The upcoming patch will search all requests whose cb_arg matches to abort them. In the above case, the search may find two requests by mistake. To avoid such error, change nvme_pcie_qpair_complete_tracker() to dequeue tr from pqpair->outstanding_tr before calling nvme_complete_request(). Signed-off-by: Shuhei Matsumoto Change-Id: Ie9efc200d06d02d8ee2be3cb8e9fd64591bc210d Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/2861 Tested-by: SPDK CI Jenkins Community-CI: Mellanox Build Bot Reviewed-by: Ben Walker Reviewed-by: Aleksey Marchuk Reviewed-by: Michael Haeuptle --- lib/nvme/nvme_pcie.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/nvme/nvme_pcie.c b/lib/nvme/nvme_pcie.c index 5c710efad..ec9058cbd 100644 --- a/lib/nvme/nvme_pcie.c +++ b/lib/nvme/nvme_pcie.c @@ -1383,6 +1383,8 @@ nvme_pcie_qpair_complete_tracker(struct spdk_nvme_qpair *qpair, struct nvme_trac req->retries++; nvme_pcie_qpair_submit_tracker(qpair, tr); } else { + TAILQ_REMOVE(&pqpair->outstanding_tr, tr, tq_list); + /* Only check admin requests from different processes. */ if (nvme_qpair_is_admin_queue(qpair) && req->pid != getpid()) { req_from_current_proc = false; @@ -1397,7 +1399,6 @@ nvme_pcie_qpair_complete_tracker(struct spdk_nvme_qpair *qpair, struct nvme_trac tr->req = NULL; - TAILQ_REMOVE(&pqpair->outstanding_tr, tr, tq_list); TAILQ_INSERT_HEAD(&pqpair->free_tr, tr, tq_list); } }