88#include <assert.h>
99#include <errno.h>
1010#include <limits.h>
11+ #include <stdbool.h>
1112#include <stddef.h>
1213#include <stdio.h>
1314#include <stdlib.h>
@@ -36,12 +37,13 @@ umf_memory_provider_ops_t *umfDevDaxMemoryProviderOps(void) {
3637#define TLS_MSG_BUF_LEN 1024
3738
3839typedef struct devdax_memory_provider_t {
39- char path [PATH_MAX ]; // a path to the device DAX
40- size_t size ; // size of the file used for memory mapping
41- void * base ; // base address of memory mapping
42- size_t offset ; // offset in the file used for memory mapping
43- utils_mutex_t lock ; // lock of ptr and offset
44- unsigned protection ; // combination of OS-specific protection flags
40+ char path [PATH_MAX ]; // a path to the device DAX
41+ size_t size ; // size of the file used for memory mapping
42+ void * base ; // base address of memory mapping
43+ size_t offset ; // offset in the file used for memory mapping
44+ utils_mutex_t lock ; // lock of ptr and offset
45+ unsigned protection ; // combination of OS-specific protection flags
46+ bool ipc_consumer_only_mode ; // when path==NULL and size==0
4547} devdax_memory_provider_t ;
4648
4749typedef struct devdax_last_native_error_t {
@@ -104,13 +106,9 @@ static umf_result_t devdax_initialize(void *params, void **provider) {
104106 umf_devdax_memory_provider_params_t * in_params =
105107 (umf_devdax_memory_provider_params_t * )params ;
106108
107- if (in_params -> path == NULL ) {
108- LOG_ERR ("devdax path is missing" );
109- return UMF_RESULT_ERROR_INVALID_ARGUMENT ;
110- }
111-
112- if (in_params -> size == 0 ) {
113- LOG_ERR ("devdax size is 0" );
109+ if (!(!in_params -> path == !in_params -> size )) {
110+ LOG_ERR (
111+ "both path and size of the devdax have to be provided or both not" );
114112 return UMF_RESULT_ERROR_INVALID_ARGUMENT ;
115113 }
116114
@@ -122,6 +120,36 @@ static umf_result_t devdax_initialize(void *params, void **provider) {
122120
123121 memset (devdax_provider , 0 , sizeof (* devdax_provider ));
124122
123+ if (in_params -> path == NULL && in_params -> size == 0 ) {
124+ // IPC-consumer-only mode (limited functionality):
125+ //
126+ // Supported ops:
127+ // .initialize()
128+ // .finalize()
129+ // .get_last_native_error()
130+ // .get_recommended_page_size()
131+ // .get_min_page_size()
132+ // .get_name()
133+ // .ipc.get_ipc_handle_size()
134+ // .ipc.open_ipc_handle()
135+ // .ipc.close_ipc_handle()
136+ //
137+ // Unsupported ops (always return UMF_RESULT_ERROR_NOT_SUPPORTED):
138+ // .alloc()
139+ // .free() (as always unsupported)
140+ // .ext.purge_lazy() (as always unsupported)
141+ // .ext.purge_force()
142+ // .ext.allocation_split()
143+ // .ext.allocation_merge()
144+ // .ipc.get_ipc_handle()
145+ // .ipc.put_ipc_handle()
146+ devdax_provider -> ipc_consumer_only_mode = true;
147+ LOG_WARN ("devdax provider started in the IPC-consumer-only mode "
148+ "(limited functionality)" );
149+ * provider = devdax_provider ;
150+ return UMF_RESULT_SUCCESS ;
151+ }
152+
125153 ret = devdax_translate_params (in_params , devdax_provider );
126154 if (ret != UMF_RESULT_SUCCESS ) {
127155 goto err_free_devdax_provider ;
@@ -181,8 +209,12 @@ static void devdax_finalize(void *provider) {
181209 }
182210
183211 devdax_memory_provider_t * devdax_provider = provider ;
184- utils_mutex_destroy_not_free (& devdax_provider -> lock );
185- utils_munmap (devdax_provider -> base , devdax_provider -> size );
212+
213+ if (!devdax_provider -> ipc_consumer_only_mode ) {
214+ utils_mutex_destroy_not_free (& devdax_provider -> lock );
215+ utils_munmap (devdax_provider -> base , devdax_provider -> size );
216+ }
217+
186218 umf_ba_global_free (devdax_provider );
187219}
188220
@@ -224,7 +256,22 @@ static umf_result_t devdax_alloc(void *provider, size_t size, size_t alignment,
224256 void * * resultPtr ) {
225257 int ret ;
226258
227- if (provider == NULL || resultPtr == NULL ) {
259+ if (provider == NULL ) {
260+ return UMF_RESULT_ERROR_INVALID_ARGUMENT ;
261+ }
262+
263+ devdax_memory_provider_t * devdax_provider =
264+ (devdax_memory_provider_t * )provider ;
265+
266+ if (devdax_provider -> ipc_consumer_only_mode ) {
267+ LOG_ERR ("devdax provider is working in the IPC-consumer-only mode" );
268+ if (resultPtr ) {
269+ * resultPtr = NULL ;
270+ }
271+ return UMF_RESULT_ERROR_NOT_SUPPORTED ;
272+ }
273+
274+ if (resultPtr == NULL ) {
228275 return UMF_RESULT_ERROR_INVALID_ARGUMENT ;
229276 }
230277
@@ -237,9 +284,6 @@ static umf_result_t devdax_alloc(void *provider, size_t size, size_t alignment,
237284 return UMF_RESULT_ERROR_INVALID_ARGUMENT ;
238285 }
239286
240- devdax_memory_provider_t * devdax_provider =
241- (devdax_memory_provider_t * )provider ;
242-
243287 void * addr = NULL ;
244288 errno = 0 ;
245289 ret = devdax_alloc_aligned (size , alignment , devdax_provider -> base ,
@@ -323,7 +367,19 @@ static umf_result_t devdax_purge_lazy(void *provider, void *ptr, size_t size) {
323367}
324368
325369static umf_result_t devdax_purge_force (void * provider , void * ptr , size_t size ) {
326- if (provider == NULL || ptr == NULL ) {
370+ if (provider == NULL ) {
371+ return UMF_RESULT_ERROR_INVALID_ARGUMENT ;
372+ }
373+
374+ devdax_memory_provider_t * devdax_provider =
375+ (devdax_memory_provider_t * )provider ;
376+
377+ if (devdax_provider -> ipc_consumer_only_mode ) {
378+ LOG_ERR ("devdax provider is working in the IPC-consumer-only mode" );
379+ return UMF_RESULT_ERROR_NOT_SUPPORTED ;
380+ }
381+
382+ if (ptr == NULL ) {
327383 return UMF_RESULT_ERROR_INVALID_ARGUMENT ;
328384 }
329385
@@ -345,17 +401,38 @@ static const char *devdax_get_name(void *provider) {
345401static umf_result_t devdax_allocation_split (void * provider , void * ptr ,
346402 size_t totalSize ,
347403 size_t firstSize ) {
348- (void )provider ;
349404 (void )ptr ;
350405 (void )totalSize ;
351406 (void )firstSize ;
352407
408+ if (provider == NULL ) {
409+ return UMF_RESULT_ERROR_INVALID_ARGUMENT ;
410+ }
411+
412+ devdax_memory_provider_t * devdax_provider =
413+ (devdax_memory_provider_t * )provider ;
414+
415+ if (devdax_provider -> ipc_consumer_only_mode ) {
416+ LOG_ERR ("devdax provider is working in the IPC-consumer-only mode" );
417+ return UMF_RESULT_ERROR_NOT_SUPPORTED ;
418+ }
419+
353420 return UMF_RESULT_SUCCESS ;
354421}
355422
356423static umf_result_t devdax_allocation_merge (void * provider , void * lowPtr ,
357424 void * highPtr , size_t totalSize ) {
358- (void )provider ;
425+ if (provider == NULL ) {
426+ return UMF_RESULT_ERROR_INVALID_ARGUMENT ;
427+ }
428+
429+ devdax_memory_provider_t * devdax_provider =
430+ (devdax_memory_provider_t * )provider ;
431+
432+ if (devdax_provider -> ipc_consumer_only_mode ) {
433+ LOG_ERR ("devdax provider is working in the IPC-consumer-only mode" );
434+ return UMF_RESULT_ERROR_NOT_SUPPORTED ;
435+ }
359436
360437 if ((uintptr_t )highPtr <= (uintptr_t )lowPtr ) {
361438 return UMF_RESULT_ERROR_INVALID_ARGUMENT ;
@@ -387,13 +464,22 @@ static umf_result_t devdax_get_ipc_handle_size(void *provider, size_t *size) {
387464
388465static umf_result_t devdax_get_ipc_handle (void * provider , const void * ptr ,
389466 size_t size , void * providerIpcData ) {
390- if (provider == NULL || ptr == NULL || providerIpcData == NULL ) {
467+ if (provider == NULL ) {
391468 return UMF_RESULT_ERROR_INVALID_ARGUMENT ;
392469 }
393470
394471 devdax_memory_provider_t * devdax_provider =
395472 (devdax_memory_provider_t * )provider ;
396473
474+ if (devdax_provider -> ipc_consumer_only_mode ) {
475+ LOG_ERR ("devdax provider is working in the IPC-consumer-only mode" );
476+ return UMF_RESULT_ERROR_NOT_SUPPORTED ;
477+ }
478+
479+ if (ptr == NULL || providerIpcData == NULL ) {
480+ return UMF_RESULT_ERROR_INVALID_ARGUMENT ;
481+ }
482+
397483 devdax_ipc_data_t * devdax_ipc_data = (devdax_ipc_data_t * )providerIpcData ;
398484 strncpy (devdax_ipc_data -> path , devdax_provider -> path , PATH_MAX - 1 );
399485 devdax_ipc_data -> path [PATH_MAX - 1 ] = '\0' ;
@@ -407,12 +493,22 @@ static umf_result_t devdax_get_ipc_handle(void *provider, const void *ptr,
407493
408494static umf_result_t devdax_put_ipc_handle (void * provider ,
409495 void * providerIpcData ) {
410- if (provider == NULL || providerIpcData == NULL ) {
496+ if (provider == NULL ) {
411497 return UMF_RESULT_ERROR_INVALID_ARGUMENT ;
412498 }
413499
414500 devdax_memory_provider_t * devdax_provider =
415501 (devdax_memory_provider_t * )provider ;
502+
503+ if (devdax_provider -> ipc_consumer_only_mode ) {
504+ LOG_ERR ("devdax provider is working in the IPC-consumer-only mode" );
505+ return UMF_RESULT_ERROR_NOT_SUPPORTED ;
506+ }
507+
508+ if (providerIpcData == NULL ) {
509+ return UMF_RESULT_ERROR_INVALID_ARGUMENT ;
510+ }
511+
416512 devdax_ipc_data_t * devdax_ipc_data = (devdax_ipc_data_t * )providerIpcData ;
417513
418514 // verify the path of the /dev/dax
0 commit comments