Skip to content

Commit e0262fc

Browse files
committed
Fix devdax_open_ipc_handle() and devdax_close_ipc_handle()
devdax_open_ipc_handle() has to use the path of the remote /dev/dax got from the IPC handle, not the local one. devdax_open_ipc_handle() has to use also the memory protection got from the IPC handle, so let's add the memory protection to the IPC handle. devdax_open_ipc_handle() should mmap only the required range of memory, not the whole /dev/dax device, so let's add the length of the allocation to the IPC handle. devdax_close_ipc_handle() should unmap only the required range of memory, not the whole /dev/dax device. Signed-off-by: Lukasz Dorau <[email protected]>
1 parent 71d7ef8 commit e0262fc

File tree

2 files changed

+50
-53
lines changed

2 files changed

+50
-53
lines changed

src/provider/provider_devdax_memory.c

Lines changed: 45 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -378,9 +378,11 @@ static umf_result_t devdax_allocation_merge(void *provider, void *lowPtr,
378378
}
379379

380380
typedef struct devdax_ipc_data_t {
381-
char dd_path[PATH_MAX]; // path to the /dev/dax
382-
size_t dd_size; // size of the /dev/dax
383-
size_t offset; // offset of the data
381+
char path[PATH_MAX]; // path to the /dev/dax
382+
unsigned protection; // combination of OS-specific memory protection flags
383+
// offset of the data (from the beginning of the devdax mapping) - see devdax_get_ipc_handle()
384+
size_t offset;
385+
size_t length; // length of the data
384386
} devdax_ipc_data_t;
385387

