Skip to content

Commit 822250e

Browse files
authored
Merge pull request #294 from kswiecicki/mem-policy-fail
Fix OOM test for HOST ALL memspace
2 parents 9097d91 + 8487a2f commit 822250e

File tree

3 files changed

+68
-26
lines changed

3 files changed

+68
-26
lines changed

test/CMakeLists.txt

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -135,22 +135,22 @@ if(UMF_BUILD_OS_MEMORY_PROVIDER AND LINUX) # OS-specific functions are implement
135135
LIBS umf_utils ${LIBNUMA_LIBRARIES})
136136
add_umf_test(NAME memspace_host_all
137137
SRCS memspaces/memspace_host_all.cpp
138-
LIBS ${LIBNUMA_LIBRARIES})
138+
LIBS umf_utils ${LIBNUMA_LIBRARIES})
139139
endif()
140140

141141
# TODO add support for Windows
142142
if(UMF_BUILD_LEVEL_ZERO_PROVIDER AND LINUX)
143-
# we have two test binaries here that use the same sources, but differ in
144-
# the way they are linked to the Level Zero (statically or at runtime using
143+
# we have two test binaries here that use the same sources, but differ in
144+
# the way they are linked to the Level Zero (statically or at runtime using
145145
# dlopen)
146146
add_umf_test(NAME provider_level_zero
147147
SRCS providers/provider_level_zero.cpp
148148
LIBS umf_utils ze_loader)
149-
149+
150150
add_umf_test(NAME provider_level_zero_dlopen
151151
SRCS providers/provider_level_zero.cpp
152152
LIBS umf_utils)
153-
target_compile_definitions(umf_test-provider_level_zero_dlopen
153+
target_compile_definitions(umf_test-provider_level_zero_dlopen
154154
PUBLIC USE_DLOPEN=1)
155155
endif()
156156

test/memspaces/memspace_host_all.cpp

Lines changed: 42 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#include "memspace_helpers.hpp"
77
#include "memspace_internal.h"
88
#include "test_helpers.h"
9+
#include "utils_sanitizers.h"
910

1011
#include <numa.h>
1112
#include <numaif.h>
@@ -96,39 +97,53 @@ static void getAllocationPolicy(void *ptr, unsigned long maxNodeId, int &mode,
9697
allocNodeId = static_cast<size_t>(nodeId);
9798
}
9899

99-
TEST_F(memspaceHostAllProviderTest, memoryPolicyOOM) {
100+
TEST_F(memspaceHostAllProviderTest, allocsSpreadAcrossAllNumaNodes) {
101+
// This testcase is unsuitable for TSan.
102+
#ifdef __SANITIZE_THREAD__
103+
GTEST_SKIP();
104+
#endif
105+
100106
// Arbitrary allocation size, should be big enough to avoid unnecessarily
101107
// prolonging the test execution.
102-
size_t size = SIZE_4M * 128;
108+
size_t size = SIZE_4M;
103109
size_t alignment = 0;
104-
std::vector<void *> allocs;
105110

106-
enum umf_result_t umf_ret = UMF_RESULT_SUCCESS;
107-
// Create allocations until OOM.
108-
while (true) {
111+
long long numaCombinedFreeSize = 0;
112+
// Gather free size of all numa nodes.
113+
for (auto &id : nodeIds) {
114+
long long numaFreeSize = 0;
115+
long long numaSize = numa_node_size64(id, &numaFreeSize);
116+
UT_ASSERTne(numaSize, -1);
117+
// We need the space for at least two allocations, so that we can
118+
// have some space left to avoid OOM killer.
119+
UT_ASSERT(numaFreeSize >= (long long)(2 * size));
120+
121+
numaCombinedFreeSize += numaFreeSize;
122+
}
123+
124+
umf_result_t umf_ret = UMF_RESULT_SUCCESS;
125+
// Create allocations until all the NUMA nodes until there's space only for
126+
// one allocation.
127+
std::vector<void *> allocs;
128+
std::unordered_set<size_t> allocNodeIds;
129+
while (numaCombinedFreeSize >= (long long)(2 * size)) {
109130
void *ptr = nullptr;
110131
umf_ret = umfMemoryProviderAlloc(hProvider, size, alignment, &ptr);
111132
if (umf_ret != UMF_RESULT_SUCCESS) {
133+
UT_ASSERTeq(umf_ret, UMF_RESULT_ERROR_MEMORY_PROVIDER_SPECIFIC);
134+
const char *msg = nullptr;
135+
int32_t err = 0;
136+
umfMemoryProviderGetLastNativeError(hProvider, &msg, &err);
137+
// In this scenario, 'UMF_OS_RESULT_ERROR_ALLOC_FAILED' indicates OOM.
138+
UT_ASSERTeq(err, UMF_OS_RESULT_ERROR_ALLOC_FAILED);
112139
break;
113140
}
114141

115142
UT_ASSERTne(ptr, nullptr);
116-
allocs.push_back(ptr);
117-
}
143+
// Access the allocation, so that all the pages associated with it are
144+
// allocated on available NUMA nodes.
145+
memset(ptr, 0xFF, size);
118146

119-
UT_ASSERTeq(umf_ret, UMF_RESULT_ERROR_MEMORY_PROVIDER_SPECIFIC);
120-
const char *msg = nullptr;
121-
int32_t err = 0;
122-
umfMemoryProviderGetLastNativeError(hProvider, &msg, &err);
123-
// In this scenario, 'UMF_OS_RESULT_ERROR_ALLOC_FAILED' indicates OOM.
124-
UT_ASSERTeq(err, UMF_OS_RESULT_ERROR_ALLOC_FAILED);
125-
126-
// When allocating until OOM, the allocations should be distributed across
127-
// all the NUMA nodes bound to 'HOST ALL' memspace, until each node runs
128-
// out of memory.
129-
UT_ASSERT(allocs.size() >= nodeIds.size());
130-
std::unordered_set<size_t> allocNodeIds;
131-
for (auto &ptr : allocs) {
132147
int mode = -1;
133148
std::vector<size_t> boundNodeIds;
134149
size_t allocNodeId = SIZE_MAX;
@@ -151,8 +166,14 @@ TEST_F(memspaceHostAllProviderTest, memoryPolicyOOM) {
151166
auto it = std::find(nodeIds.begin(), nodeIds.end(), allocNodeId);
152167
UT_ASSERT(it != nodeIds.end());
153168

169+
allocs.push_back(ptr);
154170
allocNodeIds.insert(allocNodeId);
155171

172+
numaCombinedFreeSize -= size;
173+
}
174+
175+
UT_ASSERT(allocs.size() >= nodeIds.size());
176+
for (auto &ptr : allocs) {
156177
umf_ret = umfMemoryProviderFree(hProvider, ptr, size);
157178
UT_ASSERTeq(umf_ret, UMF_RESULT_SUCCESS);
158179
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
{
2+
4,608 bytes in 2 blocks are possibly lost in loss record 242 of 246
3+
Memcheck:Leak
4+
match-leak-kinds: possible
5+
fun:malloc
6+
fun:malloc
7+
fun:_dlfo_mappings_segment_allocate
8+
fun:_dl_find_object_update_1
9+
fun:_dl_find_object_update
10+
fun:dl_open_worker_begin
11+
fun:_dl_catch_exception
12+
fun:dl_open_worker
13+
fun:_dl_catch_exception
14+
fun:_dl_open
15+
fun:dlopen_doit
16+
fun:_dl_catch_exception
17+
fun:_dl_catch_error
18+
fun:_dlerror_run
19+
fun:dlopen_implementation
20+
fun:dlopen@@GLIBC_*
21+
}

0 commit comments

Comments
 (0)