Skip to content

Commit a4f1c8b

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 d72a841 commit a4f1c8b

File tree

1 file changed

+52
-54
lines changed

1 file changed

+52
-54
lines changed

src/provider/provider_devdax_memory.c

Lines changed: 52 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,8 @@ umf_memory_provider_ops_t *umfDevDaxMemoryProviderOps(void) {
3131
#include "utils_concurrency.h"
3232
#include "utils_log.h"
3333

34-
#define NODESET_STR_BUF_LEN 1024
34+
// the default alignment for the devdax mode
35+
#define DEVDAX_ALIGNMENT_2MB (2 * 1024 * 1024) // == 2 MB
3536

3637
#define TLS_MSG_BUF_LEN 1024
3738

@@ -300,7 +301,8 @@ static umf_result_t devdax_get_recommended_page_size(void *provider,
300301
return UMF_RESULT_ERROR_INVALID_ARGUMENT;
301302
}
302303

303-
*page_size = utils_get_page_size();
304+
// the default alignment for the devdax mode
305+
*page_size = DEVDAX_ALIGNMENT_2MB;
304306

305307
return UMF_RESULT_SUCCESS;
306308
}
@@ -369,9 +371,11 @@ static umf_result_t devdax_allocation_merge(void *provider, void *lowPtr,
369371
}
370372

371373
typedef struct devdax_ipc_data_t {
372-
char dd_path[PATH_MAX]; // path to the /dev/dax
373-
size_t dd_size; // size of the /dev/dax
374-
size_t offset; // offset of the data
374+
char path[PATH_MAX]; // path to the /dev/dax
375+
unsigned protection; // combination of OS-specific memory protection flags
376+
// offset of the data (from the beginning of the devdax mapping) - see devdax_get_ipc_handle()
377+
size_t offset;
378+
size_t length; // length of the data
375379
} devdax_ipc_data_t;
376380

