Skip to content

Commit e6201b5

Browse files
author
Damian Duy
committed
Add OS provider tests for different bind modes
1 parent 085e4ba commit e6201b5

File tree

1 file changed

+126
-4
lines changed

1 file changed

+126
-4
lines changed

test/provider_os_memory_multiple_numa_nodes.cpp

Lines changed: 126 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,9 @@
66

77
#include <numa.h>
88
#include <numaif.h>
9+
#include <sched.h>
910

11+
#include "test_helpers.h"
1012
#include <umf/providers/provider_os_memory.h>
1113

1214
static umf_os_memory_provider_params_t UMF_OS_MEMORY_PROVIDER_PARAMS_TEST =
@@ -28,7 +30,17 @@ std::vector<int> get_available_numa_nodes_numbers() {
2830
return available_numa_nodes_numbers;
2931
}
3032

31-
struct testNumaNodes : public testing::TestWithParam<int> {
33+
void set_all_available_nodemask_bits(bitmask *nodemask) {
34+
UT_ASSERTne(numa_available(), -1);
35+
UT_ASSERTne(numa_all_nodes_ptr, nullptr);
36+
37+
numa_bitmask_clearall(nodemask);
38+
39+
// Set all available NUMA nodes numbers.
40+
copy_bitmask_to_bitmask(numa_all_nodes_ptr, nodemask);
41+
}
42+
43+
struct testNuma : testing::Test {
3244
void SetUp() override {
3345
if (numa_available() == -1) {
3446
GTEST_SKIP() << "Test skipped, NUMA not available";
@@ -56,10 +68,22 @@ struct testNumaNodes : public testing::TestWithParam<int> {
5668
int numa_node;
5769
int ret = get_mempolicy(&numa_node, nullptr, 0, addr,
5870
MPOL_F_NODE | MPOL_F_ADDR);
59-
EXPECT_EQ(ret, 0);
71+
UT_ASSERTeq(ret, 0);
6072
return numa_node;
6173
}
6274

75+
long unsigned int retrieve_nodemask(void *addr) {
76+
struct bitmask *retrieved_nodemask = numa_allocate_nodemask();
77+
UT_ASSERTne(nodemask, nullptr);
78+
int ret = get_mempolicy(nullptr, retrieved_nodemask->maskp,
79+
nodemask->size, addr, MPOL_F_ADDR);
80+
UT_ASSERTeq(ret, 0);
81+
long unsigned int retrieved_nodemask_value =
82+
*(retrieved_nodemask->maskp);
83+
numa_bitmask_free(retrieved_nodemask);
84+
return retrieved_nodemask_value;
85+
}
86+
6387
void TearDown() override {
6488
umf_result_t umf_result;
6589
if (ptr) {
@@ -82,14 +106,16 @@ struct testNumaNodes : public testing::TestWithParam<int> {
82106
umf_memory_provider_handle_t os_memory_provider = nullptr;
83107
};
84108

109+
struct testNumaOnAllNodes : testNuma, testing::WithParamInterface<int> {};
110+
85111
INSTANTIATE_TEST_SUITE_P(
86-
testNumaNodesAllocations, testNumaNodes,
112+
testNumaNodesAllocations, testNumaOnAllNodes,
87113
::testing::ValuesIn(get_available_numa_nodes_numbers()));
88114

89115
// Test for allocations on numa nodes. This test will be executed for all numa nodes
90116
// available on the system. The available nodes are returned in vector from the
91117
// get_available_numa_nodes_numbers() function and passed to test as parameters.
92-
TEST_P(testNumaNodes, checkNumaNodesAllocations) {
118+
TEST_P(testNumaOnAllNodes, checkNumaNodesAllocations) {
93119
int numa_node_number = GetParam();
94120
umf_os_memory_provider_params_t os_memory_provider_params =
95121
UMF_OS_MEMORY_PROVIDER_PARAMS_TEST;
@@ -111,3 +137,99 @@ TEST_P(testNumaNodes, checkNumaNodesAllocations) {
111137
int retrieved_numa_node_number = retrieve_numa_node_number(ptr);
112138
ASSERT_EQ(retrieved_numa_node_number, numa_node_number);
113139
}
140+
141+
// Test for allocations on numa nodes with mode preferred. It runs for all available
142+
// numa nodes obtained from the get_available_numa_nodes_numbers() function.
143+
TEST_P(testNumaOnAllNodes, checkModePreferred) {
144+
int numa_node_number = GetParam();
145+
umf_os_memory_provider_params_t os_memory_provider_params =
146+
UMF_OS_MEMORY_PROVIDER_PARAMS_TEST;
147+
os_memory_provider_params.maxnode = numa_node_number + 1;
148+
numa_bitmask_setbit(nodemask, numa_node_number);
149+
os_memory_provider_params.nodemask = nodemask->maskp;
150+
os_memory_provider_params.numa_mode = UMF_NUMA_MODE_PREFERRED;
151+
initOsProvider(os_memory_provider_params);
152+
153+
umf_result_t umf_result;
154+
umf_result =
155+
umfMemoryProviderAlloc(os_memory_provider, alloc_size, 0, &ptr);
156+
ASSERT_EQ(umf_result, UMF_RESULT_SUCCESS);
157+
ASSERT_NE(ptr, nullptr);
158+
159+
// This pointer must point to an initialized value before retrieving a number of
160+
// the numa node that the pointer was allocated on (calling get_mempolicy).
161+
memset(ptr, 0xFF, alloc_size);
162+
int retrieved_numa_node_number = retrieve_numa_node_number(ptr);
163+
ASSERT_EQ(retrieved_numa_node_number, numa_node_number);
164+
}
165+
166+
// Test for allocation on numa node with local mode enabled. The memory is
167+
// allocated on the node of the CPU that triggered the allocation.
168+
TEST_F(testNuma, checkModeLocal) {
169+
int cpu = sched_getcpu();
170+
int numa_node_number = numa_node_of_cpu(cpu);
171+
umf_os_memory_provider_params_t os_memory_provider_params =
172+
UMF_OS_MEMORY_PROVIDER_PARAMS_TEST;
173+
os_memory_provider_params.numa_mode = UMF_NUMA_MODE_LOCAL;
174+
initOsProvider(os_memory_provider_params);
175+
176+
umf_result_t umf_result;
177+
umf_result =
178+
umfMemoryProviderAlloc(os_memory_provider, alloc_size, 0, &ptr);
179+
ASSERT_EQ(umf_result, UMF_RESULT_SUCCESS);
180+
ASSERT_NE(ptr, nullptr);
181+
182+
// This pointer must point to an initialized value before retrieving a number of
183+
// the numa node that the pointer was allocated on (calling get_mempolicy).
184+
memset(ptr, 0xFF, alloc_size);
185+
int retrieved_numa_node_number = retrieve_numa_node_number(ptr);
186+
ASSERT_EQ(retrieved_numa_node_number, numa_node_number);
187+
}
188+
189+
// Test for allocation on numa node with default mode enabled.
190+
// Since no policy is set by the set_mempolicy function, it should
191+
// default to the system-wide default policy, which allocates pages
192+
// on the node of the CPU that triggers the allocation.
193+
TEST_F(testNuma, checkModeDefault) {
194+
int cpu = sched_getcpu();
195+
int numa_node_number = numa_node_of_cpu(cpu);
196+
umf_os_memory_provider_params_t os_memory_provider_params =
197+
UMF_OS_MEMORY_PROVIDER_PARAMS_TEST;
198+
initOsProvider(os_memory_provider_params);
199+
200+
umf_result_t umf_result;
201+
umf_result =
202+
umfMemoryProviderAlloc(os_memory_provider, alloc_size, 0, &ptr);
203+
ASSERT_EQ(umf_result, UMF_RESULT_SUCCESS);
204+
ASSERT_NE(ptr, nullptr);
205+
206+
// This pointer must point to an initialized value before retrieving a number of
207+
// the numa node that the pointer was allocated on (calling get_mempolicy).
208+
memset(ptr, 0xFF, alloc_size);
209+
int retrieved_numa_node_number = retrieve_numa_node_number(ptr);
210+
ASSERT_EQ(retrieved_numa_node_number, numa_node_number);
211+
}
212+
213+
// Test for allocations on numa nodes with interleave mode enabled.
214+
// The page allocations are interleaved across the set of nodes specified in nodemask.
215+
TEST_F(testNuma, checkModeInterleave) {
216+
umf_os_memory_provider_params_t os_memory_provider_params =
217+
UMF_OS_MEMORY_PROVIDER_PARAMS_TEST;
218+
os_memory_provider_params.maxnode = numa_max_node();
219+
set_all_available_nodemask_bits(nodemask);
220+
os_memory_provider_params.nodemask = nodemask->maskp;
221+
os_memory_provider_params.numa_mode = UMF_NUMA_MODE_INTERLEAVE;
222+
initOsProvider(os_memory_provider_params);
223+
224+
umf_result_t umf_result;
225+
umf_result =
226+
umfMemoryProviderAlloc(os_memory_provider, alloc_size, 0, &ptr);
227+
ASSERT_EQ(umf_result, UMF_RESULT_SUCCESS);
228+
ASSERT_NE(ptr, nullptr);
229+
230+
// This pointer must point to an initialized value before retrieving a number of
231+
// the numa node that the pointer was allocated on (calling get_mempolicy).
232+
memset(ptr, 0xFF, alloc_size);
233+
long unsigned int retrieved_nodemask_value = retrieve_nodemask(ptr);
234+
ASSERT_EQ(retrieved_nodemask_value, *(nodemask->maskp));
235+
}

0 commit comments

Comments
 (0)