Skip to content

Commit 882a4c8

Browse files
Merge pull request #883 from ldorau/Add_threshold_to_proxy_lib_to_call_system_allocator
Add threshold to proxy lib to call system allocator
2 parents 1f137a5 + 16ca017 commit 882a4c8

16 files changed

+477
-38
lines changed

.github/workflows/reusable_proxy_lib.yml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,15 @@ jobs:
7777
working-directory: ${{env.BUILD_DIR}}
7878
run: UMF_PROXY="page.disposition=shared-shm" LD_PRELOAD=./lib/libumf_proxy.so /usr/bin/date
7979

80+
# TODO enable the provider_file_memory_ipc test when the IPC tests with the proxy library are fixed
81+
# see the issue: https://github.com/oneapi-src/unified-memory-framework/issues/864
82+
- name: Run "ctest --output-on-failure" with proxy library and size.threshold=128
83+
working-directory: ${{env.BUILD_DIR}}
84+
run: >
85+
UMF_PROXY="page.disposition=shared-shm;size.threshold=128"
86+
LD_PRELOAD=./lib/libumf_proxy.so
87+
ctest --output-on-failure -E provider_file_memory_ipc
88+
8089
- name: Check coverage
8190
if: ${{ matrix.build_type == 'Debug' }}
8291
working-directory: ${{env.BUILD_DIR}}

README.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -317,6 +317,13 @@ The memory used by the proxy memory allocator is mmap'ed:
317317
- `page.disposition=shared-shm` - IPC uses the named shared memory. An SHM name is generated using the `umf_proxy_lib_shm_pid_$PID` pattern, where `$PID` is the PID of the process. It creates the `/dev/shm/umf_proxy_lib_shm_pid_$PID` file.
318318
- `page.disposition=shared-fd` - IPC uses the file descriptor duplication. It requires using `pidfd_getfd(2)` to obtain a duplicate of another process's file descriptor. Permission to duplicate another process's file descriptor is governed by a ptrace access mode `PTRACE_MODE_ATTACH_REALCREDS` check (see `ptrace(2)`) that can be changed using the `/proc/sys/kernel/yama/ptrace_scope` interface. `pidfd_getfd(2)` is supported since Linux 5.6.
319319

320+
**Size threshold**
321+
322+
The **size threshold** feature (Linux only) causes that all allocations of size less than the given threshold value go to the default system allocator instead of the proxy library.
323+
It can be enabled by adding the `size.threshold=<value>` string to the `UMF_PROXY` environment variable (with `';'` as a separator), for example: `UMF_PROXY="page.disposition=shared-shm;size.threshold=64"`.
324+
325+
**Remark:** changing a size of allocation (using `realloc()` ) does not change the allocator (`realloc(malloc(threshold - 1), threshold + 1)` still belongs to the default system allocator and `realloc(malloc(threshold + 1), threshold - 1)` still belongs to the proxy library pool allocator).
326+
320327
#### Windows
321328

322329
In case of Windows it requires:

src/base_alloc/base_alloc_global.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,8 @@ static void umf_ba_create_global(void) {
6767

6868
size_t smallestSize = BASE_ALLOC.ac_sizes[0];
6969
BASE_ALLOC.smallest_ac_size_log2 = log2Utils(smallestSize);
70+
71+
LOG_DEBUG("UMF base allocator created");
7072
}
7173

7274
// returns index of the allocation class for a given size

src/libumf.c

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include "ipc_cache.h"
1414
#include "memspace_internal.h"
1515
#include "provider_tracking.h"
16+
#include "utils_common.h"
1617
#include "utils_log.h"
1718
#if !defined(UMF_NO_HWLOC)
1819
#include "topology.h"
@@ -30,11 +31,20 @@ int umfInit(void) {
3031
LOG_ERR("Failed to create memory tracker");
3132
return -1;
3233
}
34+
35+
LOG_DEBUG("UMF tracker created");
36+
3337
umf_result_t umf_result = umfIpcCacheGlobalInit();
3438
if (umf_result != UMF_RESULT_SUCCESS) {
3539
LOG_ERR("Failed to initialize IPC cache");
3640
return -1;
3741
}
42+
43+
LOG_DEBUG("UMF IPC cache initialized");
44+
}
45+
46+
if (TRACKER) {
47+
LOG_DEBUG("UMF library initialized");
3848
}
3949

