@@ -58,6 +58,7 @@ umf_result_t umfDevDaxMemoryProviderParamsSetProtection(
58
58
#else // !defined(_WIN32) && !defined(UMF_NO_HWLOC)
59
59
60
60
#include "base_alloc_global.h"
61
+ #include "coarse.h"
61
62
#include "libumf.h"
62
63
#include "utils_common.h"
63
64
#include "utils_concurrency.h"
@@ -74,6 +75,7 @@ typedef struct devdax_memory_provider_t {
74
75
size_t offset ; // offset in the file used for memory mapping
75
76
utils_mutex_t lock ; // lock of ptr and offset
76
77
unsigned protection ; // combination of OS-specific protection flags
78
+ coarse_t * coarse ; // coarse library handle
77
79
} devdax_memory_provider_t ;
78
80
79
81
// DevDax Memory provider settings struct
@@ -133,6 +135,12 @@ devdax_translate_params(umf_devdax_memory_provider_params_t *in_params,
133
135
return UMF_RESULT_SUCCESS ;
134
136
}
135
137
138
+ static umf_result_t devdax_allocation_split_cb (void * provider , void * ptr ,
139
+ size_t totalSize ,
140
+ size_t firstSize );
141
+ static umf_result_t devdax_allocation_merge_cb (void * provider , void * lowPtr ,
142
+ void * highPtr , size_t totalSize );
143
+
136
144
static umf_result_t devdax_initialize (void * params , void * * provider ) {
137
145
umf_result_t ret ;
138
146
@@ -161,21 +169,42 @@ static umf_result_t devdax_initialize(void *params, void **provider) {
161
169
162
170
memset (devdax_provider , 0 , sizeof (* devdax_provider ));
163
171
164
- ret = devdax_translate_params (in_params , devdax_provider );
172
+ coarse_params_t coarse_params = {0 };
173
+ coarse_params .provider = devdax_provider ;
174
+ coarse_params .page_size = DEVDAX_PAGE_SIZE_2MB ;
175
+ // The alloc callback is not available in case of the devdax provider
176
+ // because it is a fixed-size memory provider
177
+ // and the entire devdax memory is added as a single block
178
+ // to the coarse library.
179
+ coarse_params .cb .alloc = NULL ;
180
+ coarse_params .cb .free = NULL ; // not available for the devdax provider
181
+ coarse_params .cb .split = devdax_allocation_split_cb ;
182
+ coarse_params .cb .merge = devdax_allocation_merge_cb ;
183
+
184
+ coarse_t * coarse = NULL ;
185
+ ret = coarse_new (& coarse_params , & coarse );
165
186
if (ret != UMF_RESULT_SUCCESS ) {
187
+ LOG_ERR ("coarse_new() failed" );
166
188
goto err_free_devdax_provider ;
167
189
}
168
190
191
+ devdax_provider -> coarse = coarse ;
192
+
193
+ ret = devdax_translate_params (in_params , devdax_provider );
194
+ if (ret != UMF_RESULT_SUCCESS ) {
195
+ goto err_coarse_delete ;
196
+ }
197
+
169
198
devdax_provider -> size = in_params -> size ;
170
199
if (utils_copy_path (in_params -> path , devdax_provider -> path , PATH_MAX )) {
171
- goto err_free_devdax_provider ;
200
+ goto err_coarse_delete ;
172
201
}
173
202
174
203
int fd = utils_devdax_open (in_params -> path );
175
204
if (fd == -1 ) {
176
205
LOG_ERR ("cannot open the device DAX: %s" , in_params -> path );
177
206
ret = UMF_RESULT_ERROR_INVALID_ARGUMENT ;
178
- goto err_free_devdax_provider ;
207
+ goto err_coarse_delete ;
179
208
}
180
209
181
210
bool is_dax = false;
@@ -189,23 +218,26 @@ static umf_result_t devdax_initialize(void *params, void **provider) {
189
218
LOG_PDEBUG ("mapping the devdax failed (path=%s, size=%zu)" ,
190
219
in_params -> path , devdax_provider -> size );
191
220
ret = UMF_RESULT_ERROR_UNKNOWN ;
192
- goto err_free_devdax_provider ;
221
+ goto err_coarse_delete ;
193
222
}
194
223
195
224
if (!is_dax ) {
196
225
LOG_ERR ("mapping the devdax with MAP_SYNC failed: %s" , in_params -> path );
197
226
ret = UMF_RESULT_ERROR_UNKNOWN ;
198
-
199
- if (devdax_provider -> base ) {
200
- utils_munmap (devdax_provider -> base , devdax_provider -> size );
201
- }
202
-
203
- goto err_free_devdax_provider ;
227
+ goto err_unmap_devdax ;
204
228
}
205
229
206
230
LOG_DEBUG ("devdax memory mapped (path=%s, size=%zu, addr=%p)" ,
207
231
in_params -> path , devdax_provider -> size , devdax_provider -> base );
208
232
233
+ // add the entire devdax memory as a single block
234
+ ret = coarse_add_memory_fixed (coarse , devdax_provider -> base ,
235
+ devdax_provider -> size );
236
+ if (ret != UMF_RESULT_SUCCESS ) {
237
+ LOG_ERR ("adding memory block failed" );
238
+ goto err_unmap_devdax ;
239
+ }
240
+
209
241
if (utils_mutex_init (& devdax_provider -> lock ) == NULL ) {
210
242
LOG_ERR ("lock init failed" );
211
243
ret = UMF_RESULT_ERROR_UNKNOWN ;
@@ -217,7 +249,11 @@ static umf_result_t devdax_initialize(void *params, void **provider) {
217
249
return UMF_RESULT_SUCCESS ;
218
250
219
251
err_unmap_devdax :
220
- utils_munmap (devdax_provider -> base , devdax_provider -> size );
252
+ if (devdax_provider -> base ) {
253
+ utils_munmap (devdax_provider -> base , devdax_provider -> size );
254
+ }
255
+ err_coarse_delete :
256
+ coarse_delete (devdax_provider -> coarse );
221
257
err_free_devdax_provider :
222
258
umf_ba_global_free (devdax_provider );
223
259
return ret ;
@@ -227,78 +263,15 @@ static void devdax_finalize(void *provider) {
227
263
devdax_memory_provider_t * devdax_provider = provider ;
228
264
utils_mutex_destroy_not_free (& devdax_provider -> lock );
229
265
utils_munmap (devdax_provider -> base , devdax_provider -> size );
266
+ coarse_delete (devdax_provider -> coarse );
230
267
umf_ba_global_free (devdax_provider );
231
268
}
232
269
233
- static int devdax_alloc_aligned (size_t length , size_t alignment , void * base ,
234
- size_t size , utils_mutex_t * lock ,
235
- void * * out_addr , size_t * offset ) {
236
- assert (out_addr );
237
-
238
- if (utils_mutex_lock (lock )) {
239
- LOG_ERR ("locking file offset failed" );
240
- return -1 ;
241
- }
242
-
243
- uintptr_t ptr = (uintptr_t )base + * offset ;
244
- uintptr_t rest_of_div = alignment ? (ptr % alignment ) : 0 ;
245
-
246
- if (alignment > 0 && rest_of_div > 0 ) {
247
- ptr += alignment - rest_of_div ;
248
- }
249
-
250
- size_t new_offset = ptr - (uintptr_t )base + length ;
251
-
252
- if (new_offset > size ) {
253
- utils_mutex_unlock (lock );
254
- LOG_ERR ("cannot allocate more memory than the device DAX size: %zu" ,
255
- size );
256
- return -1 ;
257
- }
258
-
259
- * offset = new_offset ;
260
- * out_addr = (void * )ptr ;
261
-
262
- utils_mutex_unlock (lock );
263
-
264
- return 0 ;
265
- }
266
-
267
270
static umf_result_t devdax_alloc (void * provider , size_t size , size_t alignment ,
268
271
void * * resultPtr ) {
269
- int ret ;
270
-
271
- // alignment must be a power of two and a multiple or a divider of the page size
272
- if (alignment && ((alignment & (alignment - 1 )) ||
273
- ((alignment % DEVDAX_PAGE_SIZE_2MB ) &&
274
- (DEVDAX_PAGE_SIZE_2MB % alignment )))) {
275
- LOG_ERR ("wrong alignment: %zu (not a power of 2 or a multiple or a "
276
- "divider of the page size (%zu))" ,
277
- alignment , DEVDAX_PAGE_SIZE_2MB );
278
- return UMF_RESULT_ERROR_INVALID_ARGUMENT ;
279
- }
280
-
281
- if (IS_NOT_ALIGNED (alignment , DEVDAX_PAGE_SIZE_2MB )) {
282
- alignment = ALIGN_UP (alignment , DEVDAX_PAGE_SIZE_2MB );
283
- }
284
-
285
272
devdax_memory_provider_t * devdax_provider =
286
273
(devdax_memory_provider_t * )provider ;
287
-
288
- void * addr = NULL ;
289
- errno = 0 ;
290
- ret = devdax_alloc_aligned (size , alignment , devdax_provider -> base ,
291
- devdax_provider -> size , & devdax_provider -> lock ,
292
- & addr , & devdax_provider -> offset );
293
- if (ret ) {
294
- devdax_store_last_native_error (UMF_DEVDAX_RESULT_ERROR_ALLOC_FAILED , 0 );
295
- LOG_ERR ("memory allocation failed" );
296
- return UMF_RESULT_ERROR_MEMORY_PROVIDER_SPECIFIC ;
297
- }
298
-
299
- * resultPtr = addr ;
300
-
301
- return UMF_RESULT_SUCCESS ;
274
+ return coarse_alloc (devdax_provider -> coarse , size , alignment , resultPtr );
302
275
}
303
276
304
277
static void devdax_get_last_native_error (void * provider , const char * * ppMessage ,
@@ -384,6 +357,14 @@ static const char *devdax_get_name(void *provider) {
384
357
static umf_result_t devdax_allocation_split (void * provider , void * ptr ,
385
358
size_t totalSize ,
386
359
size_t firstSize ) {
360
+ devdax_memory_provider_t * devdax_provider =
361
+ (devdax_memory_provider_t * )provider ;
362
+ return coarse_split (devdax_provider -> coarse , ptr , totalSize , firstSize );
363
+ }
364
+
365
+ static umf_result_t devdax_allocation_split_cb (void * provider , void * ptr ,
366
+ size_t totalSize ,
367
+ size_t firstSize ) {
387
368
(void )provider ;
388
369
(void )ptr ;
389
370
(void )totalSize ;
@@ -393,6 +374,14 @@ static umf_result_t devdax_allocation_split(void *provider, void *ptr,
393
374
394
375
static umf_result_t devdax_allocation_merge (void * provider , void * lowPtr ,
395
376
void * highPtr , size_t totalSize ) {
377
+ devdax_memory_provider_t * devdax_provider =
378
+ (devdax_memory_provider_t * )provider ;
379
+ return coarse_merge (devdax_provider -> coarse , lowPtr , highPtr , totalSize );
380
+ }
381
+
382
+ static umf_result_t devdax_allocation_merge_cb (void * provider , void * lowPtr ,
383
+ void * highPtr ,
384
+ size_t totalSize ) {
396
385
(void )provider ;
397
386
(void )lowPtr ;
398
387
(void )highPtr ;
@@ -527,6 +516,12 @@ static umf_result_t devdax_close_ipc_handle(void *provider, void *ptr,
527
516
return UMF_RESULT_SUCCESS ;
528
517
}
529
518
519
+ static umf_result_t devdax_free (void * provider , void * ptr , size_t size ) {
520
+ devdax_memory_provider_t * devdax_provider =
521
+ (devdax_memory_provider_t * )provider ;
522
+ return coarse_free (devdax_provider -> coarse , ptr , size );
523
+ }
524
+
530
525
static umf_memory_provider_ops_t UMF_DEVDAX_MEMORY_PROVIDER_OPS = {
531
526
.version = UMF_VERSION_CURRENT ,
532
527
.initialize = devdax_initialize ,
@@ -536,6 +531,7 @@ static umf_memory_provider_ops_t UMF_DEVDAX_MEMORY_PROVIDER_OPS = {
536
531
.get_recommended_page_size = devdax_get_recommended_page_size ,
537
532
.get_min_page_size = devdax_get_min_page_size ,
538
533
.get_name = devdax_get_name ,
534
+ .ext .free = devdax_free ,
539
535
.ext .purge_lazy = devdax_purge_lazy ,
540
536
.ext .purge_force = devdax_purge_force ,
541
537
.ext .allocation_merge = devdax_allocation_merge ,
0 commit comments