memory: allow unregistering multiple adjacent regions at once

All mem_maps will still receive separate unregister
notification for each registered region, but the
public memory unregister API is more flexible now.

This follows the VFIO_TYPE1v2_IOMMU interface, which
allows the same.

Change-Id: Ifc008afdc6bff39d9b3b4c892c379ade10c3098e
Signed-off-by: Darek Stojaczyk <dariusz.stojaczyk@intel.com>
Reviewed-on: https://review.gerrithub.io/428715
Chandler-Test-Pool: SPDK Automated Test System <sys_sgsw@intel.com>
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: Ben Walker <benjamin.walker@intel.com>
Reviewed-by: Jim Harris <james.r.harris@intel.com>
This commit is contained in:
Darek Stojaczyk 2018-10-10 17:23:24 +02:00 committed by Jim Harris
parent 08039550d9
commit 3372a72ca9
2 changed files with 26 additions and 8 deletions

View File

@ -438,8 +438,8 @@ spdk_mem_unregister(void *vaddr, size_t len)
}
}
seg_vaddr = vaddr + VALUE_2MB;
seg_len = 0;
seg_vaddr = vaddr;
seg_len = VALUE_2MB;
} else {
seg_len += VALUE_2MB;
}

View File

@ -406,13 +406,17 @@ test_mem_map_registration(void)
static void
test_mem_map_registration_adjacent(void)
{
struct spdk_mem_map *map;
struct spdk_mem_map *map, *newmap;
uint64_t default_translation = 0xDEADBEEF0BADF00D;
uintptr_t vaddr;
unsigned i;
size_t notify_len[PAGE_ARRAY_SIZE] = {0};
size_t chunk_len[] = { 2, 1, 3, 2, 1, 1 };
map = spdk_mem_map_alloc(default_translation,
&test_map_ops_notify_checklen, notify_len);
SPDK_CU_ASSERT_FATAL(map != NULL);
vaddr = 0;
for (i = 0; i < SPDK_COUNTOF(chunk_len); i++) {
notify_len[vaddr / VALUE_2MB] = chunk_len[i] * VALUE_2MB;
@ -421,11 +425,11 @@ test_mem_map_registration_adjacent(void)
}
/* Verify the memory is translated in the same chunks it was registered */
map = spdk_mem_map_alloc(default_translation,
&test_map_ops_notify_checklen, notify_len);
SPDK_CU_ASSERT_FATAL(map != NULL);
spdk_mem_map_free(&map);
CU_ASSERT(map == NULL);
newmap = spdk_mem_map_alloc(default_translation,
&test_map_ops_notify_checklen, notify_len);
SPDK_CU_ASSERT_FATAL(newmap != NULL);
spdk_mem_map_free(&newmap);
CU_ASSERT(newmap == NULL);
vaddr = 0;
for (i = 0; i < SPDK_COUNTOF(chunk_len); i++) {
@ -433,6 +437,20 @@ test_mem_map_registration_adjacent(void)
spdk_mem_unregister((void *)vaddr, notify_len[vaddr / VALUE_2MB]);
vaddr += notify_len[vaddr / VALUE_2MB];
}
/* Register all chunks again just to unregister them again, but this
* time with only a single unregister() call.
*/
vaddr = 0;
for (i = 0; i < SPDK_COUNTOF(chunk_len); i++) {
notify_len[vaddr / VALUE_2MB] = chunk_len[i] * VALUE_2MB;
spdk_mem_register((void *)vaddr, notify_len[vaddr / VALUE_2MB]);
vaddr += notify_len[vaddr / VALUE_2MB];
}
spdk_mem_unregister(0, vaddr);
spdk_mem_map_free(&map);
CU_ASSERT(map == NULL);
}
int