386388
static umf_result_t devdax_get_ipc_handle_size(void *provider, size_t *size) {
@@ -395,8 +397,6 @@ static umf_result_t devdax_get_ipc_handle_size(void *provider, size_t *size) {
395397

396398
static umf_result_t devdax_get_ipc_handle(void *provider, const void *ptr,
397399
size_t size, void *providerIpcData) {
398-
(void)size; // unused
399-
400400
if (provider == NULL || ptr == NULL || providerIpcData == NULL) {
401401
return UMF_RESULT_ERROR_INVALID_ARGUMENT;
402402
}
@@ -405,11 +405,12 @@ static umf_result_t devdax_get_ipc_handle(void *provider, const void *ptr,
405405
(devdax_memory_provider_t *)provider;
406406

407407
devdax_ipc_data_t *devdax_ipc_data = (devdax_ipc_data_t *)providerIpcData;
408+
strncpy(devdax_ipc_data->path, devdax_provider->path, PATH_MAX - 1);
409+
devdax_ipc_data->path[PATH_MAX - 1] = '\0';
410+
devdax_ipc_data->protection = devdax_provider->protection;
408411
devdax_ipc_data->offset =
409412
(size_t)((uintptr_t)ptr - (uintptr_t)devdax_provider->base);
410-
strncpy(devdax_ipc_data->dd_path, devdax_provider->path, PATH_MAX - 1);
411-
devdax_ipc_data->dd_path[PATH_MAX - 1] = '\0';
412-
devdax_ipc_data->dd_size = devdax_provider->size;
413+
devdax_ipc_data->length = size;
413414

414415
return UMF_RESULT_SUCCESS;
415416
}
@@ -425,16 +426,9 @@ static umf_result_t devdax_put_ipc_handle(void *provider,
425426
devdax_ipc_data_t *devdax_ipc_data = (devdax_ipc_data_t *)providerIpcData;
426427

427428
// verify the path of the /dev/dax
428-
if (strncmp(devdax_ipc_data->dd_path, devdax_provider->path, PATH_MAX)) {
429+
if (strncmp(devdax_ipc_data->path, devdax_provider->path, PATH_MAX)) {
429430
LOG_ERR("devdax path mismatch (local: %s, ipc: %s)",
430-
devdax_provider->path, devdax_ipc_data->dd_path);
431-
return UMF_RESULT_ERROR_INVALID_ARGUMENT;
432-
}
433-
434-
// verify the size of the /dev/dax
435-
if (devdax_ipc_data->dd_size != devdax_provider->size) {
436-
LOG_ERR("devdax size mismatch (local: %zu, ipc: %zu)",
437-
devdax_provider->size, devdax_ipc_data->dd_size);
431+
devdax_provider->path, devdax_ipc_data->path);
438432
return UMF_RESULT_ERROR_INVALID_ARGUMENT;
439433
}
440434

@@ -447,58 +441,56 @@ static umf_result_t devdax_open_ipc_handle(void *provider,
447441
return UMF_RESULT_ERROR_INVALID_ARGUMENT;
448442
}
449443

450-
devdax_memory_provider_t *devdax_provider =
451-
(devdax_memory_provider_t *)provider;
452444
devdax_ipc_data_t *devdax_ipc_data = (devdax_ipc_data_t *)providerIpcData;
453445

454-
// verify it is the same devdax - first verify the path
455-
if (strncmp(devdax_ipc_data->dd_path, devdax_provider->path, PATH_MAX)) {
456-
LOG_ERR("devdax path mismatch (local: %s, ipc: %s)",
457-
devdax_provider->path, devdax_ipc_data->dd_path);
446+
// length and offset passed to mmap() have to be page-aligned
447+
if (IS_NOT_ALIGNED(devdax_ipc_data->offset, DEVDAX_PAGE_SIZE_2MB)) {
448+
LOG_ERR("incorrect offset (%zu) in IPC handle - it is not page-aligned",
449+
devdax_ipc_data->offset);
458450
return UMF_RESULT_ERROR_INVALID_ARGUMENT;
459451
}
460452

461-
// verify the size of the /dev/dax
462-
if (devdax_ipc_data->dd_size != devdax_provider->size) {
463-
LOG_ERR("devdax size mismatch (local: %zu, ipc: %zu)",
464-
devdax_provider->size, devdax_ipc_data->dd_size);
465-
return UMF_RESULT_ERROR_INVALID_ARGUMENT;
466-
}
453+
// length and offset passed to mmap() have to be page-aligned
454+
size_t length_aligned =
455+
ALIGN_UP(devdax_ipc_data->length, DEVDAX_PAGE_SIZE_2MB);
467456

468-
umf_result_t ret = UMF_RESULT_SUCCESS;
469-
int fd = utils_devdax_open(devdax_provider->path);
457+
int fd = utils_devdax_open(devdax_ipc_data->path);
470458
if (fd == -1) {
471-
LOG_PERR("opening a devdax (%s) failed", devdax_provider->path);
459+
LOG_PERR("opening the devdax (%s) failed", devdax_ipc_data->path);
472460
return UMF_RESULT_ERROR_INVALID_ARGUMENT;
473461
}
474462

475463
unsigned map_sync_flag = 0;
476464
utils_translate_mem_visibility_flag(UMF_MEM_MAP_SYNC, &map_sync_flag);
477465

478466
// mmap /dev/dax with the MAP_SYNC xor MAP_SHARED flag (if MAP_SYNC fails)
479-
char *base = utils_mmap_file(NULL, devdax_provider->size,
480-
devdax_provider->protection, map_sync_flag, fd,
481-
0 /* offset */);
482-
if (base == NULL) {
467+
char *addr =
468+
utils_mmap_file(NULL, length_aligned, devdax_ipc_data->protection,
469+
map_sync_flag, fd, devdax_ipc_data->offset);
470+
if (addr == NULL) {
483471
devdax_store_last_native_error(UMF_DEVDAX_RESULT_ERROR_ALLOC_FAILED,
484472
errno);
485473
LOG_PERR("devdax mapping failed (path: %s, size: %zu, protection: %i, "
486-
"fd: %i)",
487-
devdax_provider->path, devdax_provider->size,
488-
devdax_provider->protection, fd);
489-
ret = UMF_RESULT_ERROR_MEMORY_PROVIDER_SPECIFIC;
474+
"fd: %i, offset: %zu)",
475+
devdax_ipc_data->path, length_aligned,
476+
devdax_ipc_data->protection, fd, devdax_ipc_data->offset);
477+
478+
*ptr = NULL;
479+
(void)utils_close_fd(fd);
480+
481+
return UMF_RESULT_ERROR_MEMORY_PROVIDER_SPECIFIC;
490482
}
491483

492484
LOG_DEBUG("devdax mapped (path: %s, size: %zu, protection: %i, fd: %i, "
493485
"offset: %zu)",
494-
devdax_provider->path, devdax_provider->size,
495-
devdax_provider->protection, fd, devdax_ipc_data->offset);
486+
devdax_ipc_data->path, length_aligned,
487+
devdax_ipc_data->protection, fd, devdax_ipc_data->offset);
496488

497-
(void)utils_close_fd(fd);
489+
*ptr = addr;
498490

499-
*ptr = base + devdax_ipc_data->offset;
491+
(void)utils_close_fd(fd);
500492

501-
return ret;
493+
return UMF_RESULT_SUCCESS;
502494
}
503495

504496
static umf_result_t devdax_close_ipc_handle(void *provider, void *ptr,
@@ -507,11 +499,16 @@ static umf_result_t devdax_close_ipc_handle(void *provider, void *ptr,
507499
return UMF_RESULT_ERROR_INVALID_ARGUMENT;
508500
}
509501

510-
devdax_memory_provider_t *devdax_provider =
511-
(devdax_memory_provider_t *)provider;
502+
// ptr and size passed to munmap() have to be page-aligned
503+
if (IS_NOT_ALIGNED((uintptr_t)ptr, DEVDAX_PAGE_SIZE_2MB)) {
504+
LOG_ERR("incorrect ptr (%p) - it is not page-aligned", ptr);
505+
return UMF_RESULT_ERROR_INVALID_ARGUMENT;
506+
}
507+
508+
size = ALIGN_UP(size, DEVDAX_PAGE_SIZE_2MB);
512509

513510
errno = 0;
514-
int ret = utils_munmap(devdax_provider->base, devdax_provider->size);
511+
int ret = utils_munmap(ptr, size);
515512
// ignore error when size == 0
516513
if (ret && (size > 0)) {
517514
devdax_store_last_native_error(UMF_DEVDAX_RESULT_ERROR_FREE_FAILED,

test/provider_devdax_memory.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,11 @@ TEST_P(umfProviderTest, alloc_2page_align_page_size) {
204204
PURGE_NONE);
205205
}
206206

207+
TEST_P(umfProviderTest, alloc_page64_align_page_div_2) {
208+
test_alloc_free_success(provider.get(), page_plus_64, page_size / 2,
209+
PURGE_NONE);
210+
}
211+
207212
TEST_P(umfProviderTest, purge_lazy) {
208213
test_alloc_free_success(provider.get(), page_size, 0, PURGE_LAZY);
209214
}
@@ -214,11 +219,6 @@ TEST_P(umfProviderTest, purge_force) {
214219

215220
// negative tests using test_alloc_failure
216221

217-
TEST_P(umfProviderTest, alloc_page64_align_page_div_2) {
218-
test_alloc_failure(provider.get(), page_plus_64, page_size / 2,
219-
UMF_RESULT_ERROR_INVALID_ARGUMENT, 0);
220-
}
221-
222222
TEST_P(umfProviderTest, alloc_page64_align_page_minus_1_WRONG_ALIGNMENT_1) {
223223
test_alloc_failure(provider.get(), page_plus_64, page_size - 1,
224224
UMF_RESULT_ERROR_INVALID_ARGUMENT, 0);

0 commit comments

Comments
 (0)