Commit 5354d0c6 authored by Jim Harris's avatar Jim Harris Committed by Tomasz Zawadzki
Browse files

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: default avatarJim 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: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: default avatarBen Walker <benjamin.walker@intel.com>
Reviewed-by: default avatarShuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
Reviewed-by: default avatarChangpeng Liu <changpeng.liu@intel.com>
Reviewed-by: default avatarAleksey Marchuk <alexeymar@mellanox.com>
parent 6fd1cc37
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -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);