diff --git a/CHANGELOG.md b/CHANGELOG.md index f6328d9b7..a9e0d6c71 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,12 @@ on each call. This allows multiple callers to query I/O statistics without confl with each other. Existing users will need to adjust their code to record the previous I/O statistics to calculate the delta between calls. +### Env + +The spdk_mem_map_translate() function now takes a size parameter to indicate the size of +the memory region. This can be used by environment implementations to validate the +requested translation. + ### git pre-commit and pre-push hooks The pre-commit hook will run `scripts/check_format.sh` and verify there are no formating diff --git a/include/spdk/env.h b/include/spdk/env.h index 83903b96d..2b75aa035 100644 --- a/include/spdk/env.h +++ b/include/spdk/env.h @@ -1007,10 +1007,12 @@ int spdk_mem_map_clear_translation(struct spdk_mem_map *map, uint64_t vaddr, uin * * \param map Memory map. * \param vaddr Virtual address. + * \param size Size of memory region. * - * \return the translation of 2MB hugepage mapping. + * \return the translation of vaddr stored in the map, or default_translation + * as specified in spdk_mem_map_alloc() if vaddr is not present in the map. */ -uint64_t spdk_mem_map_translate(const struct spdk_mem_map *map, uint64_t vaddr); +uint64_t spdk_mem_map_translate(const struct spdk_mem_map *map, uint64_t vaddr, uint64_t size); /** * Register the specified memory region for address translation. diff --git a/lib/env_dpdk/memory.c b/lib/env_dpdk/memory.c index 122e38718..eb5404099 100644 --- a/lib/env_dpdk/memory.c +++ b/lib/env_dpdk/memory.c @@ -239,7 +239,7 @@ spdk_mem_register(void *vaddr, size_t len) uint64_t ref_count; /* In g_mem_reg_map, the "translation" is the reference count */ - ref_count = spdk_mem_map_translate(g_mem_reg_map, (uint64_t)vaddr); + ref_count = spdk_mem_map_translate(g_mem_reg_map, (uint64_t)vaddr, VALUE_2MB); spdk_mem_map_set_translation(g_mem_reg_map, (uint64_t)vaddr, VALUE_2MB, ref_count + 1); if (ref_count > 0) { @@ -302,7 +302,7 @@ spdk_mem_unregister(void *vaddr, size_t len) seg_vaddr = vaddr; seg_len = len; while (seg_len > 0) { - ref_count = spdk_mem_map_translate(g_mem_reg_map, (uint64_t)seg_vaddr); + ref_count = spdk_mem_map_translate(g_mem_reg_map, (uint64_t)seg_vaddr, VALUE_2MB); if (ref_count == 0) { pthread_mutex_unlock(&g_spdk_mem_map_mutex); return -EINVAL; @@ -315,7 +315,7 @@ spdk_mem_unregister(void *vaddr, size_t len) seg_len = 0; while (len > 0) { /* In g_mem_reg_map, the "translation" is the reference count */ - ref_count = spdk_mem_map_translate(g_mem_reg_map, (uint64_t)vaddr); + ref_count = spdk_mem_map_translate(g_mem_reg_map, (uint64_t)vaddr, VALUE_2MB); spdk_mem_map_set_translation(g_mem_reg_map, (uint64_t)vaddr, VALUE_2MB, ref_count - 1); if (ref_count > 1) { @@ -471,7 +471,7 @@ spdk_mem_map_clear_translation(struct spdk_mem_map *map, uint64_t vaddr, uint64_ } uint64_t -spdk_mem_map_translate(const struct spdk_mem_map *map, uint64_t vaddr) +spdk_mem_map_translate(const struct spdk_mem_map *map, uint64_t vaddr, uint64_t size) { const struct map_1gb *map_1gb; const struct map_2mb *map_2mb; diff --git a/lib/env_dpdk/vtophys.c b/lib/env_dpdk/vtophys.c index 224ebf486..fe483b17b 100644 --- a/lib/env_dpdk/vtophys.c +++ b/lib/env_dpdk/vtophys.c @@ -404,7 +404,7 @@ spdk_vtophys_notify(void *cb_ctx, struct spdk_mem_map *map, * we need to unmap the range from the IOMMU */ if (g_vfio.enabled) { - paddr = spdk_mem_map_translate(map, (uint64_t)vaddr); + paddr = spdk_mem_map_translate(map, (uint64_t)vaddr, VALUE_2MB); rc = vtophys_iommu_unmap_dma(paddr, VALUE_2MB); if (rc) { return -EFAULT; @@ -618,7 +618,7 @@ spdk_vtophys(void *buf) vaddr = (uint64_t)buf; - paddr_2mb = spdk_mem_map_translate(g_vtophys_map, vaddr); + paddr_2mb = spdk_mem_map_translate(g_vtophys_map, vaddr, VALUE_2MB); /* * SPDK_VTOPHYS_ERROR has all bits set, so if the lookup returned SPDK_VTOPHYS_ERROR, diff --git a/lib/nvme/nvme_rdma.c b/lib/nvme/nvme_rdma.c index 757213538..a6299bd56 100644 --- a/lib/nvme/nvme_rdma.c +++ b/lib/nvme/nvme_rdma.c @@ -687,7 +687,7 @@ nvme_rdma_mr_map_notify(void *cb_ctx, struct spdk_mem_map *map, } break; case SPDK_MEM_MAP_NOTIFY_UNREGISTER: - mr = (struct ibv_mr *)spdk_mem_map_translate(map, (uint64_t)vaddr); + mr = (struct ibv_mr *)spdk_mem_map_translate(map, (uint64_t)vaddr, size); rc = spdk_mem_map_clear_translation(map, (uint64_t)vaddr, size); if (mr) { ibv_dereg_mr(mr); @@ -911,7 +911,8 @@ nvme_rdma_build_contig_request(struct nvme_rdma_qpair *rqpair, struct nvme_reque assert(req->payload_size != 0); assert(nvme_payload_type(&req->payload) == NVME_PAYLOAD_TYPE_CONTIG); - mr = (struct ibv_mr *)spdk_mem_map_translate(rqpair->mr_map->map, (uint64_t)payload); + mr = (struct ibv_mr *)spdk_mem_map_translate(rqpair->mr_map->map, (uint64_t)payload, + req->payload_size); if (mr == NULL) { return -1; } @@ -954,7 +955,8 @@ nvme_rdma_build_sgl_request(struct nvme_rdma_qpair *rqpair, struct nvme_request return -1; } - mr = (struct ibv_mr *)spdk_mem_map_translate(rqpair->mr_map->map, (uint64_t)virt_addr); + mr = (struct ibv_mr *)spdk_mem_map_translate(rqpair->mr_map->map, (uint64_t)virt_addr, + req->payload_size); if (mr == NULL) { return -1; } diff --git a/lib/nvmf/rdma.c b/lib/nvmf/rdma.c index 5e392c352..7025dd09c 100644 --- a/lib/nvmf/rdma.c +++ b/lib/nvmf/rdma.c @@ -779,7 +779,7 @@ spdk_nvmf_rdma_mem_notify(void *cb_ctx, struct spdk_mem_map *map, } break; case SPDK_MEM_MAP_NOTIFY_UNREGISTER: - mr = (struct ibv_mr *)spdk_mem_map_translate(map, (uint64_t)vaddr); + mr = (struct ibv_mr *)spdk_mem_map_translate(map, (uint64_t)vaddr, size); spdk_mem_map_clear_translation(map, (uint64_t)vaddr, size); if (mr) { ibv_dereg_mr(mr); @@ -871,7 +871,7 @@ spdk_nvmf_rdma_request_fill_iovs(struct spdk_nvmf_rdma_transport *rtransport, rdma_req->data.wr.sg_list[i].addr = (uintptr_t)(rdma_req->req.iov[i].iov_base); rdma_req->data.wr.sg_list[i].length = rdma_req->req.iov[i].iov_len; rdma_req->data.wr.sg_list[i].lkey = ((struct ibv_mr *)spdk_mem_map_translate(device->map, - (uint64_t)buf))->lkey; + (uint64_t)buf, rdma_req->req.iov[i].iov_len))->lkey; length -= rdma_req->req.iov[i].iov_len; i++; diff --git a/test/env/memory/memory_ut.c b/test/env/memory/memory_ut.c index bee66487e..af93dbbe3 100644 --- a/test/env/memory/memory_ut.c +++ b/test/env/memory/memory_ut.c @@ -125,7 +125,7 @@ test_mem_map_translation(void) SPDK_CU_ASSERT_FATAL(map != NULL); /* Try to get translation for address with no translation */ - addr = spdk_mem_map_translate(map, 10); + addr = spdk_mem_map_translate(map, 10, VALUE_2MB); CU_ASSERT(addr == default_translation); /* Set translation for region of non-2MB multiple size */ @@ -149,15 +149,15 @@ test_mem_map_translation(void) CU_ASSERT(rc == 0); /* Get translation for first page */ - addr = spdk_mem_map_translate(map, 0); + addr = spdk_mem_map_translate(map, 0, VALUE_2MB); CU_ASSERT(addr == 0); /* Verify translation for 2nd page is the default */ - addr = spdk_mem_map_translate(map, VALUE_2MB); + addr = spdk_mem_map_translate(map, VALUE_2MB, VALUE_2MB); CU_ASSERT(addr == default_translation); /* Get translation for third page */ - addr = spdk_mem_map_translate(map, 2 * VALUE_2MB); + addr = spdk_mem_map_translate(map, 2 * VALUE_2MB, VALUE_2MB); /* * Note that addr should be 0, not 4MB. When we set the * translation above, we said the whole 6MB region @@ -170,7 +170,7 @@ test_mem_map_translation(void) CU_ASSERT(rc == 0); /* Get translation for the first page */ - addr = spdk_mem_map_translate(map, 0); + addr = spdk_mem_map_translate(map, 0, VALUE_2MB); CU_ASSERT(addr == default_translation); /* Clear translation for the third page */ @@ -178,7 +178,7 @@ test_mem_map_translation(void) CU_ASSERT(rc == 0); /* Get translation for the third page */ - addr = spdk_mem_map_translate(map, 2 * VALUE_2MB); + addr = spdk_mem_map_translate(map, 2 * VALUE_2MB, VALUE_2MB); CU_ASSERT(addr == default_translation); spdk_mem_map_free(&map);