From 4f8b83cf51b9a817a75eb165aed7bf09c82857bd Mon Sep 17 00:00:00 2001 From: Jim Harris Date: Wed, 28 Apr 2021 12:44:18 -0700 Subject: [PATCH] nvme: reset mapping_length correctly for contig SGL spdk_vtophys() takes a mapping_length parameter, so it can return the length for which the returned virtual address is valid. But spdk_vtophys() will only return the max between the valid length and the input mapping_length parameter. So the nvme SGL building code for contiguous buffers was broken, since it would only set the mapping_length once, before the loop started. Worst case, if a buffer started just before (maybe 256 bytes) before a huge page boundary, each time through the loop we would create a new SGL for only 256 bytes at a time, very quickly running out of SGL entries for a large buffer. Fixes #1852. Signed-off-by: Jim Harris Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/7659 (master) (cherry picked from commit 5354d0c63f5da25e3c85d77bbfa44530d58c78e5) Change-Id: Ib1000d8b130e8e4bfeacccd6e60f8109428dfc1e Signed-off-by: Krzysztof Karas Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/7675 Reviewed-by: Tomasz Zawadzki Reviewed-by: Aleksey Marchuk Reviewed-by: Jim Harris Reviewed-by: Ben Walker Tested-by: SPDK CI Jenkins --- lib/nvme/nvme_pcie.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/nvme/nvme_pcie.c b/lib/nvme/nvme_pcie.c index df751c479..2a5a7f72d 100644 --- a/lib/nvme/nvme_pcie.c +++ b/lib/nvme/nvme_pcie.c @@ -1219,7 +1219,6 @@ nvme_pcie_qpair_build_contig_hw_sgl_request(struct spdk_nvme_qpair *qpair, struc length = req->payload_size; virt_addr = req->payload.contig_or_cb_arg + req->payload_offset; - mapping_length = length; while (length > 0) { if (nseg >= NVME_MAX_SGL_DESCRIPTORS) { @@ -1233,6 +1232,7 @@ nvme_pcie_qpair_build_contig_hw_sgl_request(struct spdk_nvme_qpair *qpair, struc return -EFAULT; } + mapping_length = length; phys_addr = spdk_vtophys(virt_addr, &mapping_length); if (phys_addr == SPDK_VTOPHYS_ERROR) { nvme_pcie_fail_request_bad_vtophys(qpair, tr);