6
6
7
7
#include < numa.h>
8
8
#include < numaif.h>
9
+ #include < sched.h>
9
10
11
+ #include " test_helpers.h"
10
12
#include < umf/providers/provider_os_memory.h>
11
13
12
14
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() {
28
30
return available_numa_nodes_numbers;
29
31
}
30
32
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 {
32
44
void SetUp () override {
33
45
if (numa_available () == -1 ) {
34
46
GTEST_SKIP () << " Test skipped, NUMA not available" ;
@@ -56,10 +68,22 @@ struct testNumaNodes : public testing::TestWithParam<int> {
56
68
int numa_node;
57
69
int ret = get_mempolicy (&numa_node, nullptr , 0 , addr,
58
70
MPOL_F_NODE | MPOL_F_ADDR);
59
- EXPECT_EQ (ret, 0 );
71
+ UT_ASSERTeq (ret, 0 );
60
72
return numa_node;
61
73
}
62
74
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
+
63
87
void TearDown () override {
64
88
umf_result_t umf_result;
65
89
if (ptr) {
@@ -82,14 +106,16 @@ struct testNumaNodes : public testing::TestWithParam<int> {
82
106
umf_memory_provider_handle_t os_memory_provider = nullptr ;
83
107
};
84
108
109
+ struct testNumaOnAllNodes : testNuma, testing::WithParamInterface<int > {};
110
+
85
111
INSTANTIATE_TEST_SUITE_P (
86
- testNumaNodesAllocations, testNumaNodes ,
112
+ testNumaNodesAllocations, testNumaOnAllNodes ,
87
113
::testing::ValuesIn (get_available_numa_nodes_numbers()));
88
114
89
115
// Test for allocations on numa nodes. This test will be executed for all numa nodes
90
116
// available on the system. The available nodes are returned in vector from the
91
117
// get_available_numa_nodes_numbers() function and passed to test as parameters.
92
- TEST_P (testNumaNodes , checkNumaNodesAllocations) {
118
+ TEST_P (testNumaOnAllNodes , checkNumaNodesAllocations) {
93
119
int numa_node_number = GetParam ();
94
120
umf_os_memory_provider_params_t os_memory_provider_params =
95
121
UMF_OS_MEMORY_PROVIDER_PARAMS_TEST;
@@ -111,3 +137,99 @@ TEST_P(testNumaNodes, checkNumaNodesAllocations) {
111
137
int retrieved_numa_node_number = retrieve_numa_node_number (ptr);
112
138
ASSERT_EQ (retrieved_numa_node_number, numa_node_number);
113
139
}
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