4050
return 0;
@@ -50,12 +60,26 @@ void umfTearDown(void) {
5060
umfDestroyTopology();
5161
#endif
5262
umfIpcCacheGlobalTearDown();
63+
64+
if (utils_is_running_in_proxy_lib_with_size_threshold()) {
65+
// We cannot destroy the TRACKER nor the base allocator
66+
// when we are running in the proxy library with a size threshold,
67+
// because it could result in calling the system free()
68+
// with an invalid pointer and a segfault.
69+
goto fini_umfTearDown;
70+
}
71+
5372
// make sure TRACKER is not used after being destroyed
5473
umf_memory_tracker_handle_t t = TRACKER;
5574
TRACKER = NULL;
5675
umfMemoryTrackerDestroy(t);
76+
LOG_DEBUG("UMF tracker destroyed");
5777

5878
umf_ba_destroy_global();
79+
LOG_DEBUG("UMF base allocator destroyed");
80+
81+
fini_umfTearDown:
82+
LOG_DEBUG("UMF library finalized");
5983
}
6084
}
6185

src/provider/provider_cuda.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -470,6 +470,7 @@ static umf_result_t cu_memory_provider_open_ipc_handle(void *provider,
470470

471471
static umf_result_t
472472
cu_memory_provider_close_ipc_handle(void *provider, void *ptr, size_t size) {
473+
(void)provider;
473474
(void)size;
474475

475476
CUresult cu_result;

src/provider/provider_devdax_memory.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -326,6 +326,7 @@ static umf_result_t devdax_purge_lazy(void *provider, void *ptr, size_t size) {
326326
}
327327

328328
static umf_result_t devdax_purge_force(void *provider, void *ptr, size_t size) {
329+
(void)provider; // unused
329330
errno = 0;
330331
if (utils_purge(ptr, size, UMF_PURGE_FORCE)) {
331332
devdax_store_last_native_error(
@@ -410,6 +411,7 @@ static umf_result_t devdax_put_ipc_handle(void *provider,
410411

411412
static umf_result_t devdax_open_ipc_handle(void *provider,
412413
void *providerIpcData, void **ptr) {
414+
(void)provider; // unused
413415
*ptr = NULL;
414416

415417
devdax_ipc_data_t *devdax_ipc_data = (devdax_ipc_data_t *)providerIpcData;
@@ -469,6 +471,7 @@ static umf_result_t devdax_open_ipc_handle(void *provider,
469471

470472
static umf_result_t devdax_close_ipc_handle(void *provider, void *ptr,
471473
size_t size) {
474+
(void)provider; // unused
472475
size = ALIGN_UP(size, DEVDAX_PAGE_SIZE_2MB);
473476

474477
errno = 0;

src/provider/provider_tracking.c

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -106,16 +106,19 @@ umf_memory_pool_handle_t umfMemoryTrackerGetPool(const void *ptr) {
106106

107107
umf_result_t umfMemoryTrackerGetAllocInfo(const void *ptr,
108108
umf_alloc_info_t *pAllocInfo) {
109-
assert(ptr);
110109
assert(pAllocInfo);
111110

111+
if (ptr == NULL) {
112+
return UMF_RESULT_ERROR_INVALID_ARGUMENT;
113+
}
114+
112115
if (TRACKER == NULL) {
113-
LOG_ERR("tracker is not created");
116+
LOG_ERR("tracker does not exist");
114117
return UMF_RESULT_ERROR_NOT_SUPPORTED;
115118
}
116119

117120
if (TRACKER->map == NULL) {
118-
LOG_ERR("tracker's map is not created");
121+
LOG_ERR("tracker's map does not exist");
119122
return UMF_RESULT_ERROR_NOT_SUPPORTED;
120123
}
121124

@@ -124,9 +127,8 @@ umf_result_t umfMemoryTrackerGetAllocInfo(const void *ptr,
124127
int found = critnib_find(TRACKER->map, (uintptr_t)ptr, FIND_LE,
125128
(void *)&rkey, (void **)&rvalue);
126129
if (!found || (uintptr_t)ptr >= rkey + rvalue->size) {
127-
LOG_WARN("pointer %p not found in the "
128-
"tracker, TRACKER=%p",
129-
ptr, (void *)TRACKER);
130+
LOG_DEBUG("pointer %p not found in the tracker, TRACKER=%p", ptr,
131+
(void *)TRACKER);
130132
return UMF_RESULT_ERROR_INVALID_ARGUMENT;
131133
}
132134

0 commit comments

Comments
 (0)