• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * SPDX-License-Identifier: GPL-2.0-or-later
3  *
4  * Copyright (c) 2018 Cyril Hrubis <chrubis@suse.cz>
5  */
6 
7 /*
8  * We are testing set_mempolicy() with MPOL_BIND and MPOL_PREFERRED.
9  *
10  * For each node with memory we set its bit in nodemask with set_mempolicy()
11  * and verify that memory has been allocated accordingly.
12  */
13 
14 #include <errno.h>
15 #include "config.h"
16 #ifdef HAVE_NUMA_V2
17 # include <numa.h>
18 # include <numaif.h>
19 #endif
20 #include "tst_test.h"
21 #include "tst_numa.h"
22 
23 #ifdef HAVE_NUMA_V2
24 
25 #include "set_mempolicy.h"
26 
27 static size_t page_size;
28 static struct tst_nodemap *nodes;
29 
30 #define PAGES_ALLOCATED 16u
31 
setup(void)32 static void setup(void)
33 {
34 	page_size = getpagesize();
35 
36 	nodes = tst_get_nodemap(TST_NUMA_MEM, 2 * PAGES_ALLOCATED * page_size / 1024);
37 	if (nodes->cnt <= 1)
38 		tst_brk(TCONF, "Test requires at least two NUMA memory nodes");
39 }
40 
cleanup(void)41 static void cleanup(void)
42 {
43 	tst_nodemap_free(nodes);
44 }
45 
verify_mempolicy(unsigned int node,int mode)46 static void verify_mempolicy(unsigned int node, int mode)
47 {
48 	struct bitmask *bm = numa_allocate_nodemask();
49 	unsigned int i;
50 
51 	numa_bitmask_setbit(bm, node);
52 
53 	TEST(set_mempolicy(mode, bm->maskp, bm->size+1));
54 
55 	if (TST_RET) {
56 		tst_res(TFAIL | TTERRNO,
57 		        "set_mempolicy(%s) node %u",
58 		        tst_numa_mode_name(mode), node);
59 		return;
60 	}
61 
62 	tst_res(TPASS, "set_mempolicy(%s) node %u",
63 	        tst_numa_mode_name(mode), node);
64 
65 	numa_free_nodemask(bm);
66 
67 	const char *prefix = "child: ";
68 
69 	if (SAFE_FORK()) {
70 		prefix = "parent: ";
71 		tst_reap_children();
72 	}
73 
74 	tst_nodemap_reset_counters(nodes);
75 	alloc_fault_count(nodes, NULL, PAGES_ALLOCATED * page_size);
76 	tst_nodemap_print_counters(nodes);
77 
78 	for (i = 0; i < nodes->cnt; i++) {
79 		if (nodes->map[i] == node) {
80 			if (nodes->counters[i] == PAGES_ALLOCATED) {
81 				tst_res(TPASS, "%sNode %u allocated %u",
82 				        prefix, node, PAGES_ALLOCATED);
83 			} else {
84 				tst_res(TFAIL, "%sNode %u allocated %u, expected %u",
85 				        prefix, node, nodes->counters[i],
86 				        PAGES_ALLOCATED);
87 			}
88 			continue;
89 		}
90 
91 		if (nodes->counters[i]) {
92 			tst_res(TFAIL, "%sNode %u allocated %u, expected 0",
93 			        prefix, i, nodes->counters[i]);
94 		}
95 	}
96 }
97 
verify_set_mempolicy(unsigned int n)98 static void verify_set_mempolicy(unsigned int n)
99 {
100 	unsigned int i;
101 	int mode = n ? MPOL_PREFERRED : MPOL_BIND;
102 
103 	for (i = 0; i < nodes->cnt; i++)
104 		verify_mempolicy(nodes->map[i], mode);
105 }
106 
107 static struct tst_test test = {
108 	.setup = setup,
109 	.cleanup = cleanup,
110 	.test = verify_set_mempolicy,
111 	.tcnt = 2,
112 	.forks_child = 1,
113 	.needs_checkpoints = 1,
114 };
115 
116 #else
117 
118 TST_TEST_TCONF(NUMA_ERROR_MSG);
119 
120 #endif /* HAVE_NUMA_V2 */
121