nvme/rdma: Check that SGL descriptors fit into ICD

The issue happens when SPDK RDMA initiator is connected to a remote
target and this target reports rather small (or zero) ICD and we try
to send several SGL descriptors.
Since SGL descriptors are located in ICD, we should check that their
total length fits into ICD. In other case sending such a command
will cause RDMA errors (local length error)

Change-Id: I8c0e8375dae799bc442ed2fab249cad2c4ccce51
Signed-off-by: Alexey Marchuk <alexeymar@mellanox.com>
Reported-by: Or Gerlitz <ogerlitz@mellanox.com>
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/4131
Reviewed-by: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
Reviewed-by: Ben Walker <benjamin.walker@intel.com>
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
This commit is contained in:
Alexey Marchuk 2020-09-09 16:19:39 +03:00 committed by Tomasz Zawadzki
parent 0b510f0e83
commit eb78b90ca8
2 changed files with 21 additions and 3 deletions

View File

@ -1634,12 +1634,18 @@ nvme_rdma_build_sgl_request(struct nvme_rdma_qpair *rqpair,
* Otherwise, The SGL descriptor embedded in the command must point to the list of
* SGL descriptors used to describe the operation. In that case it is a last segment descriptor.
*/
rdma_req->send_sgl[0].length = sizeof(struct spdk_nvme_cmd) + sizeof(struct
spdk_nvme_sgl_descriptor) * num_sgl_desc;
uint32_t descriptors_size = sizeof(struct spdk_nvme_sgl_descriptor) * num_sgl_desc;
if (spdk_unlikely(descriptors_size > rqpair->qpair.ctrlr->ioccsz_bytes)) {
SPDK_ERRLOG("Size of SGL descriptors (%u) exceeds ICD (%u)\n",
descriptors_size, rqpair->qpair.ctrlr->ioccsz_bytes);
return -1;
}
rdma_req->send_sgl[0].length = sizeof(struct spdk_nvme_cmd) + descriptors_size;
req->cmd.dptr.sgl1.unkeyed.type = SPDK_NVME_SGL_TYPE_LAST_SEGMENT;
req->cmd.dptr.sgl1.unkeyed.subtype = SPDK_NVME_SGL_SUBTYPE_OFFSET;
req->cmd.dptr.sgl1.unkeyed.length = num_sgl_desc * sizeof(struct spdk_nvme_sgl_descriptor);
req->cmd.dptr.sgl1.unkeyed.length = descriptors_size;
req->cmd.dptr.sgl1.address = (uint64_t)0;
}

View File

@ -126,6 +126,7 @@ test_nvme_rdma_build_sgl_request(void)
ctrlr.max_sges = NVME_RDMA_MAX_SGL_DESCRIPTORS;
ctrlr.cdata.nvmf_specific.msdbd = 16;
ctrlr.ioccsz_bytes = 4096;
rqpair.mr_map = &rmap;
rqpair.qpair.ctrlr = &ctrlr;
@ -208,6 +209,17 @@ test_nvme_rdma_build_sgl_request(void)
bio.iovs[1].iov_len = 1 << 24;
rc = nvme_rdma_build_sgl_request(&rqpair, &rdma_req);
SPDK_CU_ASSERT_FATAL(rc != 0);
/* Test case 6: 4 SGL descriptors, size of SGL descriptors exceeds ICD. Expected: FAIL */
ctrlr.ioccsz_bytes = 60;
bio.iovpos = 0;
req.payload_offset = 0;
req.payload_size = 0x4000;
for (i = 0; i < 4; i++) {
bio.iovs[i].iov_len = 0x1000;
}
rc = nvme_rdma_build_sgl_request(&rqpair, &rdma_req);
SPDK_CU_ASSERT_FATAL(rc == -1);
}
static void