diff --git a/lib/env_dpdk/memory.c b/lib/env_dpdk/memory.c index 62c594227..36c08e23b 100644 --- a/lib/env_dpdk/memory.c +++ b/lib/env_dpdk/memory.c @@ -252,10 +252,10 @@ err_unregister: } for (; idx_1gb < UINT64_MAX; idx_1gb--) { + /* Rebuild the virtual address from the indexes */ + uint64_t vaddr = (idx_256tb << SHIFT_1GB) | (idx_1gb << SHIFT_2MB); if ((map_1gb->map[idx_1gb].translation_2mb & REG_MAP_REGISTERED) && (contig_end == UINT64_MAX || (map_1gb->map[idx_1gb].translation_2mb & REG_MAP_NOTIFY_START) == 0)) { - /* Rebuild the virtual address from the indexes */ - uint64_t vaddr = (idx_256tb << SHIFT_1GB) | (idx_1gb << SHIFT_2MB); if (contig_end == UINT64_MAX) { contig_end = vaddr; @@ -263,12 +263,14 @@ err_unregister: contig_start = vaddr; } else { if (contig_end != UINT64_MAX) { + if (map_1gb->map[idx_1gb].translation_2mb & REG_MAP_NOTIFY_START) { + contig_start = vaddr; + } /* End of of a virtually contiguous range */ map->ops.notify_cb(map->cb_ctx, map, SPDK_MEM_MAP_NOTIFY_UNREGISTER, (void *)contig_start, contig_end - contig_start + VALUE_2MB); - idx_1gb++; } contig_end = UINT64_MAX; } @@ -285,6 +287,7 @@ spdk_mem_map_alloc(uint64_t default_translation, const struct spdk_mem_map_ops * { struct spdk_mem_map *map; int rc; + size_t i; map = calloc(1, sizeof(*map)); if (map == NULL) { @@ -309,6 +312,9 @@ spdk_mem_map_alloc(uint64_t default_translation, const struct spdk_mem_map_ops * pthread_mutex_unlock(&g_spdk_mem_map_mutex); DEBUG_PRINT("Initial mem_map notify failed\n"); pthread_mutex_destroy(&map->mutex); + for (i = 0; i < sizeof(map->map_256tb.map) / sizeof(map->map_256tb.map[0]); i++) { + free(map->map_256tb.map[i]); + } free(map); return NULL; } diff --git a/test/env/memory/memory_ut.c b/test/env/memory/memory_ut.c index e0583375f..3fb5b7f18 100644 --- a/test/env/memory/memory_ut.c +++ b/test/env/memory/memory_ut.c @@ -100,6 +100,8 @@ test_mem_map_notify_fail(void *cb_ctx, struct spdk_mem_map *map, enum spdk_mem_map_notify_action action, void *vaddr, size_t size) { struct spdk_mem_map *reg_map = cb_ctx; + uint64_t reg_addr; + uint64_t reg_size = size; switch (action) { case SPDK_MEM_MAP_NOTIFY_REGISTER: @@ -107,8 +109,16 @@ test_mem_map_notify_fail(void *cb_ctx, struct spdk_mem_map *map, /* Test the error handling. */ return -1; } + + CU_ASSERT(spdk_mem_map_set_translation(map, (uint64_t)vaddr, (uint64_t)size, (uint64_t)vaddr) == 0); + break; case SPDK_MEM_MAP_NOTIFY_UNREGISTER: + /* validate the start address */ + reg_addr = spdk_mem_map_translate(map, (uint64_t)vaddr, ®_size); + CU_ASSERT(reg_addr == (uint64_t)vaddr); + spdk_mem_map_clear_translation(map, (uint64_t)vaddr, size); + /* Clear the same region in the other mem_map to be able to * verify that there was no memory left still registered after * the mem_map creation failure.