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 <james.r.harris@intel.com>
Change-Id: Ib1000d8b130e8e4bfeacccd6e60f8109428dfc1e

Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/7659
Community-CI: Mellanox Build Bot
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: Ben Walker <benjamin.walker@intel.com>
Reviewed-by: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
Reviewed-by: Changpeng Liu <changpeng.liu@intel.com>
Reviewed-by: Aleksey Marchuk <alexeymar@mellanox.com>
This commit is contained in:
Jim Harris 2021-04-28 12:44:18 -07:00 committed by Tomasz Zawadzki
parent 6fd1cc3716
commit 5354d0c63f

View File

@ -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);