1 /******************************************************************************/
2 /* Copyright (c) Crackerjack Project., 2007-2008 ,Hitachi, Ltd */
3 /* Author(s): Takahiro Yasui <takahiro.yasui.mp@hitachi.com>, */
4 /* Yumiko Sugita <yumiko.sugita.yf@hitachi.com>, */
5 /* Satoshi Fujiwara <sa-fuji@sdl.hitachi.co.jp> */
6 /* */
7 /* This program is free software; you can redistribute it and/or modify */
8 /* it under the terms of the GNU General Public License as published by */
9 /* the Free Software Foundation; either version 2 of the License, or */
10 /* (at your option) any later version. */
11 /* */
12 /* This program is distributed in the hope that it will be useful, */
13 /* but WITHOUT ANY WARRANTY; without even the implied warranty of */
14 /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */
15 /* the GNU General Public License for more details. */
16 /* */
17 /* You should have received a copy of the GNU General Public License */
18 /* along with this program; if not, write to the Free Software */
19 /* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
20 /* */
21 /******************************************************************************/
22 /******************************************************************************/
23 /* */
24 /* File: get_mempolicy01.c */
25 /* */
26 /* Description: This tests the get_mempolicy() syscall */
27 /* */
28 /* Usage: <for command-line> */
29 /* get_mempolicy01 [-c n] [-e][-i n] [-I x] [-p x] [-t] */
30 /* where, -c n : Run n copies concurrently. */
31 /* -e : Turn on errno logging. */
32 /* -i n : Execute test n times. */
33 /* -I x : Execute test for x seconds. */
34 /* -P x : Pause for x seconds between iterations. */
35 /* -t : Turn on syscall timing. */
36 /* */
37 /* Total Tests: 1 */
38 /* */
39 /* Test Name: get_mempolicy01 */
40 /* History: Porting from Crackerjack to LTP is done by */
41 /* Manas Kumar Nayak maknayak@in.ibm.com> */
42 /******************************************************************************/
43
44 #include "config.h"
45 #include <sys/types.h>
46 #include <sys/mman.h>
47 #include <getopt.h>
48 #include <string.h>
49 #include <stdlib.h>
50 #include <errno.h>
51 #include <stdio.h>
52 #include <unistd.h>
53 #include <libgen.h>
54 #if HAVE_NUMA_H
55 #include <numa.h>
56 #endif
57 #if HAVE_NUMAIF_H
58 #include <numaif.h>
59 #endif
60
61 #include "test.h"
62 #include "lapi/syscalls.h"
63 #include "include_j_h.h"
64 #include "common_j_h.c"
65 #include "numa_helper.h"
66
67 char *TCID = "get_mempolicy01";
68 int TST_TOTAL = 1;
69
70 #ifdef HAVE_NUMA_V2
71
72 #define MEM_LENGTH (4 * 1024 * 1024)
73
74 static int testno;
75
76 enum test_type {
77 DEFAULT, /* get default policy */
78 ADDR, /* get policy of memory which include mapped address */
79 INVALID_POINTER,
80 INVALID_FLAGS,
81 };
82
83 enum from_node {
84 NONE,
85 SELF,
86 };
87
88 struct test_case {
89 int ttype;
90 int policy;
91 int from_node;
92 int ret;
93 int err;
94 };
95
96 /* Test cases
97 *
98 * test status of errors on man page
99 *
100 * (NONE) man page hadn't been completed.
101 *
102 * test status of errors NOT on man page
103 *
104 * EFAULT v (invalid address)
105 * EINVAL v (invalid parameters)
106 */
107 static struct test_case tcase[] = {
108 { /* case00 */
109 .ttype = DEFAULT,
110 .policy = MPOL_DEFAULT,
111 .from_node = NONE,
112 .ret = 0,
113 .err = 0,
114 },
115 { /* case01 */
116 .ttype = DEFAULT,
117 .policy = MPOL_BIND,
118 .from_node = SELF,
119 .ret = 0,
120 .err = 0,
121 },
122 { /* case02 */
123 .ttype = DEFAULT,
124 .policy = MPOL_INTERLEAVE,
125 .from_node = SELF,
126 .ret = 0,
127 .err = 0,
128 },
129 { /* case03 */
130 .ttype = DEFAULT,
131 .policy = MPOL_PREFERRED,
132 .from_node = NONE,
133 .ret = 0,
134 .err = 0,
135 },
136 { /* case04 */
137 .ttype = DEFAULT,
138 .policy = MPOL_PREFERRED,
139 .from_node = SELF,
140 .ret = 0,
141 .err = 0,
142 },
143 { /* case05 */
144 .ttype = ADDR,
145 .policy = MPOL_DEFAULT,
146 .from_node = NONE,
147 .ret = 0,
148 .err = 0,
149 },
150 { /* case06 */
151 .ttype = ADDR,
152 .policy = MPOL_BIND,
153 .from_node = SELF,
154 .ret = 0,
155 .err = 0,
156 },
157 { /* case07 */
158 .ttype = ADDR,
159 .policy = MPOL_INTERLEAVE,
160 .from_node = SELF,
161 .ret = 0,
162 .err = 0,
163 },
164 { /* case08 */
165 .ttype = ADDR,
166 .policy = MPOL_PREFERRED,
167 .from_node = NONE,
168 .ret = 0,
169 .err = 0,
170 },
171 { /* case09 */
172 .ttype = ADDR,
173 .policy = MPOL_PREFERRED,
174 .from_node = SELF,
175 .ret = 0,
176 .err = 0,
177 },
178 { /* case10 */
179 .ttype = INVALID_POINTER,
180 .policy = MPOL_DEFAULT,
181 .from_node = NONE,
182 .ret = -1,
183 .err = EFAULT,
184 },
185 { /* case11 */
186 .ttype = INVALID_FLAGS,
187 .policy = MPOL_DEFAULT,
188 .from_node = NONE,
189 .ret = -1,
190 .err = EINVAL,
191 },
192 };
193
194 static int do_test(struct test_case *tc);
195 static void setup(void);
196 static void cleanup(void);
197
main(int argc,char ** argv)198 int main(int argc, char **argv)
199 {
200 int i, ret, lc;
201
202 setup();
203
204 ret = 0;
205 testno = (int)ARRAY_SIZE(tcase);
206 for (lc = 0; TEST_LOOPING(lc); lc++) {
207 tst_count = 0;
208
209 for (i = 0; i < testno; i++) {
210 tst_resm(TINFO, "(case%02d) START", i);
211 ret = do_test(&tcase[i]);
212 tst_resm((ret == 0 ? TPASS : TFAIL | TERRNO),
213 "(case%02d) END", i);
214 }
215 }
216
217 cleanup();
218 tst_exit();
219 }
220
do_test(struct test_case * tc)221 static int do_test(struct test_case *tc)
222 {
223 int ret, err, result, cmp_ok;
224 int policy, flags;
225 struct bitmask *nodemask = numa_allocate_nodemask();
226 struct bitmask *getnodemask = numa_allocate_nodemask();
227 char *p = NULL;
228 unsigned long len = MEM_LENGTH;
229 int test_node = -1;
230
231 ret = get_allowed_nodes(NH_MEMS, 1, &test_node);
232 if (ret < 0)
233 tst_brkm(TBROK | TERRNO, cleanup, "get_allowed_nodes: %d", ret);
234 numa_bitmask_setbit(nodemask, test_node);
235 switch (tc->ttype) {
236 case DEFAULT:
237 flags = 0;
238 p = NULL;
239 if (tc->from_node == NONE)
240 TEST(ltp_syscall(__NR_set_mempolicy, tc->policy,
241 NULL, 0));
242 else
243 TEST(ltp_syscall(__NR_set_mempolicy, tc->policy,
244 nodemask->maskp, nodemask->size));
245 if (TEST_RETURN < 0) {
246 tst_resm(TBROK | TERRNO, "set_mempolicy");
247 return -1;
248 }
249
250 break;
251 default:
252 flags = MPOL_F_ADDR;
253 p = mmap(NULL, len, PROT_READ | PROT_WRITE,
254 MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);
255 if (p == MAP_FAILED)
256 tst_brkm(TBROK | TERRNO, cleanup, "mmap");
257 if (tc->from_node == NONE)
258 TEST(ltp_syscall(__NR_mbind, p, len, tc->policy,
259 NULL, 0, 0));
260 else
261 TEST(ltp_syscall(__NR_mbind, p, len, tc->policy,
262 nodemask->maskp, nodemask->size, 0));
263 if (TEST_RETURN < 0) {
264 tst_resm(TBROK | TERRNO, "mbind");
265 return -1;
266 }
267
268 if (tc->ttype == INVALID_POINTER)
269 #ifdef __ia64__
270 p = (char *)0x8000000000000000UL;
271 #else
272 p = 0;
273 #endif
274
275 if (tc->ttype == INVALID_FLAGS)
276 flags = -1;
277 }
278 errno = 0;
279 cmp_ok = 1;
280 TEST(ret = ltp_syscall(__NR_get_mempolicy, &policy, getnodemask->maskp,
281 getnodemask->size, p, flags));
282 err = TEST_ERRNO;
283 if (ret < 0)
284 goto TEST_END;
285
286 /* if policy == MPOL_DEFAULT, get_mempolicy doesn't return nodemask */
287 if (tc->policy == MPOL_DEFAULT)
288 numa_bitmask_clearall(nodemask);
289 cmp_ok = (tc->policy == policy && (tc->from_node == NONE ||
290 numa_bitmask_equal(nodemask,
291 getnodemask)));
292 TEST_END:
293 result = (err != tc->err) || !cmp_ok;
294 PRINT_RESULT_CMP(0, tc->ret, tc->err, ret, err, cmp_ok);
295 return result;
296 }
297
cleanup(void)298 static void cleanup(void)
299 {
300 tst_rmdir();
301 }
302
setup(void)303 static void setup(void)
304 {
305 /* check syscall availability */
306 ltp_syscall(__NR_get_mempolicy, NULL, NULL, 0, NULL, 0);
307
308 if (!is_numa(NULL, NH_MEMS, 1))
309 tst_brkm(TCONF, NULL, "requires NUMA with at least 1 node");
310
311 TEST_PAUSE;
312 tst_tmpdir();
313 }
314
315 #else
main(void)316 int main(void)
317 {
318 tst_brkm(TCONF, NULL, NUMA_ERROR_MSG);
319 }
320 #endif
321