xref: /aosp_15_r20/external/ltp/testcases/kernel/mem/cpuset/cpuset01.c (revision 49cdfc7efb34551c7342be41a7384b9c40d7cab7)
1*49cdfc7eSAndroid Build Coastguard Worker /*
2*49cdfc7eSAndroid Build Coastguard Worker  * Copyright (C) 2010-2017  Red Hat, 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  * Out Of Memory when changing cpuset's mems on NUMA. There was a
15*49cdfc7eSAndroid Build Coastguard Worker  * problem reported upstream that the allocator may see an empty
16*49cdfc7eSAndroid Build Coastguard Worker  * nodemask when changing cpuset's mems.
17*49cdfc7eSAndroid Build Coastguard Worker  * http://lkml.org/lkml/2010/5/4/77
18*49cdfc7eSAndroid Build Coastguard Worker  * http://lkml.org/lkml/2010/5/4/79
19*49cdfc7eSAndroid Build Coastguard Worker  * http://lkml.org/lkml/2010/5/4/80
20*49cdfc7eSAndroid Build Coastguard Worker  * This test is based on the reproducers for the above issue.
21*49cdfc7eSAndroid Build Coastguard Worker  */
22*49cdfc7eSAndroid Build Coastguard Worker 
23*49cdfc7eSAndroid Build Coastguard Worker #include "config.h"
24*49cdfc7eSAndroid Build Coastguard Worker #include <stdio.h>
25*49cdfc7eSAndroid Build Coastguard Worker #include <sys/wait.h>
26*49cdfc7eSAndroid Build Coastguard Worker #if HAVE_NUMA_H
27*49cdfc7eSAndroid Build Coastguard Worker #include <numa.h>
28*49cdfc7eSAndroid Build Coastguard Worker #endif
29*49cdfc7eSAndroid Build Coastguard Worker #if HAVE_NUMAIF_H
30*49cdfc7eSAndroid Build Coastguard Worker #include <numaif.h>
31*49cdfc7eSAndroid Build Coastguard Worker #endif
32*49cdfc7eSAndroid Build Coastguard Worker 
33*49cdfc7eSAndroid Build Coastguard Worker #include "mem.h"
34*49cdfc7eSAndroid Build Coastguard Worker #include "numa_helper.h"
35*49cdfc7eSAndroid Build Coastguard Worker 
36*49cdfc7eSAndroid Build Coastguard Worker #ifdef HAVE_NUMA_V2
37*49cdfc7eSAndroid Build Coastguard Worker 
38*49cdfc7eSAndroid Build Coastguard Worker volatile int end;
39*49cdfc7eSAndroid Build Coastguard Worker static int *nodes;
40*49cdfc7eSAndroid Build Coastguard Worker static int nnodes;
41*49cdfc7eSAndroid Build Coastguard Worker static long ncpus;
42*49cdfc7eSAndroid Build Coastguard Worker 
43*49cdfc7eSAndroid Build Coastguard Worker static void sighandler(int signo LTP_ATTRIBUTE_UNUSED);
44*49cdfc7eSAndroid Build Coastguard Worker static int mem_hog(void);
45*49cdfc7eSAndroid Build Coastguard Worker static int mem_hog_cpuset(int ntasks);
46*49cdfc7eSAndroid Build Coastguard Worker static long count_cpu(void);
47*49cdfc7eSAndroid Build Coastguard Worker 
test_cpuset(void)48*49cdfc7eSAndroid Build Coastguard Worker static void test_cpuset(void)
49*49cdfc7eSAndroid Build Coastguard Worker {
50*49cdfc7eSAndroid Build Coastguard Worker 	int child, i;
51*49cdfc7eSAndroid Build Coastguard Worker 	unsigned long nmask[MAXNODES / BITS_PER_LONG] = { 0 };
52*49cdfc7eSAndroid Build Coastguard Worker 	char buf[BUFSIZ];
53*49cdfc7eSAndroid Build Coastguard Worker 
54*49cdfc7eSAndroid Build Coastguard Worker 	SAFE_CG_READ(tst_cg, "cpuset.cpus", buf, sizeof(buf));
55*49cdfc7eSAndroid Build Coastguard Worker 	SAFE_CG_PRINT(tst_cg, "cpuset.cpus", buf);
56*49cdfc7eSAndroid Build Coastguard Worker 	SAFE_CG_READ(tst_cg, "cpuset.mems", buf, sizeof(buf));
57*49cdfc7eSAndroid Build Coastguard Worker 	SAFE_CG_PRINT(tst_cg, "cpuset.mems", buf);
58*49cdfc7eSAndroid Build Coastguard Worker 
59*49cdfc7eSAndroid Build Coastguard Worker 	child = SAFE_FORK();
60*49cdfc7eSAndroid Build Coastguard Worker 	if (child == 0) {
61*49cdfc7eSAndroid Build Coastguard Worker 		for (i = 0; i < nnodes; i++) {
62*49cdfc7eSAndroid Build Coastguard Worker 			if (nodes[i] >= MAXNODES)
63*49cdfc7eSAndroid Build Coastguard Worker 				continue;
64*49cdfc7eSAndroid Build Coastguard Worker 			set_node(nmask, nodes[i]);
65*49cdfc7eSAndroid Build Coastguard Worker 		}
66*49cdfc7eSAndroid Build Coastguard Worker 		if (set_mempolicy(MPOL_BIND, nmask, MAXNODES) == -1)
67*49cdfc7eSAndroid Build Coastguard Worker 			tst_brk(TBROK | TERRNO, "set_mempolicy");
68*49cdfc7eSAndroid Build Coastguard Worker 		exit(mem_hog_cpuset(ncpus > 1 ? ncpus : 1));
69*49cdfc7eSAndroid Build Coastguard Worker 	}
70*49cdfc7eSAndroid Build Coastguard Worker 
71*49cdfc7eSAndroid Build Coastguard Worker 	SAFE_CG_PRINTF(tst_cg, "cpuset.mems", "%d", nodes[0]);
72*49cdfc7eSAndroid Build Coastguard Worker 	SAFE_CG_PRINTF(tst_cg, "cpuset.mems", "%d", nodes[1]);
73*49cdfc7eSAndroid Build Coastguard Worker 
74*49cdfc7eSAndroid Build Coastguard Worker 	tst_reap_children();
75*49cdfc7eSAndroid Build Coastguard Worker 
76*49cdfc7eSAndroid Build Coastguard Worker 	tst_res(TPASS, "cpuset test pass");
77*49cdfc7eSAndroid Build Coastguard Worker }
78*49cdfc7eSAndroid Build Coastguard Worker 
setup(void)79*49cdfc7eSAndroid Build Coastguard Worker static void setup(void)
80*49cdfc7eSAndroid Build Coastguard Worker {
81*49cdfc7eSAndroid Build Coastguard Worker 	ncpus = count_cpu();
82*49cdfc7eSAndroid Build Coastguard Worker 	if (get_allowed_nodes_arr(NH_MEMS | NH_CPUS, &nnodes, &nodes) < 0)
83*49cdfc7eSAndroid Build Coastguard Worker 		tst_brk(TBROK | TERRNO, "get_allowed_nodes_arr");
84*49cdfc7eSAndroid Build Coastguard Worker 	if (nnodes <= 1)
85*49cdfc7eSAndroid Build Coastguard Worker 		tst_brk(TCONF, "requires a NUMA system.");
86*49cdfc7eSAndroid Build Coastguard Worker 
87*49cdfc7eSAndroid Build Coastguard Worker 	SAFE_CG_PRINTF(tst_cg, "cgroup.procs", "%d", getpid());
88*49cdfc7eSAndroid Build Coastguard Worker }
89*49cdfc7eSAndroid Build Coastguard Worker 
sighandler(int signo LTP_ATTRIBUTE_UNUSED)90*49cdfc7eSAndroid Build Coastguard Worker static void sighandler(int signo LTP_ATTRIBUTE_UNUSED)
91*49cdfc7eSAndroid Build Coastguard Worker {
92*49cdfc7eSAndroid Build Coastguard Worker 	end = 1;
93*49cdfc7eSAndroid Build Coastguard Worker }
94*49cdfc7eSAndroid Build Coastguard Worker 
mem_hog(void)95*49cdfc7eSAndroid Build Coastguard Worker static int mem_hog(void)
96*49cdfc7eSAndroid Build Coastguard Worker {
97*49cdfc7eSAndroid Build Coastguard Worker 	long pagesize;
98*49cdfc7eSAndroid Build Coastguard Worker 	unsigned long *addr;
99*49cdfc7eSAndroid Build Coastguard Worker 	int ret = 0;
100*49cdfc7eSAndroid Build Coastguard Worker 
101*49cdfc7eSAndroid Build Coastguard Worker 	pagesize = getpagesize();
102*49cdfc7eSAndroid Build Coastguard Worker 	while (!end) {
103*49cdfc7eSAndroid Build Coastguard Worker 		addr = SAFE_MMAP(NULL, pagesize * 10, PROT_READ | PROT_WRITE,
104*49cdfc7eSAndroid Build Coastguard Worker 			    MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
105*49cdfc7eSAndroid Build Coastguard Worker 		memset(addr, 0xF7, pagesize * 10);
106*49cdfc7eSAndroid Build Coastguard Worker 		SAFE_MUNMAP(addr, pagesize * 10);
107*49cdfc7eSAndroid Build Coastguard Worker 	}
108*49cdfc7eSAndroid Build Coastguard Worker 	return ret;
109*49cdfc7eSAndroid Build Coastguard Worker }
110*49cdfc7eSAndroid Build Coastguard Worker 
mem_hog_cpuset(int ntasks)111*49cdfc7eSAndroid Build Coastguard Worker static int mem_hog_cpuset(int ntasks)
112*49cdfc7eSAndroid Build Coastguard Worker {
113*49cdfc7eSAndroid Build Coastguard Worker 	int i, status, ret = 0;
114*49cdfc7eSAndroid Build Coastguard Worker 	struct sigaction sa;
115*49cdfc7eSAndroid Build Coastguard Worker 	pid_t *pids;
116*49cdfc7eSAndroid Build Coastguard Worker 
117*49cdfc7eSAndroid Build Coastguard Worker 	if (ntasks <= 0)
118*49cdfc7eSAndroid Build Coastguard Worker 		tst_brk(TBROK | TERRNO, "ntasks is small.");
119*49cdfc7eSAndroid Build Coastguard Worker 	sa.sa_handler = sighandler;
120*49cdfc7eSAndroid Build Coastguard Worker 	if (sigemptyset(&sa.sa_mask) < 0)
121*49cdfc7eSAndroid Build Coastguard Worker 		tst_brk(TBROK | TERRNO, "sigemptyset");
122*49cdfc7eSAndroid Build Coastguard Worker 	sa.sa_flags = 0;
123*49cdfc7eSAndroid Build Coastguard Worker 	if (sigaction(SIGUSR1, &sa, NULL) < 0)
124*49cdfc7eSAndroid Build Coastguard Worker 		tst_brk(TBROK | TERRNO, "sigaction");
125*49cdfc7eSAndroid Build Coastguard Worker 
126*49cdfc7eSAndroid Build Coastguard Worker 	pids = SAFE_MALLOC(sizeof(pid_t) * ntasks);
127*49cdfc7eSAndroid Build Coastguard Worker 	for (i = 0; i < ntasks; i++) {
128*49cdfc7eSAndroid Build Coastguard Worker 		switch (pids[i] = fork()) {
129*49cdfc7eSAndroid Build Coastguard Worker 		case -1:
130*49cdfc7eSAndroid Build Coastguard Worker 			tst_res(TFAIL | TERRNO, "fork %d", pids[i]);
131*49cdfc7eSAndroid Build Coastguard Worker 			ret = 1;
132*49cdfc7eSAndroid Build Coastguard Worker 			break;
133*49cdfc7eSAndroid Build Coastguard Worker 		case 0:
134*49cdfc7eSAndroid Build Coastguard Worker 			ret = mem_hog();
135*49cdfc7eSAndroid Build Coastguard Worker 			exit(ret);
136*49cdfc7eSAndroid Build Coastguard Worker 		default:
137*49cdfc7eSAndroid Build Coastguard Worker 			break;
138*49cdfc7eSAndroid Build Coastguard Worker 		}
139*49cdfc7eSAndroid Build Coastguard Worker 	}
140*49cdfc7eSAndroid Build Coastguard Worker 
141*49cdfc7eSAndroid Build Coastguard Worker 	while (i--) {
142*49cdfc7eSAndroid Build Coastguard Worker 		if (kill(pids[i], SIGUSR1) == -1) {
143*49cdfc7eSAndroid Build Coastguard Worker 			tst_res(TFAIL | TERRNO, "kill %d", pids[i]);
144*49cdfc7eSAndroid Build Coastguard Worker 			ret = 1;
145*49cdfc7eSAndroid Build Coastguard Worker 		}
146*49cdfc7eSAndroid Build Coastguard Worker 	}
147*49cdfc7eSAndroid Build Coastguard Worker 	while (waitpid(-1, &status, WUNTRACED | WCONTINUED) > 0) {
148*49cdfc7eSAndroid Build Coastguard Worker 		if (WIFEXITED(status)) {
149*49cdfc7eSAndroid Build Coastguard Worker 			if (WEXITSTATUS(status) != 0) {
150*49cdfc7eSAndroid Build Coastguard Worker 				tst_res(TFAIL, "child exit status is %d",
151*49cdfc7eSAndroid Build Coastguard Worker 					 WEXITSTATUS(status));
152*49cdfc7eSAndroid Build Coastguard Worker 				ret = 1;
153*49cdfc7eSAndroid Build Coastguard Worker 			}
154*49cdfc7eSAndroid Build Coastguard Worker 		} else if (WIFSIGNALED(status)) {
155*49cdfc7eSAndroid Build Coastguard Worker 			tst_res(TFAIL, "child caught signal %d",
156*49cdfc7eSAndroid Build Coastguard Worker 				 WTERMSIG(status));
157*49cdfc7eSAndroid Build Coastguard Worker 			ret = 1;
158*49cdfc7eSAndroid Build Coastguard Worker 		}
159*49cdfc7eSAndroid Build Coastguard Worker 	}
160*49cdfc7eSAndroid Build Coastguard Worker 	return ret;
161*49cdfc7eSAndroid Build Coastguard Worker }
162*49cdfc7eSAndroid Build Coastguard Worker 
count_cpu(void)163*49cdfc7eSAndroid Build Coastguard Worker static long count_cpu(void)
164*49cdfc7eSAndroid Build Coastguard Worker {
165*49cdfc7eSAndroid Build Coastguard Worker 	int ncpus = 0;
166*49cdfc7eSAndroid Build Coastguard Worker 
167*49cdfc7eSAndroid Build Coastguard Worker 	while (path_exist(PATH_SYS_SYSTEM "/cpu/cpu%d", ncpus))
168*49cdfc7eSAndroid Build Coastguard Worker 		ncpus++;
169*49cdfc7eSAndroid Build Coastguard Worker 
170*49cdfc7eSAndroid Build Coastguard Worker 	return ncpus;
171*49cdfc7eSAndroid Build Coastguard Worker }
172*49cdfc7eSAndroid Build Coastguard Worker 
173*49cdfc7eSAndroid Build Coastguard Worker static struct tst_test test = {
174*49cdfc7eSAndroid Build Coastguard Worker 	.needs_root = 1,
175*49cdfc7eSAndroid Build Coastguard Worker 	.forks_child = 1,
176*49cdfc7eSAndroid Build Coastguard Worker 	.setup = setup,
177*49cdfc7eSAndroid Build Coastguard Worker 	.test_all = test_cpuset,
178*49cdfc7eSAndroid Build Coastguard Worker 	.needs_cgroup_ctrls = (const char *const []){ "cpuset", NULL },
179*49cdfc7eSAndroid Build Coastguard Worker };
180*49cdfc7eSAndroid Build Coastguard Worker 
181*49cdfc7eSAndroid Build Coastguard Worker #else
182*49cdfc7eSAndroid Build Coastguard Worker 	TST_TEST_TCONF(NUMA_ERROR_MSG);
183*49cdfc7eSAndroid Build Coastguard Worker #endif
184