Skip to content

Commit fb53918

Browse files
authored
Merge pull request #932 from ldorau/Use_the_coarse_library
Use libcoarse in the file and the devdax providers
2 parents 27ee09f + d9f1fee commit fb53918

10 files changed

+177
-149
lines changed

src/provider/provider_devdax_memory.c

Lines changed: 72 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ umf_result_t umfDevDaxMemoryProviderParamsSetProtection(
5858
#else // !defined(_WIN32) && !defined(UMF_NO_HWLOC)
5959

6060
#include "base_alloc_global.h"
61+
#include "coarse.h"
6162
#include "libumf.h"
6263
#include "utils_common.h"
6364
#include "utils_concurrency.h"
@@ -74,6 +75,7 @@ typedef struct devdax_memory_provider_t {
7475
size_t offset; // offset in the file used for memory mapping
7576
utils_mutex_t lock; // lock of ptr and offset
7677
unsigned protection; // combination of OS-specific protection flags
78+
coarse_t *coarse; // coarse library handle
7779
} devdax_memory_provider_t;
7880

7981
// DevDax Memory provider settings struct
@@ -133,6 +135,12 @@ devdax_translate_params(umf_devdax_memory_provider_params_t *in_params,
133135
return UMF_RESULT_SUCCESS;
134136
}
135137

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+
136144
static umf_result_t devdax_initialize(void *params, void **provider) {
137145
umf_result_t ret;
138146

@@ -161,21 +169,42 @@ static umf_result_t devdax_initialize(void *params, void **provider) {
161169

162170
memset(devdax_provider, 0, sizeof(*devdax_provider));
163171

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);
165186
if (ret != UMF_RESULT_SUCCESS) {
187+
LOG_ERR("coarse_new() failed");
166188
goto err_free_devdax_provider;
167189
}
168190

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+
169198
devdax_provider->size = in_params->size;
170199
if (utils_copy_path(in_params->path, devdax_provider->path, PATH_MAX)) {
171-
goto err_free_devdax_provider;
200+
goto err_coarse_delete;
172201
}
173202

174203
int fd = utils_devdax_open(in_params->path);
175204
if (fd == -1) {
176205
LOG_ERR("cannot open the device DAX: %s", in_params->path);
177206
ret = UMF_RESULT_ERROR_INVALID_ARGUMENT;
178-
goto err_free_devdax_provider;
207+
goto err_coarse_delete;
179208
}
180209

181210
bool is_dax = false;
@@ -189,23 +218,26 @@ static umf_result_t devdax_initialize(void *params, void **provider) {
189218
LOG_PDEBUG("mapping the devdax failed (path=%s, size=%zu)",
190219
in_params->path, devdax_provider->size);
191220
ret = UMF_RESULT_ERROR_UNKNOWN;
192-
goto err_free_devdax_provider;
221+
goto err_coarse_delete;
193222
}
194223

195224
if (!is_dax) {
196225
LOG_ERR("mapping the devdax with MAP_SYNC failed: %s", in_params->path);
197226
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;
204228
}
205229

206230
LOG_DEBUG("devdax memory mapped (path=%s, size=%zu, addr=%p)",
207231
in_params->path, devdax_provider->size, devdax_provider->base);
208232

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+
209241
if (utils_mutex_init(&devdax_provider->lock) == NULL) {
210242
LOG_ERR("lock init failed");
211243
ret = UMF_RESULT_ERROR_UNKNOWN;
@@ -217,7 +249,11 @@ static umf_result_t devdax_initialize(void *params, void **provider) {
217249
return UMF_RESULT_SUCCESS;
218250

219251
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);
221257
err_free_devdax_provider:
222258
umf_ba_global_free(devdax_provider);
223259
return ret;
@@ -227,78 +263,15 @@ static void devdax_finalize(void *provider) {
227263
devdax_memory_provider_t *devdax_provider = provider;
228264
utils_mutex_destroy_not_free(&devdax_provider->lock);
229265
utils_munmap(devdax_provider->base, devdax_provider->size);
266+
coarse_delete(devdax_provider->coarse);
230267
umf_ba_global_free(devdax_provider);
231268
}
232269

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-
267270
static umf_result_t devdax_alloc(void *provider, size_t size, size_t alignment,
268271
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-
285272
devdax_memory_provider_t *devdax_provider =
286273
(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);
302275
}
303276

304277
static void devdax_get_last_native_error(void *provider, const char **ppMessage,
@@ -384,6 +357,14 @@ static const char *devdax_get_name(void *provider) {
384357
static umf_result_t devdax_allocation_split(void *provider, void *ptr,
385358
size_t totalSize,
386359
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) {
387368
(void)provider;
388369
(void)ptr;
389370
(void)totalSize;
@@ -393,6 +374,14 @@ static umf_result_t devdax_allocation_split(void *provider, void *ptr,
393374

394375
static umf_result_t devdax_allocation_merge(void *provider, void *lowPtr,
395376
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) {
396385
(void)provider;
397386
(void)lowPtr;
398387
(void)highPtr;
@@ -527,6 +516,12 @@ static umf_result_t devdax_close_ipc_handle(void *provider, void *ptr,
527516
return UMF_RESULT_SUCCESS;
528517
}
529518

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+
530525
static umf_memory_provider_ops_t UMF_DEVDAX_MEMORY_PROVIDER_OPS = {
531526
.version = UMF_VERSION_CURRENT,
532527
.initialize = devdax_initialize,
@@ -536,6 +531,7 @@ static umf_memory_provider_ops_t UMF_DEVDAX_MEMORY_PROVIDER_OPS = {
536531
.get_recommended_page_size = devdax_get_recommended_page_size,
537532
.get_min_page_size = devdax_get_min_page_size,
538533
.get_name = devdax_get_name,
534+
.ext.free = devdax_free,
539535
.ext.purge_lazy = devdax_purge_lazy,
540536
.ext.purge_force = devdax_purge_force,
541537
.ext.allocation_merge = devdax_allocation_merge,

src/provider/provider_file_memory.c

Lines changed: 57 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ umf_result_t umfFileMemoryProviderParamsSetVisibility(
6363
#else // !defined(_WIN32) && !defined(UMF_NO_HWLOC)
6464

6565
#include "base_alloc_global.h"
66+
#include "coarse.h"
6667
#include "critnib.h"
6768
#include "libumf.h"
6869
#include "utils_common.h"
@@ -101,6 +102,8 @@ typedef struct file_memory_provider_t {
101102
// It is needed mainly in the get_ipc_handle and open_ipc_handle hooks
102103
// to mmap a specific part of a file.
103104
critnib *fd_offset_map;
105+
106+
coarse_t *coarse; // coarse library handle
104107
} file_memory_provider_t;
105108

106109
// File Memory Provider settings struct
@@ -166,6 +169,14 @@ file_translate_params(umf_file_memory_provider_params_t *in_params,
166169
return UMF_RESULT_SUCCESS;
167170
}
168171

172+
static umf_result_t file_alloc_cb(void *provider, size_t size, size_t alignment,
173+
void **resultPtr);
174+
static umf_result_t file_allocation_split_cb(void *provider, void *ptr,
175+
size_t totalSize,
176+
size_t firstSize);
177+
static umf_result_t file_allocation_merge_cb(void *provider, void *lowPtr,
178+
void *highPtr, size_t totalSize);
179+
169180
static umf_result_t file_initialize(void *params, void **provider) {
170181
umf_result_t ret;
171182

@@ -233,10 +244,27 @@ static umf_result_t file_initialize(void *params, void **provider) {
233244
file_provider->page_size = utils_get_page_size();
234245
}
235246

247+
coarse_params_t coarse_params = {0};
248+
coarse_params.provider = file_provider;
249+
coarse_params.page_size = file_provider->page_size;
250+
coarse_params.cb.alloc = file_alloc_cb;
251+
coarse_params.cb.free = NULL; // not available for the file provider
252+
coarse_params.cb.split = file_allocation_split_cb;
253+
coarse_params.cb.merge = file_allocation_merge_cb;
254+
255+
coarse_t *coarse = NULL;
256+
ret = coarse_new(&coarse_params, &coarse);
257+
if (ret != UMF_RESULT_SUCCESS) {
258+
LOG_ERR("coarse_new() failed");
259+
goto err_close_fd;
260+
}
261+
262+
file_provider->coarse = coarse;
263+
236264
if (utils_mutex_init(&file_provider->lock) == NULL) {
237265
LOG_ERR("lock init failed");
238266
ret = UMF_RESULT_ERROR_UNKNOWN;
239-
goto err_close_fd;
267+
goto err_coarse_delete;
240268
}
241269

242270
file_provider->fd_offset_map = critnib_new();
@@ -261,6 +289,8 @@ static umf_result_t file_initialize(void *params, void **provider) {
261289
critnib_delete(file_provider->fd_offset_map);
262290
err_mutex_destroy_not_free:
263291
utils_mutex_destroy_not_free(&file_provider->lock);
292+
err_coarse_delete:
293+
coarse_delete(file_provider->coarse);
264294
err_close_fd:
265295
utils_close_fd(file_provider->fd);
266296
err_free_file_provider:
@@ -285,6 +315,7 @@ static void file_finalize(void *provider) {
285315
utils_close_fd(file_provider->fd);
286316
critnib_delete(file_provider->fd_offset_map);
287317
critnib_delete(file_provider->mmaps);
318+
coarse_delete(file_provider->coarse);
288319
umf_ba_global_free(file_provider);
289320
}
290321

@@ -443,6 +474,12 @@ static umf_result_t file_alloc_aligned(file_memory_provider_t *file_provider,
443474

444475
static umf_result_t file_alloc(void *provider, size_t size, size_t alignment,
445476
void **resultPtr) {
477+
file_memory_provider_t *file_provider = (file_memory_provider_t *)provider;
478+
return coarse_alloc(file_provider->coarse, size, alignment, resultPtr);
479+
}
480+
481+
static umf_result_t file_alloc_cb(void *provider, size_t size, size_t alignment,
482+
void **resultPtr) {
446483
umf_result_t umf_result;
447484
int ret;
448485

@@ -568,10 +605,15 @@ static const char *file_get_name(void *provider) {
568605
return "FILE";
569606
}
570607

571-
// This function is supposed to be thread-safe, so it should NOT be called concurrently
572-
// with file_allocation_merge() with the same pointer.
573608
static umf_result_t file_allocation_split(void *provider, void *ptr,
574609
size_t totalSize, size_t firstSize) {
610+
file_memory_provider_t *file_provider = (file_memory_provider_t *)provider;
611+
return coarse_split(file_provider->coarse, ptr, totalSize, firstSize);
612+
}
613+
614+
static umf_result_t file_allocation_split_cb(void *provider, void *ptr,
615+
size_t totalSize,
616+
size_t firstSize) {
575617
(void)totalSize;
576618

577619
file_memory_provider_t *file_provider = (file_memory_provider_t *)provider;
@@ -601,9 +643,14 @@ static umf_result_t file_allocation_split(void *provider, void *ptr,
601643
return UMF_RESULT_SUCCESS;
602644
}
603645

604-
// It should NOT be called concurrently with file_allocation_split() with the same pointer.
605646
static umf_result_t file_allocation_merge(void *provider, void *lowPtr,
606647
void *highPtr, size_t totalSize) {
648+
file_memory_provider_t *file_provider = (file_memory_provider_t *)provider;
649+
return coarse_merge(file_provider->coarse, lowPtr, highPtr, totalSize);
650+
}
651+
652+
static umf_result_t file_allocation_merge_cb(void *provider, void *lowPtr,
653+
void *highPtr, size_t totalSize) {
607654
(void)lowPtr;
608655
(void)totalSize;
609656

@@ -768,6 +815,11 @@ static umf_result_t file_close_ipc_handle(void *provider, void *ptr,
768815
return UMF_RESULT_SUCCESS;
769816
}
770817

818+
static umf_result_t file_free(void *provider, void *ptr, size_t size) {
819+
file_memory_provider_t *file_provider = (file_memory_provider_t *)provider;
820+
return coarse_free(file_provider->coarse, ptr, size);
821+
}
822+
771823
static umf_memory_provider_ops_t UMF_FILE_MEMORY_PROVIDER_OPS = {
772824
.version = UMF_VERSION_CURRENT,
773825
.initialize = file_initialize,
@@ -777,6 +829,7 @@ static umf_memory_provider_ops_t UMF_FILE_MEMORY_PROVIDER_OPS = {
777829
.get_recommended_page_size = file_get_recommended_page_size,
778830
.get_min_page_size = file_get_min_page_size,
779831
.get_name = file_get_name,
832+
.ext.free = file_free,
780833
.ext.purge_lazy = file_purge_lazy,
781834
.ext.purge_force = file_purge_force,
782835
.ext.allocation_merge = file_allocation_merge,

0 commit comments

Comments
 (0)