@@ -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+
136144static 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
219251err_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 );
221257err_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-
267270static 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
304277static void devdax_get_last_native_error (void * provider , const char * * ppMessage ,
@@ -384,6 +357,14 @@ static const char *devdax_get_name(void *provider) {
384357static 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
394375static 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 ;
0 commit comments