diff --git a/CHANGELOG.md b/CHANGELOG.md index 13ddbd69b..0bf499f9f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -22,6 +22,12 @@ does not at this time confer any SPDK ABI compatibility claims. spdk_bdev_alias_del_all() was added to delete all alias from block device. +### Environment Abstraction Layer and Event Framework + +The size parameter of spdk_mem_map_translate is now a pointer. This allows the +function to report back the actual size of the translation relative to the original +request made by the user. + ### iscsi Parameter names of `set_iscsi_options` and `get_iscsi_global_params` RPC diff --git a/include/spdk/env.h b/include/spdk/env.h index 43c01980e..68aff6d73 100644 --- a/include/spdk/env.h +++ b/include/spdk/env.h @@ -1032,12 +1032,13 @@ 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. + * \param size Contains the size of the memory region pointed to by vaddr. + * Updated with the size of the memory region for which the translation is valid. * * \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 size); +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 db0ce9216..b2b381964 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, VALUE_2MB); + ref_count = spdk_mem_map_translate(g_mem_reg_map, (uint64_t)vaddr, NULL); 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, VALUE_2MB); + ref_count = spdk_mem_map_translate(g_mem_reg_map, (uint64_t)seg_vaddr, NULL); 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, VALUE_2MB); + ref_count = spdk_mem_map_translate(g_mem_reg_map, (uint64_t)vaddr, NULL); spdk_mem_map_set_translation(g_mem_reg_map, (uint64_t)vaddr, VALUE_2MB, ref_count - 1); if (ref_count > 1) { @@ -475,7 +475,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, uint64_t size) +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; @@ -483,6 +483,10 @@ spdk_mem_map_translate(const struct spdk_mem_map *map, uint64_t vaddr, uint64_t uint64_t idx_1gb; uint64_t vfn_2mb; + if (size != NULL) { + *size = 0; + } + if (spdk_unlikely(vaddr & ~MASK_256TB)) { DEBUG_PRINT("invalid usermode virtual address %p\n", (void *)vaddr); return map->default_translation; @@ -498,6 +502,9 @@ spdk_mem_map_translate(const struct spdk_mem_map *map, uint64_t vaddr, uint64_t } map_2mb = &map_1gb->map[idx_1gb]; + if (size != NULL) { + *size = VALUE_2MB; + } return map_2mb->translation_2mb; } diff --git a/lib/env_dpdk/vtophys.c b/lib/env_dpdk/vtophys.c index 4ae20f580..a936130d1 100644 --- a/lib/env_dpdk/vtophys.c +++ b/lib/env_dpdk/vtophys.c @@ -405,7 +405,11 @@ 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, VALUE_2MB); + uint64_t buffer_len; + paddr = spdk_mem_map_translate(map, (uint64_t)vaddr, &buffer_len); + if (buffer_len != VALUE_2MB) { + return -EINVAL; + } rc = vtophys_iommu_unmap_dma(paddr, VALUE_2MB); if (rc) { return -EFAULT; @@ -619,7 +623,7 @@ spdk_vtophys(void *buf) vaddr = (uint64_t)buf; - paddr_2mb = spdk_mem_map_translate(g_vtophys_map, vaddr, VALUE_2MB); + paddr_2mb = spdk_mem_map_translate(g_vtophys_map, vaddr, NULL); /* * 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 1bac63653..2aff646d5 100644 --- a/lib/nvme/nvme_rdma.c +++ b/lib/nvme/nvme_rdma.c @@ -618,7 +618,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, size); + mr = (struct ibv_mr *)spdk_mem_map_translate(map, (uint64_t)vaddr, NULL); rc = spdk_mem_map_clear_translation(map, (uint64_t)vaddr, size); if (mr) { ibv_dereg_mr(mr); @@ -848,7 +848,7 @@ nvme_rdma_build_contig_inline_request(struct nvme_rdma_qpair *rqpair, 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, req->payload_size); + (uint64_t)payload, NULL); if (mr == NULL) { return -EINVAL; @@ -885,7 +885,7 @@ nvme_rdma_build_contig_request(struct nvme_rdma_qpair *rqpair, 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, - req->payload_size); + NULL); if (mr == NULL) { return -1; } @@ -932,7 +932,7 @@ nvme_rdma_build_sgl_request(struct nvme_rdma_qpair *rqpair, } mr = (struct ibv_mr *)spdk_mem_map_translate(rqpair->mr_map->map, (uint64_t)virt_addr, - req->payload_size); + NULL); if (mr == NULL) { return -1; } @@ -980,7 +980,7 @@ nvme_rdma_build_sgl_inline_request(struct nvme_rdma_qpair *rqpair, } mr = (struct ibv_mr *)spdk_mem_map_translate(rqpair->mr_map->map, (uint64_t)virt_addr, - req->payload_size); + NULL); if (mr == NULL) { return -1; } diff --git a/lib/nvmf/rdma.c b/lib/nvmf/rdma.c index 1b72b9963..4f12d9a2f 100644 --- a/lib/nvmf/rdma.c +++ b/lib/nvmf/rdma.c @@ -1161,7 +1161,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, size); + mr = (struct ibv_mr *)spdk_mem_map_translate(map, (uint64_t)vaddr, NULL); spdk_mem_map_clear_translation(map, (uint64_t)vaddr, size); if (mr) { ibv_dereg_mr(mr); @@ -1258,7 +1258,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, rdma_req->req.iov[i].iov_len))->lkey; + (uint64_t)buf, NULL))->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 626e312b3..23e64a3e8 100644 --- a/test/env/memory/memory_ut.c +++ b/test/env/memory/memory_ut.c @@ -121,7 +121,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, VALUE_2MB); + addr = spdk_mem_map_translate(map, 10, NULL); CU_ASSERT(addr == default_translation); /* Set translation for region of non-2MB multiple size */ @@ -145,15 +145,15 @@ test_mem_map_translation(void) CU_ASSERT(rc == 0); /* Get translation for first page */ - addr = spdk_mem_map_translate(map, 0, VALUE_2MB); + addr = spdk_mem_map_translate(map, 0, NULL); CU_ASSERT(addr == 0); /* Verify translation for 2nd page is the default */ - addr = spdk_mem_map_translate(map, VALUE_2MB, VALUE_2MB); + addr = spdk_mem_map_translate(map, VALUE_2MB, NULL); CU_ASSERT(addr == default_translation); /* Get translation for third page */ - addr = spdk_mem_map_translate(map, 2 * VALUE_2MB, VALUE_2MB); + addr = spdk_mem_map_translate(map, 2 * VALUE_2MB, NULL); /* * Note that addr should be 0, not 4MB. When we set the * translation above, we said the whole 6MB region @@ -166,7 +166,7 @@ test_mem_map_translation(void) CU_ASSERT(rc == 0); /* Get translation for the first page */ - addr = spdk_mem_map_translate(map, 0, VALUE_2MB); + addr = spdk_mem_map_translate(map, 0, NULL); CU_ASSERT(addr == default_translation); /* Clear translation for the third page */ @@ -174,7 +174,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, VALUE_2MB); + addr = spdk_mem_map_translate(map, 2 * VALUE_2MB, NULL); CU_ASSERT(addr == default_translation); /* Set translation for the last valid 2MB region */ @@ -182,7 +182,7 @@ test_mem_map_translation(void) CU_ASSERT(rc == 0); /* Verify translation for last valid 2MB region */ - addr = spdk_mem_map_translate(map, 0xffffffe00000ULL, VALUE_2MB); + addr = spdk_mem_map_translate(map, 0xffffffe00000ULL, NULL); CU_ASSERT(addr == 0x1234); /* Attempt to set translation for the first invalid address */