env_dpdk: spdk_mem_map_translate informs user of translation size.
This function will now check for whether or not a memory region is contiguous accross 2MB map entries and return the total length of that contiguous buffer up to the size specified by the user. Also includes unittests 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: I2ce582427d451be5a317808d0825c770e12e9a69 Signed-off-by: Seth Howell <seth.howell@intel.com> Reviewed-on: https://review.gerrithub.io/425329 Tested-by: SPDK CI Jenkins <sys_sgci@intel.com> Chandler-Test-Pool: SPDK Automated Test System <sys_sgsw@intel.com> Reviewed-by: Ben Walker <benjamin.walker@intel.com> Reviewed-by: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
This commit is contained in:
parent
4e06bb5e6d
commit
5d57386885
@ -979,11 +979,14 @@ typedef int (*spdk_mem_map_notify_cb)(void *cb_ctx, struct spdk_mem_map *map,
|
||||
enum spdk_mem_map_notify_action action,
|
||||
void *vaddr, size_t size);
|
||||
|
||||
typedef int (*spdk_mem_map_contiguous_translations)(uint64_t addr_1, uint64_t addr_2);
|
||||
|
||||
/**
|
||||
* A function table to be implemented by each memory map.
|
||||
*/
|
||||
struct spdk_mem_map_ops {
|
||||
spdk_mem_map_notify_cb notify_cb;
|
||||
spdk_mem_map_contiguous_translations are_contiguous;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -484,8 +484,12 @@ spdk_mem_map_translate(const struct spdk_mem_map *map, uint64_t vaddr, uint64_t
|
||||
uint64_t idx_256tb;
|
||||
uint64_t idx_1gb;
|
||||
uint64_t vfn_2mb;
|
||||
uint64_t total_size = 0;
|
||||
uint64_t cur_size;
|
||||
uint64_t prev_translation;
|
||||
|
||||
if (size != NULL) {
|
||||
total_size = *size;
|
||||
*size = 0;
|
||||
}
|
||||
|
||||
@ -503,14 +507,41 @@ spdk_mem_map_translate(const struct spdk_mem_map *map, uint64_t vaddr, uint64_t
|
||||
return map->default_translation;
|
||||
}
|
||||
|
||||
map_2mb = &map_1gb->map[idx_1gb];
|
||||
cur_size = VALUE_2MB;
|
||||
if (size != NULL) {
|
||||
*size = VALUE_2MB;
|
||||
}
|
||||
|
||||
map_2mb = &map_1gb->map[idx_1gb];
|
||||
if (size == NULL || map->ops.are_contiguous == NULL ||
|
||||
map_2mb->translation_2mb == map->default_translation) {
|
||||
return map_2mb->translation_2mb;
|
||||
}
|
||||
|
||||
prev_translation = map_2mb->translation_2mb;;
|
||||
while (cur_size < total_size) {
|
||||
vfn_2mb++;
|
||||
idx_256tb = MAP_256TB_IDX(vfn_2mb);
|
||||
idx_1gb = MAP_1GB_IDX(vfn_2mb);
|
||||
|
||||
map_1gb = map->map_256tb.map[idx_256tb];
|
||||
if (spdk_unlikely(!map_1gb)) {
|
||||
break;
|
||||
}
|
||||
|
||||
map_2mb = &map_1gb->map[idx_1gb];
|
||||
if (!map->ops.are_contiguous(prev_translation, map_2mb->translation_2mb)) {
|
||||
break;
|
||||
}
|
||||
|
||||
cur_size += VALUE_2MB;
|
||||
prev_translation = map_2mb->translation_2mb;
|
||||
}
|
||||
|
||||
*size = cur_size;
|
||||
return prev_translation;
|
||||
}
|
||||
|
||||
#if RTE_VERSION >= RTE_VERSION_NUM(18, 05, 0, 0)
|
||||
static void
|
||||
memory_hotplug_cb(enum rte_mem_event event_type,
|
||||
|
@ -605,7 +605,8 @@ int
|
||||
spdk_vtophys_init(void)
|
||||
{
|
||||
const struct spdk_mem_map_ops vtophys_map_ops = {
|
||||
.notify_cb = spdk_vtophys_notify
|
||||
.notify_cb = spdk_vtophys_notify,
|
||||
.are_contiguous = NULL
|
||||
};
|
||||
|
||||
#if SPDK_VFIO_ENABLED
|
||||
|
@ -637,7 +637,8 @@ nvme_rdma_register_mem(struct nvme_rdma_qpair *rqpair)
|
||||
struct ibv_pd *pd = rqpair->cm_id->qp->pd;
|
||||
struct spdk_nvme_rdma_mr_map *mr_map;
|
||||
const struct spdk_mem_map_ops nvme_rdma_map_ops = {
|
||||
.notify_cb = nvme_rdma_mr_map_notify
|
||||
.notify_cb = nvme_rdma_mr_map_notify,
|
||||
.are_contiguous = NULL
|
||||
};
|
||||
|
||||
pthread_mutex_lock(&g_rdma_mr_maps_mutex);
|
||||
|
@ -1635,7 +1635,8 @@ spdk_nvmf_rdma_create(struct spdk_nvmf_transport_opts *opts)
|
||||
uint32_t sge_count;
|
||||
|
||||
const struct spdk_mem_map_ops nvmf_rdma_map_ops = {
|
||||
.notify_cb = spdk_nvmf_rdma_mem_notify
|
||||
.notify_cb = spdk_nvmf_rdma_mem_notify,
|
||||
.are_contiguous = NULL
|
||||
};
|
||||
|
||||
rtransport = calloc(1, sizeof(*rtransport));
|
||||
|
54
test/env/memory/memory_ut.c
vendored
54
test/env/memory/memory_ut.c
vendored
@ -96,8 +96,20 @@ test_mem_map_notify(void *cb_ctx, struct spdk_mem_map *map,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
test_check_regions_contiguous(uint64_t addr1, uint64_t addr2)
|
||||
{
|
||||
return addr1 == addr2;
|
||||
}
|
||||
|
||||
const struct spdk_mem_map_ops test_mem_map_ops = {
|
||||
.notify_cb = test_mem_map_notify
|
||||
.notify_cb = test_mem_map_notify,
|
||||
.are_contiguous = test_check_regions_contiguous
|
||||
};
|
||||
|
||||
const struct spdk_mem_map_ops test_mem_map_ops_no_contig = {
|
||||
.notify_cb = test_mem_map_notify,
|
||||
.are_contiguous = NULL
|
||||
};
|
||||
|
||||
static void
|
||||
@ -119,6 +131,7 @@ test_mem_map_translation(void)
|
||||
struct spdk_mem_map *map;
|
||||
uint64_t default_translation = 0xDEADBEEF0BADF00D;
|
||||
uint64_t addr;
|
||||
uint64_t mapping_length;
|
||||
int rc;
|
||||
|
||||
map = spdk_mem_map_alloc(default_translation, &test_mem_map_ops, NULL);
|
||||
@ -144,6 +157,12 @@ test_mem_map_translation(void)
|
||||
rc = spdk_mem_map_set_translation(map, 0, 3 * VALUE_2MB, 0);
|
||||
CU_ASSERT(rc == 0);
|
||||
|
||||
/* Make sure we indicate that the three regions are contiguous */
|
||||
mapping_length = VALUE_2MB * 3;
|
||||
addr = spdk_mem_map_translate(map, 0, &mapping_length);
|
||||
CU_ASSERT(addr == 0);
|
||||
CU_ASSERT(mapping_length == VALUE_2MB * 3)
|
||||
|
||||
/* Clear translation for the middle page of the larger region. */
|
||||
rc = spdk_mem_map_clear_translation(map, VALUE_2MB, VALUE_2MB);
|
||||
CU_ASSERT(rc == 0);
|
||||
@ -152,6 +171,18 @@ test_mem_map_translation(void)
|
||||
addr = spdk_mem_map_translate(map, 0, NULL);
|
||||
CU_ASSERT(addr == 0);
|
||||
|
||||
/* Make sure we indicate that the three regions are no longer contiguous */
|
||||
mapping_length = VALUE_2MB * 3;
|
||||
addr = spdk_mem_map_translate(map, 0, &mapping_length);
|
||||
CU_ASSERT(addr == 0);
|
||||
CU_ASSERT(mapping_length == VALUE_2MB)
|
||||
|
||||
/* Get translation for an unallocated block. Make sure size is 0 */
|
||||
mapping_length = VALUE_2MB * 3;
|
||||
addr = spdk_mem_map_translate(map, VALUE_2MB, &mapping_length);
|
||||
CU_ASSERT(addr == default_translation);
|
||||
CU_ASSERT(mapping_length == VALUE_2MB)
|
||||
|
||||
/* Verify translation for 2nd page is the default */
|
||||
addr = spdk_mem_map_translate(map, VALUE_2MB, NULL);
|
||||
CU_ASSERT(addr == default_translation);
|
||||
@ -199,6 +230,27 @@ test_mem_map_translation(void)
|
||||
|
||||
spdk_mem_map_free(&map);
|
||||
CU_ASSERT(map == NULL);
|
||||
|
||||
/* Allocate a map without a contiguous region checker */
|
||||
map = spdk_mem_map_alloc(default_translation, &test_mem_map_ops_no_contig, NULL);
|
||||
SPDK_CU_ASSERT_FATAL(map != NULL);
|
||||
|
||||
/* map three contiguous regions */
|
||||
rc = spdk_mem_map_set_translation(map, 0, 3 * VALUE_2MB, 0);
|
||||
CU_ASSERT(rc == 0);
|
||||
|
||||
/* Since we can't check their contiguity, make sure we only return the size of one page */
|
||||
mapping_length = VALUE_2MB * 3;
|
||||
addr = spdk_mem_map_translate(map, 0, &mapping_length);
|
||||
CU_ASSERT(addr == 0);
|
||||
CU_ASSERT(mapping_length == VALUE_2MB)
|
||||
|
||||
/* Clear the translation */
|
||||
rc = spdk_mem_map_clear_translation(map, 0, VALUE_2MB * 3);
|
||||
CU_ASSERT(rc == 0);
|
||||
|
||||
spdk_mem_map_free(&map);
|
||||
CU_ASSERT(map == NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
|
3
test/env/vtophys/vtophys.c
vendored
3
test/env/vtophys/vtophys.c
vendored
@ -136,7 +136,8 @@ mem_map_test(void)
|
||||
struct spdk_mem_map *map;
|
||||
uint64_t default_translation = 0xDEADBEEF0BADF00D;
|
||||
const struct spdk_mem_map_ops test_map_ops = {
|
||||
.notify_cb = test_map_notify
|
||||
.notify_cb = test_map_notify,
|
||||
.are_contiguous = NULL
|
||||
};
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user