Skip to content

Commit 925bc8c

Browse files
committed
move_pages12: Make sure hugepages are available
This commit makes sure that enough huge pages are available on each node prior to the test. One problem we had is that there has to be at least four huge pages available in the per-node pools even though we only allocate two. One of the possibilities is that when we are moving pages back and forth between the nodes there may be some overlap when huge page is allocated on a node but the two huge pages there, that are about to be moved, are still there or at least accounted for. Hence we have to make sure that at least four huge pages are available prior to the test. The second problem is that huge page pools are limited by several files in the virtual filesystem. There is global knob for controlling the huge page pool size in /proc, then there are per-node knobs in /sys. The value written to the global knob is distributed evenly between the per-node knobs, hence on two node machine writing 8 to the global knob is sufficient to make sure there is enough huge pages for the test. But that does not work if the machine has three or more nodes. Hence this patch tries to adjust per-node pools on the nodes selected for the test and only if that is not possible we adjust the global knob and then make sure that expected number of huge pages could be allocated on each node. Signed-off-by: Cyril Hrubis <[email protected]> Signed-off-by: Jan Stancek <[email protected]>
1 parent 9109964 commit 925bc8c

File tree

1 file changed

+96
-7
lines changed

1 file changed

+96
-7
lines changed

testcases/kernel/syscalls/move_pages/move_pages12.c

Lines changed: 96 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
#include <errno.h>
3636
#include <unistd.h>
3737
#include <string.h>
38+
#include <stdio.h>
3839
#include <sys/types.h>
3940
#include <sys/wait.h>
4041

@@ -52,7 +53,11 @@
5253
#define TEST_NODES 2
5354

5455
static int pgsz, hpsz;
55-
static long orig_hugepages;
56+
static long orig_hugepages = -1;
57+
static char path_hugepages_node1[PATH_MAX];
58+
static char path_hugepages_node2[PATH_MAX];
59+
static long orig_hugepages_node1 = -1;
60+
static long orig_hugepages_node2 = -1;
5661
static unsigned int node1, node2;
5762
static void *addr;
5863

@@ -128,6 +133,45 @@ static void do_test(void)
128133
}
129134
}
130135

