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