dma: Update translation result to hold iovec pointer

In some cases a single virtually contriguos memory
buffer can be translated to several chunks of memory.
To make such translation possible, update structure
spdk_memory_domain_translation_result to use a pointer
to iovec.
Add a single iov structure or cases where translation
is always 1:1, it will make easier translation callback
implementation. For RDMA transport translation of address
is always 1:1, so treat iovcnt other than 1 as an
error.

Change-Id: I65605575d43a490490eba72c1eb19f3a09d55ec6
Signed-off-by: Alexey Marchuk <alexeymar@mellanox.com>
Signed-off-by: Max Gurtovoy <mgurtovoy@nvidia.com>
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/9779
Community-CI: Broadcom CI <spdk-ci.pdl@broadcom.com>
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: Ben Walker <benjamin.walker@intel.com>
Reviewed-by: Jim Harris <james.r.harris@intel.com>
This commit is contained in:
Alexey Marchuk 2021-10-06 18:24:07 +03:00 committed by Jim Harris
parent 549bcdc0a4
commit 2696886c75
4 changed files with 21 additions and 10 deletions

View File

@ -120,10 +120,14 @@ typedef int (*spdk_memory_domain_push_data_cb)(struct spdk_memory_domain *dst_do
struct spdk_memory_domain_translation_result {
/** size of this structure in bytes */
size_t size;
/** Address of data buffer translated into destination memory domain space */
void *addr;
/** Size of the data buffer */
size_t len;
/** Number of elements in iov */
uint32_t iov_count;
/** Translation results, holds single address, length pair. Should only be used if \b iov_count is 1 */
struct iovec iov;
/** Translation results, array of addresses and lengths. Should only be used if \b iov_count is
* bigger than 1. The implementer of the translation callback is responsible for allocating and
* storing of this array until IO request completes */
struct iovec *iovs;
/** Destination domain passed to translation function */
struct spdk_memory_domain *dst_domain;
union {

View File

@ -1375,15 +1375,15 @@ nvme_rdma_get_memory_translation(struct nvme_request *req, struct nvme_rdma_qpai
req->payload.opts->memory_domain_ctx,
rqpair->memory_domain->domain, &ctx, _ctx->addr,
_ctx->length, &dma_translation);
if (spdk_unlikely(rc)) {
SPDK_ERRLOG("DMA memory translation failed, rc %d\n", rc);
if (spdk_unlikely(rc) || dma_translation.iov_count != 1) {
SPDK_ERRLOG("DMA memory translation failed, rc %d, iov count %u\n", rc, dma_translation.iov_count);
return rc;
}
_ctx->lkey = dma_translation.rdma.lkey;
_ctx->rkey = dma_translation.rdma.rkey;
_ctx->addr = dma_translation.addr;
_ctx->length = dma_translation.len;
_ctx->addr = dma_translation.iov.iov_base;
_ctx->length = dma_translation.iov.iov_len;
} else {
rc = spdk_rdma_get_translation(rqpair->mr_map, _ctx->addr, _ctx->length, &rdma_translation);
if (spdk_unlikely(rc)) {

View File

@ -94,8 +94,9 @@ dma_test_translate_memory_cb(struct spdk_memory_domain *src_domain, void *src_do
return -1;
}
result->len = len;
result->addr = addr;
result->iov.iov_base = addr;
result->iov.iov_len = len;
result->iov_count = 1;
result->rdma.lkey = ctx->mr->lkey;
result->rdma.rkey = ctx->mr->rkey;
result->dst_domain = dst_domain;

View File

@ -1274,12 +1274,18 @@ test_rdma_get_memory_translation(void)
MOCK_CLEAR(spdk_memory_domain_translate_data);
/* Test 2 - expect pass */
g_memory_translation_translation.iov_count = 1;
g_memory_translation_translation.iov.iov_base = ctx.addr + 1;
g_memory_translation_translation.iov.iov_len = ctx.length;
g_memory_translation_translation.rdma.lkey = 123;
g_memory_translation_translation.rdma.rkey = 321;
rc = nvme_rdma_get_memory_translation(&req, &rqpair, &ctx);
CU_ASSERT(rc == 0);
CU_ASSERT(ctx.lkey == g_memory_translation_translation.rdma.lkey);
CU_ASSERT(ctx.rkey == g_memory_translation_translation.rdma.rkey);
CU_ASSERT(ctx.addr == g_memory_translation_translation.iov.iov_base);
CU_ASSERT(ctx.length == g_memory_translation_translation.iov.iov_len);
/* case 2, using rdma translation
* Test 1 - spdk_rdma_get_translation error, expect fail */