diff --git a/lib/nvme/nvme_ns_cmd.c b/lib/nvme/nvme_ns_cmd.c index 9a014a4e0..10636310e 100644 --- a/lib/nvme/nvme_ns_cmd.c +++ b/lib/nvme/nvme_ns_cmd.c @@ -271,6 +271,12 @@ _nvme_ns_cmd_split_sgl_request(struct spdk_nvme_ns *ns, if (req_current_length < req->payload_size) { args->next_sge_fn(args->cb_arg, (void **)&address, &sge_length); } + /* + * If the next SGE is not page aligned, we will need to create a child + * request for what we have so far, and then start a new child request for + * the next SGE. + */ + start_valid = _is_page_aligned(address); } if (start_valid && end_valid && !last_sge) { diff --git a/test/lib/nvme/sgl/sgl.c b/test/lib/nvme/sgl/sgl.c index 8afee6768..baceddb66 100644 --- a/test/lib/nvme/sgl/sgl.c +++ b/test/lib/nvme/sgl/sgl.c @@ -288,6 +288,23 @@ static void build_io_request_10(struct io_request *req) } } +static void build_io_request_11(struct io_request *req) +{ + /* This test case focuses on the last element not starting on a page boundary. */ + const size_t req_len[] = { 512, 512 }; + const size_t req_off[] = { 0xe00, 0x800 }; + struct sgl_element *iovs = req->iovs; + uint32_t i; + req->nseg = SPDK_COUNTOF(req_len); + assert(SPDK_COUNTOF(req_len) == SPDK_COUNTOF(req_off)); + + for (i = 0; i < req->nseg; i++) { + iovs[i].base = spdk_dma_zmalloc(req_off[i] + req_len[i], 0x4000, NULL); + iovs[i].offset = req_off[i]; + iovs[i].len = req_len[i]; + } +} + typedef void (*nvme_build_io_req_fn_t)(struct io_request *req); static void @@ -498,7 +515,8 @@ int main(int argc, char **argv) || TEST(build_io_request_7) || TEST(build_io_request_8) || TEST(build_io_request_9) - || TEST(build_io_request_10)) { + || TEST(build_io_request_10) + || TEST(build_io_request_11)) { #undef TEST rc = 1; printf("%s: failed sgl tests\n", iter->name);