Skip to content

Commit 3129474

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 e80312b commit 3129474

File tree

1 file changed

+50
-46
lines changed

1 file changed

+50
-46
lines changed

src/provider/provider_devdax_memory.c

Lines changed: 50 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -377,9 +377,11 @@ static umf_result_t devdax_allocation_merge(void *provider, void *lowPtr,
377377
}
378378

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

385387
static umf_result_t devdax_get_ipc_handle_size(void *provider, size_t *size) {
@@ -394,8 +396,6 @@ static umf_result_t devdax_get_ipc_handle_size(void *provider, size_t *size) {
394396

395397
static umf_result_t devdax_get_ipc_handle(void *provider, const void *ptr,
396398
size_t size, void *providerIpcData) {
397-
(void)size; // unused
398-
399399
if (provider == NULL || ptr == NULL || providerIpcData == NULL) {
400400
return UMF_RESULT_ERROR_INVALID_ARGUMENT;
401401
}
@@ -404,11 +404,12 @@ static umf_result_t devdax_get_ipc_handle(void *provider, const void *ptr,
404404
(devdax_memory_provider_t *)provider;
405405

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

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

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

@@ -446,58 +440,60 @@ static umf_result_t devdax_open_ipc_handle(void *provider,
446440
return UMF_RESULT_ERROR_INVALID_ARGUMENT;
447441
}
448442

449-
devdax_memory_provider_t *devdax_provider =
450-
(devdax_memory_provider_t *)provider;
451443
devdax_ipc_data_t *devdax_ipc_data = (devdax_ipc_data_t *)providerIpcData;
452444

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

460-
// verify the size of the /dev/dax
461-
if (devdax_ipc_data->dd_size != devdax_provider->size) {
462-
LOG_ERR("devdax size mismatch (local: %zu, ipc: %zu)",
463-
devdax_provider->size, devdax_ipc_data->dd_size);
453+
if (IS_NOT_ALIGNED(devdax_ipc_data->length, DEVDAX_PAGE_SIZE_2MB)) {
454+
LOG_PERR(
455+
"incorrect length (%zu) in IPC handle - it is not page-aligned",
456+
devdax_ipc_data->length);
464457
return UMF_RESULT_ERROR_INVALID_ARGUMENT;
465458
}
466459

467-
umf_result_t ret = UMF_RESULT_SUCCESS;
468-
int fd = utils_devdax_open(devdax_provider->path);
460+
int fd = utils_devdax_open(devdax_ipc_data->path);
469461
if (fd == -1) {
470-
LOG_PERR("opening a devdax (%s) failed", devdax_provider->path);
462+
LOG_PERR("opening the devdax (%s) failed", devdax_ipc_data->path);
471463
return UMF_RESULT_ERROR_INVALID_ARGUMENT;
472464
}
473465

474466
unsigned map_sync_flag = 0;
475467
utils_translate_mem_visibility_flag(UMF_MEM_MAP_SYNC, &map_sync_flag);
476468

477469
// mmap /dev/dax with the MAP_SYNC xor MAP_SHARED flag (if MAP_SYNC fails)
478-
char *base = utils_mmap_file(NULL, devdax_provider->size,
479-
devdax_provider->protection, map_sync_flag, fd,
480-
0 /* offset */);
481-
if (base == NULL) {
470+
char *addr = utils_mmap_file(NULL, devdax_ipc_data->length,
471+
devdax_ipc_data->protection, map_sync_flag, fd,
472+
devdax_ipc_data->offset);
473+
if (addr == NULL) {
482474
devdax_store_last_native_error(UMF_DEVDAX_RESULT_ERROR_ALLOC_FAILED,
483475
errno);
484476
LOG_PERR("devdax mapping failed (path: %s, size: %zu, protection: %i, "
485-
"fd: %i)",
486-
devdax_provider->path, devdax_provider->size,
487-
devdax_provider->protection, fd);
488-
ret = UMF_RESULT_ERROR_MEMORY_PROVIDER_SPECIFIC;
477+
"fd: %i, offset: %zu)",
478+
devdax_ipc_data->path, devdax_ipc_data->length,
479+
devdax_ipc_data->protection, fd, devdax_ipc_data->offset);
480+
481+
*ptr = NULL;
482+
(void)utils_close_fd(fd);
483+
484+
return UMF_RESULT_ERROR_MEMORY_PROVIDER_SPECIFIC;
489485
}
490486

491487
LOG_DEBUG("devdax mapped (path: %s, size: %zu, protection: %i, fd: %i, "
492488
"offset: %zu)",
493-
devdax_provider->path, devdax_provider->size,
494-
devdax_provider->protection, fd, devdax_ipc_data->offset);
489+
devdax_ipc_data->path, devdax_ipc_data->length,
490+
devdax_ipc_data->protection, fd, devdax_ipc_data->offset);
495491

496-
(void)utils_close_fd(fd);
492+
*ptr = addr;
497493

498-
*ptr = base + devdax_ipc_data->offset;
494+
(void)utils_close_fd(fd);
499495

500-
return ret;
496+
return UMF_RESULT_SUCCESS;
501497
}
502498

503499
static umf_result_t devdax_close_ipc_handle(void *provider, void *ptr,
@@ -506,11 +502,19 @@ static umf_result_t devdax_close_ipc_handle(void *provider, void *ptr,
506502
return UMF_RESULT_ERROR_INVALID_ARGUMENT;
507503
}
508504

509-
devdax_memory_provider_t *devdax_provider =
510-
(devdax_memory_provider_t *)provider;
505+
// ptr and size passed to munmap() have to be page-aligned
506+
if (IS_NOT_ALIGNED((uintptr_t)ptr, DEVDAX_PAGE_SIZE_2MB)) {
507+
LOG_PERR("incorrect ptr (%p) - it is not page-aligned", ptr);
508+
return UMF_RESULT_ERROR_INVALID_ARGUMENT;
509+
}
510+
511+
if (IS_NOT_ALIGNED(size, DEVDAX_PAGE_SIZE_2MB)) {
512+
LOG_PERR("incorrect size (%zu) - it is not page-aligned", size);
513+
return UMF_RESULT_ERROR_INVALID_ARGUMENT;
514+
}
511515

512516
errno = 0;
513-
int ret = utils_munmap(devdax_provider->base, devdax_provider->size);
517+
int ret = utils_munmap(ptr, size);
514518
// ignore error when size == 0
515519
if (ret && (size > 0)) {
516520
devdax_store_last_native_error(UMF_DEVDAX_RESULT_ERROR_FREE_FAILED,

0 commit comments

Comments
 (0)