xref: /aosp_15_r20/external/ltp/testcases/kernel/lib/numa_helper.c (revision 49cdfc7efb34551c7342be41a7384b9c40d7cab7)
1*49cdfc7eSAndroid Build Coastguard Worker /*
2*49cdfc7eSAndroid Build Coastguard Worker  * Copyright (C) 2012 Linux Test Project, Inc.
3*49cdfc7eSAndroid Build Coastguard Worker  *
4*49cdfc7eSAndroid Build Coastguard Worker  * This program is free software;  you can redistribute it and/or modify
5*49cdfc7eSAndroid Build Coastguard Worker  * it under the terms of the GNU General Public License as published by
6*49cdfc7eSAndroid Build Coastguard Worker  * the Free Software Foundation; either version 2 of the License, or
7*49cdfc7eSAndroid Build Coastguard Worker  * (at your option) any later version.
8*49cdfc7eSAndroid Build Coastguard Worker  *
9*49cdfc7eSAndroid Build Coastguard Worker  * This program is distributed in the hope that it will be useful,
10*49cdfc7eSAndroid Build Coastguard Worker  * but WITHOUT ANY WARRANTY;  without even the implied warranty of
11*49cdfc7eSAndroid Build Coastguard Worker  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
12*49cdfc7eSAndroid Build Coastguard Worker  * the GNU General Public License for more details.
13*49cdfc7eSAndroid Build Coastguard Worker  *
14*49cdfc7eSAndroid Build Coastguard Worker  * You should have received a copy of the GNU General Public License
15*49cdfc7eSAndroid Build Coastguard Worker  * along with this program;  if not, write to the Free Software
16*49cdfc7eSAndroid Build Coastguard Worker  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
17*49cdfc7eSAndroid Build Coastguard Worker  */
18*49cdfc7eSAndroid Build Coastguard Worker 
19*49cdfc7eSAndroid Build Coastguard Worker #include "config.h"
20*49cdfc7eSAndroid Build Coastguard Worker #include <errno.h>
21*49cdfc7eSAndroid Build Coastguard Worker #if HAVE_NUMA_H
22*49cdfc7eSAndroid Build Coastguard Worker #include <numa.h>
23*49cdfc7eSAndroid Build Coastguard Worker #endif
24*49cdfc7eSAndroid Build Coastguard Worker #if HAVE_NUMAIF_H
25*49cdfc7eSAndroid Build Coastguard Worker #include <numaif.h>
26*49cdfc7eSAndroid Build Coastguard Worker #endif
27*49cdfc7eSAndroid Build Coastguard Worker #include <stdarg.h>
28*49cdfc7eSAndroid Build Coastguard Worker #include <stdio.h>
29*49cdfc7eSAndroid Build Coastguard Worker #include <string.h>
30*49cdfc7eSAndroid Build Coastguard Worker #include <stdlib.h>
31*49cdfc7eSAndroid Build Coastguard Worker #include <unistd.h>
32*49cdfc7eSAndroid Build Coastguard Worker #include <errno.h>
33*49cdfc7eSAndroid Build Coastguard Worker 
34*49cdfc7eSAndroid Build Coastguard Worker #include "test.h"
35*49cdfc7eSAndroid Build Coastguard Worker #include "safe_macros.h"
36*49cdfc7eSAndroid Build Coastguard Worker #include "numa_helper.h"
37*49cdfc7eSAndroid Build Coastguard Worker #include "lapi/syscalls.h"
38*49cdfc7eSAndroid Build Coastguard Worker 
get_max_node(void)39*49cdfc7eSAndroid Build Coastguard Worker unsigned long get_max_node(void)
40*49cdfc7eSAndroid Build Coastguard Worker {
41*49cdfc7eSAndroid Build Coastguard Worker 	unsigned long max_node = 0;
42*49cdfc7eSAndroid Build Coastguard Worker #ifdef HAVE_NUMA_V2
43*49cdfc7eSAndroid Build Coastguard Worker 	max_node = numa_max_possible_node() + 1;
44*49cdfc7eSAndroid Build Coastguard Worker #endif
45*49cdfc7eSAndroid Build Coastguard Worker 	return max_node;
46*49cdfc7eSAndroid Build Coastguard Worker }
47*49cdfc7eSAndroid Build Coastguard Worker 
48*49cdfc7eSAndroid Build Coastguard Worker #ifdef HAVE_NUMA_V2
get_nodemask_allnodes(nodemask_t * nodemask,unsigned long max_node)49*49cdfc7eSAndroid Build Coastguard Worker static void get_nodemask_allnodes(nodemask_t * nodemask, unsigned long max_node)
50*49cdfc7eSAndroid Build Coastguard Worker {
51*49cdfc7eSAndroid Build Coastguard Worker 	unsigned long nodemask_size = max_node / 8;
52*49cdfc7eSAndroid Build Coastguard Worker 	int i;
53*49cdfc7eSAndroid Build Coastguard Worker 	char fn[64];
54*49cdfc7eSAndroid Build Coastguard Worker 	struct stat st;
55*49cdfc7eSAndroid Build Coastguard Worker 
56*49cdfc7eSAndroid Build Coastguard Worker 	memset(nodemask, 0, nodemask_size);
57*49cdfc7eSAndroid Build Coastguard Worker 	for (i = 0; i < (int)max_node; i++) {
58*49cdfc7eSAndroid Build Coastguard Worker 		sprintf(fn, "/sys/devices/system/node/node%d", i);
59*49cdfc7eSAndroid Build Coastguard Worker 		if (stat(fn, &st) == 0)
60*49cdfc7eSAndroid Build Coastguard Worker 			nodemask_set(nodemask, i);
61*49cdfc7eSAndroid Build Coastguard Worker 	}
62*49cdfc7eSAndroid Build Coastguard Worker }
63*49cdfc7eSAndroid Build Coastguard Worker 
filter_nodemask_mem(nodemask_t * nodemask,unsigned long max_node)64*49cdfc7eSAndroid Build Coastguard Worker static int filter_nodemask_mem(nodemask_t * nodemask, unsigned long max_node)
65*49cdfc7eSAndroid Build Coastguard Worker {
66*49cdfc7eSAndroid Build Coastguard Worker #ifdef MPOL_F_MEMS_ALLOWED
67*49cdfc7eSAndroid Build Coastguard Worker 	unsigned long nodemask_size = max_node / 8;
68*49cdfc7eSAndroid Build Coastguard Worker 	memset(nodemask, 0, nodemask_size);
69*49cdfc7eSAndroid Build Coastguard Worker 	/*
70*49cdfc7eSAndroid Build Coastguard Worker 	 * avoid numa_get_mems_allowed(), because of bug in getpol()
71*49cdfc7eSAndroid Build Coastguard Worker 	 * utility function in older versions:
72*49cdfc7eSAndroid Build Coastguard Worker 	 * http://www.spinics.net/lists/linux-numa/msg00849.html
73*49cdfc7eSAndroid Build Coastguard Worker 	 *
74*49cdfc7eSAndroid Build Coastguard Worker 	 * At the moment numa_available() implementation also uses
75*49cdfc7eSAndroid Build Coastguard Worker 	 * get_mempolicy, but let's make explicit check for ENOSYS
76*49cdfc7eSAndroid Build Coastguard Worker 	 * here as well in case it changes in future. Silent ignore
77*49cdfc7eSAndroid Build Coastguard Worker 	 * of ENOSYS is OK, because without NUMA caller gets empty
78*49cdfc7eSAndroid Build Coastguard Worker 	 * set of nodes anyway.
79*49cdfc7eSAndroid Build Coastguard Worker 	 */
80*49cdfc7eSAndroid Build Coastguard Worker 	if (syscall(__NR_get_mempolicy, NULL, nodemask->n,
81*49cdfc7eSAndroid Build Coastguard Worker 		    max_node, 0, MPOL_F_MEMS_ALLOWED) < 0) {
82*49cdfc7eSAndroid Build Coastguard Worker 		if (errno == ENOSYS)
83*49cdfc7eSAndroid Build Coastguard Worker 			return 0;
84*49cdfc7eSAndroid Build Coastguard Worker 		return -2;
85*49cdfc7eSAndroid Build Coastguard Worker 	}
86*49cdfc7eSAndroid Build Coastguard Worker #else
87*49cdfc7eSAndroid Build Coastguard Worker 	int i;
88*49cdfc7eSAndroid Build Coastguard Worker 	/*
89*49cdfc7eSAndroid Build Coastguard Worker 	 * old libnuma/kernel don't have MPOL_F_MEMS_ALLOWED, so let's assume
90*49cdfc7eSAndroid Build Coastguard Worker 	 * that we can use any node with memory > 0
91*49cdfc7eSAndroid Build Coastguard Worker 	 */
92*49cdfc7eSAndroid Build Coastguard Worker 	for (i = 0; i < (int)max_node; i++) {
93*49cdfc7eSAndroid Build Coastguard Worker 		if (!nodemask_isset(nodemask, i))
94*49cdfc7eSAndroid Build Coastguard Worker 			continue;
95*49cdfc7eSAndroid Build Coastguard Worker 		if (numa_node_size64(i, NULL) <= 0)
96*49cdfc7eSAndroid Build Coastguard Worker 			nodemask_clr(nodemask, i);
97*49cdfc7eSAndroid Build Coastguard Worker 	}
98*49cdfc7eSAndroid Build Coastguard Worker #endif /* MPOL_F_MEMS_ALLOWED */
99*49cdfc7eSAndroid Build Coastguard Worker 	return 0;
100*49cdfc7eSAndroid Build Coastguard Worker }
101*49cdfc7eSAndroid Build Coastguard Worker 
cpumask_has_cpus(char * cpumask,size_t len)102*49cdfc7eSAndroid Build Coastguard Worker static int cpumask_has_cpus(char *cpumask, size_t len)
103*49cdfc7eSAndroid Build Coastguard Worker {
104*49cdfc7eSAndroid Build Coastguard Worker 	unsigned int j;
105*49cdfc7eSAndroid Build Coastguard Worker 	for (j = 0; j < len; j++)
106*49cdfc7eSAndroid Build Coastguard Worker 		if (cpumask[j] == '\0')
107*49cdfc7eSAndroid Build Coastguard Worker 			return 0;
108*49cdfc7eSAndroid Build Coastguard Worker 		else if ((cpumask[j] > '0' && cpumask[j] <= '9') ||
109*49cdfc7eSAndroid Build Coastguard Worker 			 (cpumask[j] >= 'a' && cpumask[j] <= 'f'))
110*49cdfc7eSAndroid Build Coastguard Worker 			return 1;
111*49cdfc7eSAndroid Build Coastguard Worker 	return 0;
112*49cdfc7eSAndroid Build Coastguard Worker 
113*49cdfc7eSAndroid Build Coastguard Worker }
114*49cdfc7eSAndroid Build Coastguard Worker 
filter_nodemask_cpu(nodemask_t * nodemask,unsigned long max_node)115*49cdfc7eSAndroid Build Coastguard Worker static void filter_nodemask_cpu(nodemask_t * nodemask, unsigned long max_node)
116*49cdfc7eSAndroid Build Coastguard Worker {
117*49cdfc7eSAndroid Build Coastguard Worker 	char *cpumask = NULL;
118*49cdfc7eSAndroid Build Coastguard Worker 	char fn[64];
119*49cdfc7eSAndroid Build Coastguard Worker 	FILE *f;
120*49cdfc7eSAndroid Build Coastguard Worker 	size_t len;
121*49cdfc7eSAndroid Build Coastguard Worker 	int i, ret;
122*49cdfc7eSAndroid Build Coastguard Worker 
123*49cdfc7eSAndroid Build Coastguard Worker 	for (i = 0; i < (int)max_node; i++) {
124*49cdfc7eSAndroid Build Coastguard Worker 		if (!nodemask_isset(nodemask, i))
125*49cdfc7eSAndroid Build Coastguard Worker 			continue;
126*49cdfc7eSAndroid Build Coastguard Worker 		sprintf(fn, "/sys/devices/system/node/node%d/cpumap", i);
127*49cdfc7eSAndroid Build Coastguard Worker 		f = fopen(fn, "r");
128*49cdfc7eSAndroid Build Coastguard Worker 		if (f) {
129*49cdfc7eSAndroid Build Coastguard Worker 			ret = getdelim(&cpumask, &len, '\n', f);
130*49cdfc7eSAndroid Build Coastguard Worker 			if ((ret > 0) && (!cpumask_has_cpus(cpumask, len)))
131*49cdfc7eSAndroid Build Coastguard Worker 				nodemask_clr(nodemask, i);
132*49cdfc7eSAndroid Build Coastguard Worker 			fclose(f);
133*49cdfc7eSAndroid Build Coastguard Worker 		}
134*49cdfc7eSAndroid Build Coastguard Worker 	}
135*49cdfc7eSAndroid Build Coastguard Worker 	free(cpumask);
136*49cdfc7eSAndroid Build Coastguard Worker }
137*49cdfc7eSAndroid Build Coastguard Worker #endif /* HAVE_NUMA_V2 */
138*49cdfc7eSAndroid Build Coastguard Worker 
139*49cdfc7eSAndroid Build Coastguard Worker /*
140*49cdfc7eSAndroid Build Coastguard Worker  * get_allowed_nodes_arr - get number and array of available nodes
141*49cdfc7eSAndroid Build Coastguard Worker  * @num_nodes: pointer where number of available nodes will be stored
142*49cdfc7eSAndroid Build Coastguard Worker  * @nodes: array of available node ids, this is MPOL_F_MEMS_ALLOWED
143*49cdfc7eSAndroid Build Coastguard Worker  *                 node bitmask compacted (without holes), so that each field
144*49cdfc7eSAndroid Build Coastguard Worker  *                 contains node number. If NULL only num_nodes is
145*49cdfc7eSAndroid Build Coastguard Worker  *                 returned, otherwise it cotains new allocated array,
146*49cdfc7eSAndroid Build Coastguard Worker  *                 which caller is responsible to free.
147*49cdfc7eSAndroid Build Coastguard Worker  * RETURNS:
148*49cdfc7eSAndroid Build Coastguard Worker  *     0 on success
149*49cdfc7eSAndroid Build Coastguard Worker  *    -1 on allocation failure
150*49cdfc7eSAndroid Build Coastguard Worker  *    -2 on get_mempolicy failure
151*49cdfc7eSAndroid Build Coastguard Worker  */
get_allowed_nodes_arr(int flag,int * num_nodes,int ** nodes)152*49cdfc7eSAndroid Build Coastguard Worker int get_allowed_nodes_arr(int flag, int *num_nodes, int **nodes)
153*49cdfc7eSAndroid Build Coastguard Worker {
154*49cdfc7eSAndroid Build Coastguard Worker 	int ret = 0;
155*49cdfc7eSAndroid Build Coastguard Worker #ifdef HAVE_NUMA_V2
156*49cdfc7eSAndroid Build Coastguard Worker 	int i;
157*49cdfc7eSAndroid Build Coastguard Worker 	nodemask_t *nodemask = NULL;
158*49cdfc7eSAndroid Build Coastguard Worker #endif
159*49cdfc7eSAndroid Build Coastguard Worker 	*num_nodes = 0;
160*49cdfc7eSAndroid Build Coastguard Worker 	if (nodes)
161*49cdfc7eSAndroid Build Coastguard Worker 		*nodes = NULL;
162*49cdfc7eSAndroid Build Coastguard Worker 
163*49cdfc7eSAndroid Build Coastguard Worker #ifdef HAVE_NUMA_V2
164*49cdfc7eSAndroid Build Coastguard Worker 	unsigned long max_node, nodemask_size;
165*49cdfc7eSAndroid Build Coastguard Worker 
166*49cdfc7eSAndroid Build Coastguard Worker 	if (numa_available() == -1)
167*49cdfc7eSAndroid Build Coastguard Worker 		return 0;
168*49cdfc7eSAndroid Build Coastguard Worker 
169*49cdfc7eSAndroid Build Coastguard Worker 	max_node = LTP_ALIGN(get_max_node(), sizeof(unsigned long)*8);
170*49cdfc7eSAndroid Build Coastguard Worker 	nodemask_size = max_node / 8;
171*49cdfc7eSAndroid Build Coastguard Worker 
172*49cdfc7eSAndroid Build Coastguard Worker 	nodemask = malloc(nodemask_size);
173*49cdfc7eSAndroid Build Coastguard Worker 	if (nodes)
174*49cdfc7eSAndroid Build Coastguard Worker 		*nodes = malloc(sizeof(int) * max_node);
175*49cdfc7eSAndroid Build Coastguard Worker 
176*49cdfc7eSAndroid Build Coastguard Worker 	do {
177*49cdfc7eSAndroid Build Coastguard Worker 		if (nodemask == NULL || (nodes && (*nodes == NULL))) {
178*49cdfc7eSAndroid Build Coastguard Worker 			ret = -1;
179*49cdfc7eSAndroid Build Coastguard Worker 			break;
180*49cdfc7eSAndroid Build Coastguard Worker 		}
181*49cdfc7eSAndroid Build Coastguard Worker 
182*49cdfc7eSAndroid Build Coastguard Worker 		/* allow all nodes at start, then filter based on flags */
183*49cdfc7eSAndroid Build Coastguard Worker 		get_nodemask_allnodes(nodemask, max_node);
184*49cdfc7eSAndroid Build Coastguard Worker 		if ((flag & NH_MEMS) == NH_MEMS) {
185*49cdfc7eSAndroid Build Coastguard Worker 			ret = filter_nodemask_mem(nodemask, max_node);
186*49cdfc7eSAndroid Build Coastguard Worker 			if (ret < 0)
187*49cdfc7eSAndroid Build Coastguard Worker 				break;
188*49cdfc7eSAndroid Build Coastguard Worker 		}
189*49cdfc7eSAndroid Build Coastguard Worker 		if ((flag & NH_CPUS) == NH_CPUS)
190*49cdfc7eSAndroid Build Coastguard Worker 			filter_nodemask_cpu(nodemask, max_node);
191*49cdfc7eSAndroid Build Coastguard Worker 
192*49cdfc7eSAndroid Build Coastguard Worker 		for (i = 0; i < (int)max_node; i++) {
193*49cdfc7eSAndroid Build Coastguard Worker 			if (nodemask_isset(nodemask, i)) {
194*49cdfc7eSAndroid Build Coastguard Worker 				if (nodes)
195*49cdfc7eSAndroid Build Coastguard Worker 					(*nodes)[*num_nodes] = i;
196*49cdfc7eSAndroid Build Coastguard Worker 				(*num_nodes)++;
197*49cdfc7eSAndroid Build Coastguard Worker 			}
198*49cdfc7eSAndroid Build Coastguard Worker 		}
199*49cdfc7eSAndroid Build Coastguard Worker 	} while (0);
200*49cdfc7eSAndroid Build Coastguard Worker 	free(nodemask);
201*49cdfc7eSAndroid Build Coastguard Worker #endif /* HAVE_NUMA_V2 */
202*49cdfc7eSAndroid Build Coastguard Worker 	return ret;
203*49cdfc7eSAndroid Build Coastguard Worker }
204*49cdfc7eSAndroid Build Coastguard Worker 
205*49cdfc7eSAndroid Build Coastguard Worker /*
206*49cdfc7eSAndroid Build Coastguard Worker  * get_allowed_nodes - convenience function to get fixed number of nodes
207*49cdfc7eSAndroid Build Coastguard Worker  * @count: how many nodes to get
208*49cdfc7eSAndroid Build Coastguard Worker  * @...: int pointers, where node ids will be stored
209*49cdfc7eSAndroid Build Coastguard Worker  * RETURNS:
210*49cdfc7eSAndroid Build Coastguard Worker  *     0 on success
211*49cdfc7eSAndroid Build Coastguard Worker  *    -1 on allocation failure
212*49cdfc7eSAndroid Build Coastguard Worker  *    -2 on get_mempolicy failure
213*49cdfc7eSAndroid Build Coastguard Worker  *    -3 on not enough allowed nodes
214*49cdfc7eSAndroid Build Coastguard Worker  */
get_allowed_nodes(int flag,int count,...)215*49cdfc7eSAndroid Build Coastguard Worker int get_allowed_nodes(int flag, int count, ...)
216*49cdfc7eSAndroid Build Coastguard Worker {
217*49cdfc7eSAndroid Build Coastguard Worker 	int ret;
218*49cdfc7eSAndroid Build Coastguard Worker 	int i, *nodep;
219*49cdfc7eSAndroid Build Coastguard Worker 	va_list ap;
220*49cdfc7eSAndroid Build Coastguard Worker 	int num_nodes = 0;
221*49cdfc7eSAndroid Build Coastguard Worker 	int *nodes = NULL;
222*49cdfc7eSAndroid Build Coastguard Worker 
223*49cdfc7eSAndroid Build Coastguard Worker 	ret = get_allowed_nodes_arr(flag, &num_nodes, &nodes);
224*49cdfc7eSAndroid Build Coastguard Worker 	if (ret < 0)
225*49cdfc7eSAndroid Build Coastguard Worker 		return ret;
226*49cdfc7eSAndroid Build Coastguard Worker 
227*49cdfc7eSAndroid Build Coastguard Worker 	va_start(ap, count);
228*49cdfc7eSAndroid Build Coastguard Worker 	for (i = 0; i < count; i++) {
229*49cdfc7eSAndroid Build Coastguard Worker 		nodep = va_arg(ap, int *);
230*49cdfc7eSAndroid Build Coastguard Worker 		if (i < num_nodes) {
231*49cdfc7eSAndroid Build Coastguard Worker 			*nodep = nodes[i];
232*49cdfc7eSAndroid Build Coastguard Worker 		} else {
233*49cdfc7eSAndroid Build Coastguard Worker 			ret = -3;
234*49cdfc7eSAndroid Build Coastguard Worker 			errno = EINVAL;
235*49cdfc7eSAndroid Build Coastguard Worker 			break;
236*49cdfc7eSAndroid Build Coastguard Worker 		}
237*49cdfc7eSAndroid Build Coastguard Worker 	}
238*49cdfc7eSAndroid Build Coastguard Worker 	free(nodes);
239*49cdfc7eSAndroid Build Coastguard Worker 	va_end(ap);
240*49cdfc7eSAndroid Build Coastguard Worker 
241*49cdfc7eSAndroid Build Coastguard Worker 	return ret;
242*49cdfc7eSAndroid Build Coastguard Worker }
243*49cdfc7eSAndroid Build Coastguard Worker 
print_node_info(int flag)244*49cdfc7eSAndroid Build Coastguard Worker static void print_node_info(int flag)
245*49cdfc7eSAndroid Build Coastguard Worker {
246*49cdfc7eSAndroid Build Coastguard Worker 	int *allowed_nodes = NULL;
247*49cdfc7eSAndroid Build Coastguard Worker 	int i, ret, num_nodes;
248*49cdfc7eSAndroid Build Coastguard Worker 
249*49cdfc7eSAndroid Build Coastguard Worker 	ret = get_allowed_nodes_arr(flag, &num_nodes, &allowed_nodes);
250*49cdfc7eSAndroid Build Coastguard Worker 	printf("nodes (flag=%d): ", flag);
251*49cdfc7eSAndroid Build Coastguard Worker 	if (ret == 0) {
252*49cdfc7eSAndroid Build Coastguard Worker 		for (i = 0; i < num_nodes; i++)
253*49cdfc7eSAndroid Build Coastguard Worker 			printf("%d ", allowed_nodes[i]);
254*49cdfc7eSAndroid Build Coastguard Worker 		printf("\n");
255*49cdfc7eSAndroid Build Coastguard Worker 	} else
256*49cdfc7eSAndroid Build Coastguard Worker 		printf("error(%d)\n", ret);
257*49cdfc7eSAndroid Build Coastguard Worker 	free(allowed_nodes);
258*49cdfc7eSAndroid Build Coastguard Worker }
259*49cdfc7eSAndroid Build Coastguard Worker 
260*49cdfc7eSAndroid Build Coastguard Worker /*
261*49cdfc7eSAndroid Build Coastguard Worker  * nh_dump_nodes - dump info about nodes to stdout
262*49cdfc7eSAndroid Build Coastguard Worker  */
nh_dump_nodes(void)263*49cdfc7eSAndroid Build Coastguard Worker void nh_dump_nodes(void)
264*49cdfc7eSAndroid Build Coastguard Worker {
265*49cdfc7eSAndroid Build Coastguard Worker 	print_node_info(0);
266*49cdfc7eSAndroid Build Coastguard Worker 	print_node_info(NH_MEMS);
267*49cdfc7eSAndroid Build Coastguard Worker 	print_node_info(NH_CPUS);
268*49cdfc7eSAndroid Build Coastguard Worker 	print_node_info(NH_MEMS | NH_CPUS);
269*49cdfc7eSAndroid Build Coastguard Worker }
270*49cdfc7eSAndroid Build Coastguard Worker 
271*49cdfc7eSAndroid Build Coastguard Worker /*
272*49cdfc7eSAndroid Build Coastguard Worker  * is_numa - judge a system is NUMA system or not
273*49cdfc7eSAndroid Build Coastguard Worker  * @flag: NH_MEMS and/or NH_CPUS
274*49cdfc7eSAndroid Build Coastguard Worker  * @min_nodes: find at least 'min_nodes' nodes with memory
275*49cdfc7eSAndroid Build Coastguard Worker  * NOTE: the function is designed to try to find at least 'min_nodes'
276*49cdfc7eSAndroid Build Coastguard Worker  * available nodes, where each node contains memory.
277*49cdfc7eSAndroid Build Coastguard Worker  * WARN: Don't use this func in child, as it calls tst_brkm()
278*49cdfc7eSAndroid Build Coastguard Worker  * RETURNS:
279*49cdfc7eSAndroid Build Coastguard Worker  *     0 - it's not a NUMA system
280*49cdfc7eSAndroid Build Coastguard Worker  *     1 - it's a NUMA system
281*49cdfc7eSAndroid Build Coastguard Worker  */
is_numa(void (* cleanup_fn)(void),int flag,int min_nodes)282*49cdfc7eSAndroid Build Coastguard Worker int is_numa(void (*cleanup_fn)(void), int flag, int min_nodes)
283*49cdfc7eSAndroid Build Coastguard Worker {
284*49cdfc7eSAndroid Build Coastguard Worker 	int ret;
285*49cdfc7eSAndroid Build Coastguard Worker 	int numa_nodes = 0;
286*49cdfc7eSAndroid Build Coastguard Worker 
287*49cdfc7eSAndroid Build Coastguard Worker 	ret = get_allowed_nodes_arr(flag, &numa_nodes, NULL);
288*49cdfc7eSAndroid Build Coastguard Worker 	if (ret < 0)
289*49cdfc7eSAndroid Build Coastguard Worker 		tst_brkm(TBROK | TERRNO, cleanup_fn, "get_allowed_nodes_arr");
290*49cdfc7eSAndroid Build Coastguard Worker 
291*49cdfc7eSAndroid Build Coastguard Worker 	if (numa_nodes >= min_nodes)
292*49cdfc7eSAndroid Build Coastguard Worker 		return 1;
293*49cdfc7eSAndroid Build Coastguard Worker 	else
294*49cdfc7eSAndroid Build Coastguard Worker 		return 0;
295*49cdfc7eSAndroid Build Coastguard Worker }
296