377381
static umf_result_t devdax_get_ipc_handle_size(void *provider, size_t *size) {
@@ -386,8 +390,6 @@ static umf_result_t devdax_get_ipc_handle_size(void *provider, size_t *size) {
386390

387391
static umf_result_t devdax_get_ipc_handle(void *provider, const void *ptr,
388392
size_t size, void *providerIpcData) {
389-
(void)size; // unused
390-
391393
if (provider == NULL || ptr == NULL || providerIpcData == NULL) {
392394
return UMF_RESULT_ERROR_INVALID_ARGUMENT;
393395
}
@@ -396,11 +398,12 @@ static umf_result_t devdax_get_ipc_handle(void *provider, const void *ptr,
396398
(devdax_memory_provider_t *)provider;
397399

398400
devdax_ipc_data_t *devdax_ipc_data = (devdax_ipc_data_t *)providerIpcData;
401+
strncpy(devdax_ipc_data->path, devdax_provider->path, PATH_MAX - 1);
402+
devdax_ipc_data->path[PATH_MAX - 1] = '\0';
403+
devdax_ipc_data->protection = devdax_provider->protection;
399404
devdax_ipc_data->offset =
400405
(size_t)((uintptr_t)ptr - (uintptr_t)devdax_provider->base);
401-
strncpy(devdax_ipc_data->dd_path, devdax_provider->path, PATH_MAX - 1);
402-
devdax_ipc_data->dd_path[PATH_MAX - 1] = '\0';
403-
devdax_ipc_data->dd_size = devdax_provider->size;
406+
devdax_ipc_data->length = size;
404407

405408
return UMF_RESULT_SUCCESS;
406409
}
@@ -416,16 +419,9 @@ static umf_result_t devdax_put_ipc_handle(void *provider,
416419
devdax_ipc_data_t *devdax_ipc_data = (devdax_ipc_data_t *)providerIpcData;
417420

418421
// verify the path of the /dev/dax
419-
if (strncmp(devdax_ipc_data->dd_path, devdax_provider->path, PATH_MAX)) {
422+
if (strncmp(devdax_ipc_data->path, devdax_provider->path, PATH_MAX)) {
420423
LOG_ERR("devdax path mismatch (local: %s, ipc: %s)",
421-
devdax_provider->path, devdax_ipc_data->dd_path);
422-
return UMF_RESULT_ERROR_INVALID_ARGUMENT;
423-
}
424-
425-
// verify the size of the /dev/dax
426-
if (devdax_ipc_data->dd_size != devdax_provider->size) {
427-
LOG_ERR("devdax size mismatch (local: %zu, ipc: %zu)",
428-
devdax_provider->size, devdax_ipc_data->dd_size);
424+
devdax_provider->path, devdax_ipc_data->path);
429425
return UMF_RESULT_ERROR_INVALID_ARGUMENT;
430426
}
431427

@@ -438,58 +434,56 @@ static umf_result_t devdax_open_ipc_handle(void *provider,
438434
return UMF_RESULT_ERROR_INVALID_ARGUMENT;
439435
}
440436

441-
devdax_memory_provider_t *devdax_provider =
442-
(devdax_memory_provider_t *)provider;
443437
devdax_ipc_data_t *devdax_ipc_data = (devdax_ipc_data_t *)providerIpcData;
444438

445-
// verify it is the same devdax - first verify the path
446-
if (strncmp(devdax_ipc_data->dd_path, devdax_provider->path, PATH_MAX)) {
447-
LOG_ERR("devdax path mismatch (local: %s, ipc: %s)",
448-
devdax_provider->path, devdax_ipc_data->dd_path);
449-
return UMF_RESULT_ERROR_INVALID_ARGUMENT;
450-
}
451-
452-
// verify the size of the /dev/dax
453-
if (devdax_ipc_data->dd_size != devdax_provider->size) {
454-
LOG_ERR("devdax size mismatch (local: %zu, ipc: %zu)",
455-
devdax_provider->size, devdax_ipc_data->dd_size);
456-
return UMF_RESULT_ERROR_INVALID_ARGUMENT;
457-
}
458-
459-
umf_result_t ret = UMF_RESULT_SUCCESS;
460-
int fd = utils_devdax_open(devdax_provider->path);
439+
int fd = utils_devdax_open(devdax_ipc_data->path);
461440
if (fd == -1) {
462-
LOG_PERR("opening a devdax (%s) failed", devdax_provider->path);
441+
LOG_PERR("opening the devdax (%s) failed", devdax_ipc_data->path);
463442
return UMF_RESULT_ERROR_INVALID_ARGUMENT;
464443
}
465444

466445
unsigned map_sync_flag = 0;
467446
utils_translate_mem_visibility_flag(UMF_MEM_MAP_SYNC, &map_sync_flag);
468447

448+
// get the page size
449+
size_t page_size;
450+
(void)devdax_get_recommended_page_size(provider, devdax_ipc_data->length,
451+
&page_size);
452+
453+
// length and offset passed to mmap() have to be page-aligned in case of /dev/dax device
454+
size_t offset_aligned = devdax_ipc_data->offset;
455+
size_t length_aligned = devdax_ipc_data->length;
456+
utils_align_ptr_down_size_up((void **)&offset_aligned, &length_aligned,
457+
page_size);
458+
469459
// mmap /dev/dax with the MAP_SYNC xor MAP_SHARED flag (if MAP_SYNC fails)
470-
char *base = utils_mmap_file(NULL, devdax_provider->size,
471-
devdax_provider->protection, map_sync_flag, fd,
472-
0 /* offset */);
473-
if (base == NULL) {
460+
char *addr =
461+
utils_mmap_file(NULL, length_aligned, devdax_ipc_data->protection,
462+
map_sync_flag, fd, offset_aligned);
463+
if (addr == NULL) {
474464
devdax_store_last_native_error(UMF_DEVDAX_RESULT_ERROR_ALLOC_FAILED,
475465
errno);
476466
LOG_PERR("devdax mapping failed (path: %s, size: %zu, protection: %i, "
477-
"fd: %i)",
478-
devdax_provider->path, devdax_provider->size,
479-
devdax_provider->protection, fd);
480-
ret = UMF_RESULT_ERROR_MEMORY_PROVIDER_SPECIFIC;
467+
"fd: %i, offset: %zu)",
468+
devdax_ipc_data->path, length_aligned,
469+
devdax_ipc_data->protection, fd, offset_aligned);
470+
471+
*ptr = NULL;
472+
(void)utils_close_fd(fd);
473+
474+
return UMF_RESULT_ERROR_MEMORY_PROVIDER_SPECIFIC;
481475
}
482476

483477
LOG_DEBUG("devdax mapped (path: %s, size: %zu, protection: %i, fd: %i, "
484478
"offset: %zu)",
485-
devdax_provider->path, devdax_provider->size,
486-
devdax_provider->protection, fd, devdax_ipc_data->offset);
479+
devdax_ipc_data->path, length_aligned,
480+
devdax_ipc_data->protection, fd, offset_aligned);
487481

488-
(void)utils_close_fd(fd);
482+
*ptr = addr + (devdax_ipc_data->offset - offset_aligned);
489483

490-
*ptr = base + devdax_ipc_data->offset;
484+
(void)utils_close_fd(fd);
491485

492-
return ret;
486+
return UMF_RESULT_SUCCESS;
493487
}
494488

495489
static umf_result_t devdax_close_ipc_handle(void *provider, void *ptr,
@@ -498,11 +492,15 @@ static umf_result_t devdax_close_ipc_handle(void *provider, void *ptr,
498492
return UMF_RESULT_ERROR_INVALID_ARGUMENT;
499493
}
500494

501-
devdax_memory_provider_t *devdax_provider =
502-
(devdax_memory_provider_t *)provider;
495+
// get the page size
496+
size_t page_size;
497+
(void)devdax_get_recommended_page_size(provider, size, &page_size);
498+
499+
// ptr and size passed to munmap() have to be page-aligned in case of /dev/dax device
500+
utils_align_ptr_down_size_up(&ptr, &size, page_size);
503501

504502
errno = 0;
505-
int ret = utils_munmap(devdax_provider->base, devdax_provider->size);
503+
int ret = utils_munmap(ptr, size);
506504
// ignore error when size == 0
507505
if (ret && (size > 0)) {
508506
devdax_store_last_native_error(UMF_DEVDAX_RESULT_ERROR_FREE_FAILED,

0 commit comments

Comments
 (0)