136+
static void alloc_free_huge_on_node(unsigned int node, size_t size)
137+
{
138+
char *mem;
139+
long ret;
140+
struct bitmask *bm;
141+
142+
tst_res(TINFO, "Allocating and freeing %zu hugepages on node %u",
143+
size / hpsz, node);
144+
145+
mem = mmap(NULL, size, PROT_READ | PROT_WRITE,
146+
MAP_PRIVATE | MAP_ANONYMOUS | MAP_HUGETLB, -1, 0);
147+
if (mem == MAP_FAILED) {
148+
if (errno == ENOMEM)
149+
tst_brk(TCONF, "Cannot allocate huge pages");
150+
151+
tst_brk(TBROK | TERRNO, "mmap(..., MAP_HUGETLB, ...) failed");
152+
}
153+
154+
bm = numa_bitmask_alloc(numa_max_possible_node() + 1);
155+
if (!bm)
156+
tst_brk(TBROK | TERRNO, "numa_bitmask_alloc() failed");
157+
158+
numa_bitmask_setbit(bm, node);
159+
160+
ret = mbind(mem, size, MPOL_BIND, bm->maskp, bm->size + 1, 0);
161+
if (ret) {
162+
if (errno == ENOMEM)
163+
tst_brk(TCONF, "Cannot mbind huge pages");
164+
165+
tst_brk(TBROK | TERRNO, "mbind() failed");
166+
}
167+
168+
numa_bitmask_free(bm);
169+
170+
memset(mem, 0, size);
171+
172+
SAFE_MUNMAP(mem, size);
173+
}
174+
131175
static void setup(void)
132176
{
133177
int memfree, ret;
@@ -137,6 +181,10 @@ static void setup(void)
137181
if (access(PATH_HUGEPAGES, F_OK))
138182
tst_brk(TCONF, "Huge page not supported");
139183

184+
ret = get_allowed_nodes(NH_MEMS, TEST_NODES, &node1, &node2);
185+
if (ret < 0)
186+
tst_brk(TBROK | TERRNO, "get_allowed_nodes: %d", ret);
187+
140188
pgsz = (int)get_page_size();
141189
SAFE_FILE_LINES_SCANF(PATH_MEMINFO, "Hugepagesize: %d", &hpsz);
142190

@@ -146,20 +194,61 @@ static void setup(void)
146194
if (4 * hpsz > memfree)
147195
tst_brk(TBROK, "Not enough free RAM");
148196

197+
snprintf(path_hugepages_node1, sizeof(path_hugepages_node1),
198+
"/sys/devices/system/node/node%u/hugepages/hugepages-%dkB/nr_hugepages",
199+
node1, hpsz);
200+
201+
snprintf(path_hugepages_node2, sizeof(path_hugepages_node2),
202+
"/sys/devices/system/node/node%u/hugepages/hugepages-%dkB/nr_hugepages",
203+
node2, hpsz);
204+
205+
if (!access(path_hugepages_node1, F_OK)) {
206+
SAFE_FILE_SCANF(path_hugepages_node1,
207+
"%ld", &orig_hugepages_node1);
208+
tst_res(TINFO,
209+
"Increasing %dkB hugepages pool on node %u to %ld",
210+
hpsz, node1, orig_hugepages_node1 + 4);
211+
SAFE_FILE_PRINTF(path_hugepages_node1,
212+
"%ld", orig_hugepages_node1 + 4);
213+
}
214+
215+
if (!access(path_hugepages_node2, F_OK)) {
216+
SAFE_FILE_SCANF(path_hugepages_node2,
217+
"%ld", &orig_hugepages_node2);
218+
tst_res(TINFO,
219+
"Increasing %dkB hugepages pool on node %u to %ld",
220+
hpsz, node2, orig_hugepages_node2 + 4);
221+
SAFE_FILE_PRINTF(path_hugepages_node2,
222+
"%ld", orig_hugepages_node2 + 4);
223+
}
224+
149225
hpsz *= 1024;
150226

151-
SAFE_FILE_SCANF(PATH_NR_HUGEPAGES, "%ld", &orig_hugepages);
152-
SAFE_FILE_PRINTF(PATH_NR_HUGEPAGES, "%ld", orig_hugepages + 4);
227+
if (orig_hugepages_node1 == -1 || orig_hugepages_node2 == -1) {
228+
SAFE_FILE_SCANF(PATH_NR_HUGEPAGES, "%ld", &orig_hugepages);
229+
tst_res(TINFO, "Increasing global hugepages pool to %ld",
230+
orig_hugepages + 8);
231+
SAFE_FILE_PRINTF(PATH_NR_HUGEPAGES, "%ld", orig_hugepages + 8);
232+
}
153233

154-
ret = get_allowed_nodes(NH_MEMS, TEST_NODES, &node1, &node2);
155-
if (ret < 0)
156-
tst_brk(TBROK | TERRNO, "get_allowed_nodes: %d", ret);
234+
alloc_free_huge_on_node(node1, 4 * hpsz);
235+
alloc_free_huge_on_node(node2, 4 * hpsz);
157236
}
158237

159238
static void cleanup(void)
160239
{
161-
if (!access(PATH_HUGEPAGES, F_OK))
240+
if (orig_hugepages != -1)
162241
SAFE_FILE_PRINTF(PATH_NR_HUGEPAGES, "%ld", orig_hugepages);
242+
243+
if (orig_hugepages_node1 != -1) {
244+
SAFE_FILE_PRINTF(path_hugepages_node1,
245+
"%ld", orig_hugepages_node1);
246+
}
247+
248+
if (orig_hugepages_node2 != -1) {
249+
SAFE_FILE_PRINTF(path_hugepages_node2,
250+
"%ld", orig_hugepages_node2);
251+
}
163252
}
164253

165254
static struct tst_test test = {

0 commit comments

Comments
 (0)