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 ;
@@ -388,13 +465,22 @@ static umf_result_t devdax_get_ipc_handle_size(void *provider, size_t *size) {
388
465
389
466
static umf_result_t devdax_get_ipc_handle (void * provider , const void * ptr ,
390
467
size_t size , void * providerIpcData ) {
391
- if (provider == NULL || ptr == NULL || providerIpcData == NULL ) {
468
+ if (provider == NULL ) {
392
469
return UMF_RESULT_ERROR_INVALID_ARGUMENT ;
393
470
}
394
471
395
472
devdax_memory_provider_t * devdax_provider =
396
473
(devdax_memory_provider_t * )provider ;
397
474
475
+ if (devdax_provider -> ipc_consumer_only_mode ) {
476
+ LOG_ERR ("devdax provider is working in the IPC-consumer-only mode" );
477
+ return UMF_RESULT_ERROR_NOT_SUPPORTED ;
478
+ }
479
+
480
+ if (ptr == NULL || providerIpcData == NULL ) {
481
+ return UMF_RESULT_ERROR_INVALID_ARGUMENT ;
482
+ }
483
+
398
484
devdax_ipc_data_t * devdax_ipc_data = (devdax_ipc_data_t * )providerIpcData ;
399
485
strncpy (devdax_ipc_data -> path , devdax_provider -> path , PATH_MAX - 1 );
400
486
devdax_ipc_data -> path [PATH_MAX - 1 ] = '\0' ;
@@ -408,12 +494,22 @@ static umf_result_t devdax_get_ipc_handle(void *provider, const void *ptr,
408
494
409
495
static umf_result_t devdax_put_ipc_handle (void * provider ,
410
496
void * providerIpcData ) {
411
- if (provider == NULL || providerIpcData == NULL ) {
497
+ if (provider == NULL ) {
412
498
return UMF_RESULT_ERROR_INVALID_ARGUMENT ;
413
499
}
414
500
415
501
devdax_memory_provider_t * devdax_provider =
416
502
(devdax_memory_provider_t * )provider ;
503
+
504
+ if (devdax_provider -> ipc_consumer_only_mode ) {
505
+ LOG_ERR ("devdax provider is working in the IPC-consumer-only mode" );
506
+ return UMF_RESULT_ERROR_NOT_SUPPORTED ;
507
+ }
508
+
509
+ if (providerIpcData == NULL ) {
510
+ return UMF_RESULT_ERROR_INVALID_ARGUMENT ;
511
+ }
512
+
417
513
devdax_ipc_data_t * devdax_ipc_data = (devdax_ipc_data_t * )providerIpcData ;
418
514
419
515
// verify the path of the /dev/dax
0 commit comments