env_dpdk: change behavior of spdk_mem_map_translate
The function now takes a pointer as it's last argument, and copies the size of the memory region for which the translation is validinto that pointer. For now, that will always be 2MB. However that behavior can change in the future. This series of changes is aimed at enabling spdk_mem_map_translate to report back to the user the length of the valid mem_map up to the function that requested the translation. This will be useful when retrieving memory regions associated with I/O buffers in NVMe-oF. For large I/O it will be possible that the buffer is split over multiple MRs and the I/O will have to be split into multiple SGLs. Change-Id: I8686c166ec956507f5ae55cf602341281482cb89 Signed-off-by: Seth Howell <seth.howell@intel.com> Reviewed-on: https://review.gerrithub.io/424888 Tested-by: SPDK CI Jenkins <sys_sgci@intel.com> Chandler-Test-Pool: SPDK Automated Test System <sys_sgsw@intel.com> Reviewed-by: Jim Harris <james.r.harris@intel.com> Reviewed-by: Ben Walker <benjamin.walker@intel.com>
This commit is contained in:
parent
7e408509ba
commit
d288c41242
@ -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
|
||||
|
@ -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.
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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++;
|
||||
|
14
test/env/memory/memory_ut.c
vendored
14
test/env/memory/memory_ut.c
vendored
@ -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 */
|
||||
|
Loading…
Reference in New Issue
Block a user