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>
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/7659 (master)
(cherry picked from commit 5354d0c63f
)
Change-Id: Ib1000d8b130e8e4bfeacccd6e60f8109428dfc1e
Signed-off-by: Krzysztof Karas <krzysztof.karas@intel.com>
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/9958
Reviewed-by: Tomasz Zawadzki <tomasz.zawadzki@intel.com>
Reviewed-by: Ben Walker <benjamin.walker@intel.com>
Reviewed-by: Jim Harris <james.r.harris@intel.com>
Tested-by: Tomasz Zawadzki <tomasz.zawadzki@intel.com>
This commit is contained in:
parent
cb37376ef6
commit
a1570edd1d
@ -918,7 +918,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) {
|
||||
@ -932,6 +931,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);
|
||||
|
Loading…
Reference in New Issue
Block a user