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:
parent
0b510f0e83
commit
eb78b90ca8
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user