@@ -31,7 +31,7 @@ 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+ #define DEVDAX_PAGE_SIZE_2MB ((size_t)(2 * 1024 * 1024)) // == 2 MB
3535
3636#define TLS_MSG_BUF_LEN 1024
3737
@@ -228,15 +228,20 @@ static umf_result_t devdax_alloc(void *provider, size_t size, size_t alignment,
228228 return UMF_RESULT_ERROR_INVALID_ARGUMENT ;
229229 }
230230
231- // alignment must be a power of two and a multiple of sizeof(void *)
232- if (alignment &&
233- ((alignment & (alignment - 1 )) || (alignment % sizeof (void * )))) {
234- LOG_ERR ("wrong alignment: %zu (not a power of 2 or a multiple of "
235- "sizeof(void *))" ,
236- alignment );
231+ // alignment must be a power of two and a multiple or a divider of the page size
232+ if (alignment && ((alignment & (alignment - 1 )) ||
233+ ((alignment % DEVDAX_PAGE_SIZE_2MB ) &&
234+ (DEVDAX_PAGE_SIZE_2MB % alignment )))) {
235+ LOG_ERR ("wrong alignment: %zu (not a power of 2 or a multiple or a "
236+ "divider of the page size (%zu))" ,
237+ alignment , DEVDAX_PAGE_SIZE_2MB );
237238 return UMF_RESULT_ERROR_INVALID_ARGUMENT ;
238239 }
239240
241+ if (IS_NOT_ALIGNED (alignment , DEVDAX_PAGE_SIZE_2MB )) {
242+ alignment = ALIGN_UP (alignment , DEVDAX_PAGE_SIZE_2MB );
243+ }
244+
240245 devdax_memory_provider_t * devdax_provider =
241246 (devdax_memory_provider_t * )provider ;
242247
@@ -300,7 +305,7 @@ static umf_result_t devdax_get_recommended_page_size(void *provider,
300305 return UMF_RESULT_ERROR_INVALID_ARGUMENT ;
301306 }
302307
303- * page_size = utils_get_page_size () ;
308+ * page_size = DEVDAX_PAGE_SIZE_2MB ;
304309
305310 return UMF_RESULT_SUCCESS ;
306311}
@@ -369,9 +374,11 @@ static umf_result_t devdax_allocation_merge(void *provider, void *lowPtr,
369374}
370375
371376typedef 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
377+ char path [PATH_MAX ]; // path to the /dev/dax
378+ unsigned protection ; // combination of OS-specific memory protection flags
379+ // offset of the data (from the beginning of the devdax mapping) - see devdax_get_ipc_handle()
380+ size_t offset ;
381+ size_t length ; // length of the data
375382} devdax_ipc_data_t ;
376383
377384static umf_result_t devdax_get_ipc_handle_size (void * provider , size_t * size ) {
@@ -386,8 +393,6 @@ static umf_result_t devdax_get_ipc_handle_size(void *provider, size_t *size) {
386393
387394static umf_result_t devdax_get_ipc_handle (void * provider , const void * ptr ,
388395 size_t size , void * providerIpcData ) {
389- (void )size ; // unused
390-
391396 if (provider == NULL || ptr == NULL || providerIpcData == NULL ) {
392397 return UMF_RESULT_ERROR_INVALID_ARGUMENT ;
393398 }
@@ -396,11 +401,12 @@ static umf_result_t devdax_get_ipc_handle(void *provider, const void *ptr,
396401 (devdax_memory_provider_t * )provider ;
397402
398403 devdax_ipc_data_t * devdax_ipc_data = (devdax_ipc_data_t * )providerIpcData ;
404+ strncpy (devdax_ipc_data -> path , devdax_provider -> path , PATH_MAX - 1 );
405+ devdax_ipc_data -> path [PATH_MAX - 1 ] = '\0' ;
406+ devdax_ipc_data -> protection = devdax_provider -> protection ;
399407 devdax_ipc_data -> offset =
400408 (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 ;
409+ devdax_ipc_data -> length = size ;
404410
405411 return UMF_RESULT_SUCCESS ;
406412}
@@ -416,16 +422,9 @@ static umf_result_t devdax_put_ipc_handle(void *provider,
416422 devdax_ipc_data_t * devdax_ipc_data = (devdax_ipc_data_t * )providerIpcData ;
417423
418424 // verify the path of the /dev/dax
419- if (strncmp (devdax_ipc_data -> dd_path , devdax_provider -> path , PATH_MAX )) {
425+ if (strncmp (devdax_ipc_data -> path , devdax_provider -> path , PATH_MAX )) {
420426 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 );
427+ devdax_provider -> path , devdax_ipc_data -> path );
429428 return UMF_RESULT_ERROR_INVALID_ARGUMENT ;
430429 }
431430
@@ -438,58 +437,54 @@ static umf_result_t devdax_open_ipc_handle(void *provider,
438437 return UMF_RESULT_ERROR_INVALID_ARGUMENT ;
439438 }
440439
441- devdax_memory_provider_t * devdax_provider =
442- (devdax_memory_provider_t * )provider ;
443440 devdax_ipc_data_t * devdax_ipc_data = (devdax_ipc_data_t * )providerIpcData ;
444441
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 );
442+ int fd = utils_devdax_open (devdax_ipc_data -> path );
461443 if (fd == -1 ) {
462- LOG_PERR ("opening a devdax (%s) failed" , devdax_provider -> path );
444+ LOG_PERR ("opening the devdax (%s) failed" , devdax_ipc_data -> path );
463445 return UMF_RESULT_ERROR_INVALID_ARGUMENT ;
464446 }
465447
466448 unsigned map_sync_flag = 0 ;
467449 utils_translate_mem_visibility_flag (UMF_MEM_MAP_SYNC , & map_sync_flag );
468450
451+ // It is just a workaround for case when
452+ // devdax_alloc() was called with the size argument
453+ // that is not a multiplier of DEVDAX_PAGE_SIZE_2MB.
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+ DEVDAX_PAGE_SIZE_2MB );
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 );
466+
476467 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 ;
468+ "fd: %i, offset: %zu)" ,
469+ devdax_ipc_data -> path , length_aligned ,
470+ devdax_ipc_data -> protection , fd , offset_aligned );
471+
472+ * ptr = NULL ;
473+ (void )utils_close_fd (fd );
474+
475+ return UMF_RESULT_ERROR_MEMORY_PROVIDER_SPECIFIC ;
481476 }
482477
483478 LOG_DEBUG ("devdax mapped (path: %s, size: %zu, protection: %i, fd: %i, "
484- "offset: %zu)" ,
485- devdax_provider -> path , devdax_provider -> size ,
486- devdax_provider -> protection , fd , devdax_ipc_data -> offset );
479+ "offset: %zu) to address %p " ,
480+ devdax_ipc_data -> path , length_aligned ,
481+ devdax_ipc_data -> protection , fd , offset_aligned , addr );
487482
488- ( void ) utils_close_fd ( fd ) ;
483+ * ptr = addr ;
489484
490- * ptr = base + devdax_ipc_data -> offset ;
485+ ( void ) utils_close_fd ( fd ) ;
491486
492- return ret ;
487+ return UMF_RESULT_SUCCESS ;
493488}
494489
495490static umf_result_t devdax_close_ipc_handle (void * provider , void * ptr ,
@@ -498,16 +493,15 @@ static umf_result_t devdax_close_ipc_handle(void *provider, void *ptr,
498493 return UMF_RESULT_ERROR_INVALID_ARGUMENT ;
499494 }
500495
501- devdax_memory_provider_t * devdax_provider =
502- (devdax_memory_provider_t * )provider ;
496+ size = ALIGN_UP (size , DEVDAX_PAGE_SIZE_2MB );
503497
504498 errno = 0 ;
505- int ret = utils_munmap (devdax_provider -> base , devdax_provider -> size );
499+ int ret = utils_munmap (ptr , size );
506500 // ignore error when size == 0
507501 if (ret && (size > 0 )) {
508502 devdax_store_last_native_error (UMF_DEVDAX_RESULT_ERROR_FREE_FAILED ,
509503 errno );
510- LOG_PERR ("memory unmapping failed" );
504+ LOG_PERR ("memory unmapping failed (ptr: %p, size: %zu)" , ptr , size );
511505
512506 return UMF_RESULT_ERROR_MEMORY_PROVIDER_SPECIFIC ;
513507 }
0 commit comments