Commit 299fce88 authored by Shuhei Matsumoto's avatar Shuhei Matsumoto Committed by Tomasz Zawadzki
Browse files

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: default avatarShuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
Change-Id: Ie9efc200d06d02d8ee2be3cb8e9fd64591bc210d
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/2861


Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
Community-CI: Mellanox Build Bot
Reviewed-by: default avatarBen Walker <benjamin.walker@intel.com>
Reviewed-by: default avatarAleksey Marchuk <alexeymar@mellanox.com>
Reviewed-by: default avatarMichael Haeuptle <michaelhaeuptle@gmail.com>
parent aacac0b4
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -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);
	}
}