8
8
#include <assert.h>
9
9
#include <errno.h>
10
10
#include <limits.h>
11
+ #include <stdbool.h>
11
12
#include <stddef.h>
12
13
#include <stdio.h>
13
14
#include <stdlib.h>
@@ -36,12 +37,13 @@ umf_memory_provider_ops_t *umfDevDaxMemoryProviderOps(void) {
36
37
#define TLS_MSG_BUF_LEN 1024
37
38
38
39
typedef 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
45
47
} devdax_memory_provider_t ;
46
48
47
49
typedef struct devdax_last_native_error_t {
@@ -104,13 +106,9 @@ static umf_result_t devdax_initialize(void *params, void **provider) {
104
106
umf_devdax_memory_provider_params_t * in_params =
105
107
(umf_devdax_memory_provider_params_t * )params ;
106
108
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" );
114
112
return UMF_RESULT_ERROR_INVALID_ARGUMENT ;
115
113
}
116
114
@@ -122,6 +120,36 @@ static umf_result_t devdax_initialize(void *params, void **provider) {
122
120
123
121
memset (devdax_provider , 0 , sizeof (* devdax_provider ));
124
122
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
+
125
153
ret = devdax_translate_params (in_params , devdax_provider );
126
154
if (ret != UMF_RESULT_SUCCESS ) {
127
155
goto err_free_devdax_provider ;
@@ -181,8 +209,12 @@ static void devdax_finalize(void *provider) {
181
209
}
182
210
183
211
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
+
186
218
umf_ba_global_free (devdax_provider );
187
219
}
188
220
@@ -224,7 +256,22 @@ static umf_result_t devdax_alloc(void *provider, size_t size, size_t alignment,
224
256
void * * resultPtr ) {
225
257
int ret ;
226
258
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 ) {
228
275
return UMF_RESULT_ERROR_INVALID_ARGUMENT ;
229
276
}
230
277
@@ -237,9 +284,6 @@ static umf_result_t devdax_alloc(void *provider, size_t size, size_t alignment,
237
284
return UMF_RESULT_ERROR_INVALID_ARGUMENT ;
238
285
}
239
286
240
- devdax_memory_provider_t * devdax_provider =
241
- (devdax_memory_provider_t * )provider ;
242
-
243
287
void * addr = NULL ;
244
288
errno = 0 ;
245
289
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) {
323
367
}
324
368
325
369
static 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 ) {
327
383
return UMF_RESULT_ERROR_INVALID_ARGUMENT ;
328
384
}
329
385
@@ -345,17 +401,38 @@ static const char *devdax_get_name(void *provider) {
345
401
static umf_result_t devdax_allocation_split (void * provider , void * ptr ,
346
402
size_t totalSize ,
347
403
size_t firstSize ) {
348
- (void )provider ;
349
404
(void )ptr ;
350
405
(void )totalSize ;
351
406
(void )firstSize ;
352
407
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
+
353
420
return UMF_RESULT_SUCCESS ;
354
421
}
355
422
356
423
static umf_result_t devdax_allocation_merge (void * provider , void * lowPtr ,
357
424
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
+ }
359
436
360
437
if ((uintptr_t )highPtr <= (uintptr_t )lowPtr ) {
361
438
return UMF_RESULT_ERROR_INVALID_ARGUMENT ;
@@ -387,13 +464,22 @@ static umf_result_t devdax_get_ipc_handle_size(void *provider, size_t *size) {
387
464
388
465
static umf_result_t devdax_get_ipc_handle (void * provider , const void * ptr ,
389
466
size_t size , void * providerIpcData ) {
390
- if (provider == NULL || ptr == NULL || providerIpcData == NULL ) {
467
+ if (provider == NULL ) {
391
468
return UMF_RESULT_ERROR_INVALID_ARGUMENT ;
392
469
}
393
470
394
471
devdax_memory_provider_t * devdax_provider =
395
472
(devdax_memory_provider_t * )provider ;
396
473
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
+
397
483
devdax_ipc_data_t * devdax_ipc_data = (devdax_ipc_data_t * )providerIpcData ;
398
484
strncpy (devdax_ipc_data -> path , devdax_provider -> path , PATH_MAX - 1 );
399
485
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,
407
493
408
494
static umf_result_t devdax_put_ipc_handle (void * provider ,
409
495
void * providerIpcData ) {
410
- if (provider == NULL || providerIpcData == NULL ) {
496
+ if (provider == NULL ) {
411
497
return UMF_RESULT_ERROR_INVALID_ARGUMENT ;
412
498
}
413
499
414
500
devdax_memory_provider_t * devdax_provider =
415
501
(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
+
416
512
devdax_ipc_data_t * devdax_ipc_data = (devdax_ipc_data_t * )providerIpcData ;
417
513
418
514
// verify the path of the /dev/dax
0 commit comments