1 /******************************************************************************/
2 /*                                                                            */
3 /* Copyright (c) 2009 FUJITSU LIMITED                                         */
4 /*                                                                            */
5 /* This program is free software;  you can redistribute it and/or modify      */
6 /* it under the terms of the GNU General Public License as published by       */
7 /* the Free Software Foundation; either version 2 of the License, or          */
8 /* (at your option) any later version.                                        */
9 /*                                                                            */
10 /* This program is distributed in the hope that it will be useful,            */
11 /* but WITHOUT ANY WARRANTY;  without even the implied warranty of            */
12 /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See                  */
13 /* the GNU General Public License for more details.                           */
14 /*                                                                            */
15 /* You should have received a copy of the GNU General Public License          */
16 /* along with this program;  if not, write to the Free Software               */
17 /* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA    */
18 /*                                                                            */
19 /* Author: Miao Xie <[email protected]>                                    */
20 /*                                                                            */
21 /******************************************************************************/
22 
23 #define _GNU_SOURCE
24 
25 #include "config.h"
26 #include <sched.h>
27 #include <unistd.h>
28 #include <stdlib.h>
29 #include <stdio.h>
30 #include <signal.h>
31 #include <err.h>
32 #include <limits.h>
33 #include <getopt.h>
34 #include <string.h>
35 #include <fcntl.h>
36 #include <sys/types.h>
37 #include <sys/stat.h>
38 #include <sys/mman.h>
39 #include <sys/shm.h>
40 #include <sys/syscall.h>
41 #include <inttypes.h>
42 
43 #include "test.h"
44 
45 char *TCID = "cpuset_syscall_test";
46 int TST_TOTAL = 1;
47 
48 #ifdef HAVE_NUMA_V2
49 #include <numaif.h>
50 
51 #include "../cpuset_lib/cpuset.h"
52 #include "../cpuset_lib/bitmask.h"
53 
54 static unsigned long mask;
55 static int test = -1;
56 static int flag_exit;
57 static int ret;
58 
59 #define OPT_setaffinity		(SCHAR_MAX + 1)
60 #define OPT_getaffinity		(SCHAR_MAX + 2)
61 #define OPT_mbind		(SCHAR_MAX + 3)
62 #define OPT_set_mempolicy	(SCHAR_MAX + 4)
63 #define OPT_get_mempolicy	(SCHAR_MAX + 5)
64 
65 const struct option long_opts[] = {
66 	{"setaffinity", 1, NULL, OPT_setaffinity},
67 	{"getaffinity", 0, NULL, OPT_getaffinity},
68 	{"mbind", 1, NULL, OPT_mbind},
69 	{"set_mempolicy", 1, NULL, OPT_set_mempolicy},
70 	{"get_mempolicy", 0, NULL, OPT_get_mempolicy},
71 	{NULL, 0, NULL, 0},
72 };
73 
process_options(int argc,char * argv[])74 void process_options(int argc, char *argv[])
75 {
76 	int c;
77 	char *end;
78 
79 	while (1) {
80 		c = getopt_long(argc, argv, "", long_opts, NULL);
81 		if (c == -1)
82 			break;
83 
84 		switch (c) {
85 		case OPT_setaffinity:
86 			test = 0;
87 			mask = strtoul(optarg, &end, 10);
88 			if (*end != '\0')
89 				errx(1, "wrong -s argument!");
90 			break;
91 		case OPT_getaffinity:
92 			test = 1;
93 			break;
94 		case OPT_mbind:
95 			test = 2;
96 			mask = strtoul(optarg, &end, 10);
97 			if (*end != '\0')
98 				errx(1, "wrong -s argument!");
99 			break;
100 		case OPT_set_mempolicy:
101 			test = 3;
102 			mask = strtoul(optarg, &end, 10);
103 			if (*end != '\0')
104 				errx(1, "wrong -s argument!");
105 			break;
106 		case OPT_get_mempolicy:
107 			test = 4;
108 			break;
109 		default:
110 			errx(1, "unknown option!\n");
111 			break;
112 		}
113 	}
114 }
115 
sigint_handler(int signo)116 void sigint_handler(int __attribute__ ((unused)) signo)
117 {
118 	flag_exit = 1;
119 }
120 
test_setaffinity(void)121 void test_setaffinity(void)
122 {
123 	cpu_set_t tmask;
124 	unsigned int i;
125 	CPU_ZERO(&tmask);
126 	for (i = 0; i < 8 * sizeof(mask); i++) {
127 		if ((1 << i) & mask)
128 			CPU_SET(i, &tmask);
129 	}
130 	ret = sched_setaffinity(0, sizeof(tmask), &tmask);
131 }
132 
test_getaffinity(void)133 void test_getaffinity(void)
134 {
135 	cpu_set_t tmask;
136 	unsigned int i;
137 	CPU_ZERO(&tmask);
138 	ret = sched_getaffinity(0, sizeof(tmask), &tmask);
139 	for (i = 0; i < 8 * sizeof(mask); i++) {
140 		if (CPU_ISSET(i, &tmask))
141 			printf("%d,", i);
142 	}
143 }
144 
test_mbind(void)145 void test_mbind(void)
146 {
147 	void *addr;
148 	int len = 10 * 1024 * 1024;
149 	addr = mmap(NULL, len, PROT_READ, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
150 	if (addr == MAP_FAILED) {
151 		ret = 1;
152 		return;
153 	}
154 	printf("%p\n", addr);
155 	ret = mbind(addr, len, MPOL_BIND, &mask, 8 * sizeof(mask), 0);
156 }
157 
test_set_mempolicy(void)158 void test_set_mempolicy(void)
159 {
160 	ret = set_mempolicy(MPOL_BIND, &mask, 8 * sizeof(mask));
161 }
162 
test_get_mempolicy(void)163 void test_get_mempolicy(void)
164 {
165 	int nbits;
166 	struct bitmask *nmask;
167 	char str[256];
168 
169 	nbits = cpuset_mems_nbits();
170 	if (nbits <= 0) {
171 		warn("get the nbits of nodes failed");
172 		ret = 1;
173 		return;
174 	}
175 
176 	nmask = bitmask_alloc(nbits);
177 	if (nmask == NULL) {
178 		warn("alloc bitmask failed");
179 		ret = 1;
180 		return;
181 	}
182 	ret = get_mempolicy(NULL, bitmask_mask(nmask), bitmask_nbits(nmask), 0,
183 			    MPOL_F_MEMS_ALLOWED);
184 
185 	bitmask_displaylist(str, 256, nmask);
186 	puts(str);
187 }
188 
sigusr_handler(int signo)189 void sigusr_handler(int __attribute__ ((unused)) signo)
190 {
191 	switch (test) {
192 	case 0:
193 		test_setaffinity();
194 		break;
195 	case 1:
196 		test_getaffinity();
197 		break;
198 	case 2:
199 		test_mbind();
200 		break;
201 	case 3:
202 		test_set_mempolicy();
203 		break;
204 	case 4:
205 		test_get_mempolicy();
206 		break;
207 	default:;
208 	}
209 	test = -1;
210 }
211 
main(int argc,char * argv[])212 int main(int argc, char *argv[])
213 {
214 	struct sigaction sigint_action;
215 	struct sigaction sigusr_action;
216 
217 	memset(&sigint_action, 0, sizeof(sigint_action));
218 	sigint_action.sa_handler = &sigint_handler;
219 	sigaction(SIGINT, &sigint_action, NULL);
220 
221 	memset(&sigusr_action, 0, sizeof(sigusr_action));
222 	sigusr_action.sa_handler = &sigusr_handler;
223 	sigaction(SIGUSR1, &sigusr_action, NULL);
224 
225 	process_options(argc, argv);
226 
227 	while (!flag_exit)
228 		sleep(1);
229 
230 	return ret;
231 }
232 #else
main(void)233 int main(void)
234 {
235 	tst_brkm(TCONF, NULL, NUMA_ERROR_MSG);
236 }
237 #endif
238