1 /******************************************************************************/ 2 /* Copyright (c) Crackerjack Project., 2007-2008 ,Hitachi, Ltd */ 3 /* Author(s): Takahiro Yasui <takahiro.yasui.mp (at) hitachi.com>, */ 4 /* Yumiko Sugita <yumiko.sugita.yf (at) hitachi.com>, */ 5 /* Satoshi Fujiwara <sa-fuji (at) 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 (at) 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 #include "test.h" 61 #include "linux_syscall_numbers.h" 62 #include "include_j_h.h" 63 #include "common_j_h.c" 64 #include "numa_helper.h" 65 66 char *TCID = "get_mempolicy01"; 67 int TST_TOTAL = 1; 68 69 #if HAVE_NUMA_H && HAVE_NUMAIF_H && HAVE_MPOL_CONSTANTS 70 71 #define MEM_LENGTH (4 * 1024 * 1024) 72 73 static int testno; 74 75 enum test_type { 76 DEFAULT, /* get default policy */ 77 ADDR, /* get policy of memory which include mapped address */ 78 INVALID_POINTER, 79 INVALID_FLAGS, 80 }; 81 82 enum from_node { 83 NONE, 84 SELF, 85 }; 86 87 struct test_case { 88 int ttype; 89 int policy; 90 int from_node; 91 int ret; 92 int err; 93 }; 94 95 /* Test cases 96 * 97 * test status of errors on man page 98 * 99 * (NONE) man page hadn't been completed. 100 * 101 * test status of errors NOT on man page 102 * 103 * EFAULT v (invalid address) 104 * EINVAL v (invalid parameters) 105 */ 106 static struct test_case tcase[] = { 107 { /* case00 */ 108 .ttype = DEFAULT, 109 .policy = MPOL_DEFAULT, 110 .from_node = NONE, 111 .ret = 0, 112 .err = 0, 113 }, 114 { /* case01 */ 115 .ttype = DEFAULT, 116 .policy = MPOL_BIND, 117 .from_node = SELF, 118 .ret = 0, 119 .err = 0, 120 }, 121 { /* case02 */ 122 .ttype = DEFAULT, 123 .policy = MPOL_INTERLEAVE, 124 .from_node = SELF, 125 .ret = 0, 126 .err = 0, 127 }, 128 { /* case03 */ 129 .ttype = DEFAULT, 130 .policy = MPOL_PREFERRED, 131 .from_node = NONE, 132 .ret = 0, 133 .err = 0, 134 }, 135 { /* case04 */ 136 .ttype = DEFAULT, 137 .policy = MPOL_PREFERRED, 138 .from_node = SELF, 139 .ret = 0, 140 .err = 0, 141 }, 142 { /* case05 */ 143 .ttype = ADDR, 144 .policy = MPOL_DEFAULT, 145 .from_node = NONE, 146 .ret = 0, 147 .err = 0, 148 }, 149 { /* case06 */ 150 .ttype = ADDR, 151 .policy = MPOL_BIND, 152 .from_node = SELF, 153 .ret = 0, 154 .err = 0, 155 }, 156 { /* case07 */ 157 .ttype = ADDR, 158 .policy = MPOL_INTERLEAVE, 159 .from_node = SELF, 160 .ret = 0, 161 .err = 0, 162 }, 163 { /* case08 */ 164 .ttype = ADDR, 165 .policy = MPOL_PREFERRED, 166 .from_node = NONE, 167 .ret = 0, 168 .err = 0, 169 }, 170 { /* case09 */ 171 .ttype = ADDR, 172 .policy = MPOL_PREFERRED, 173 .from_node = SELF, 174 .ret = 0, 175 .err = 0, 176 }, 177 { /* case10 */ 178 .ttype = INVALID_POINTER, 179 .policy = MPOL_DEFAULT, 180 .from_node = NONE, 181 .ret = -1, 182 .err = EFAULT, 183 }, 184 { /* case11 */ 185 .ttype = INVALID_FLAGS, 186 .policy = MPOL_DEFAULT, 187 .from_node = NONE, 188 .ret = -1, 189 .err = EINVAL, 190 }, 191 }; 192 193 static int do_test(struct test_case *tc); 194 static void setup(void); 195 static void cleanup(void); 196 197 int main(int argc, char **argv) 198 { 199 int i, ret, lc; 200 201 setup(); 202 203 ret = 0; 204 testno = (int)ARRAY_SIZE(tcase); 205 for (lc = 0; TEST_LOOPING(lc); lc++) { 206 tst_count = 0; 207 208 for (i = 0; i < testno; i++) { 209 tst_resm(TINFO, "(case%02d) START", i); 210 ret = do_test(&tcase[i]); 211 tst_resm((ret == 0 ? TPASS : TFAIL | TERRNO), 212 "(case%02d) END", i); 213 } 214 } 215 216 cleanup(); 217 tst_exit(); 218 } 219 220 static int do_test(struct test_case *tc) 221 { 222 int ret, err, result, cmp_ok; 223 int policy, flags; 224 #if !defined(LIBNUMA_API_VERSION) || LIBNUMA_API_VERSION < 2 225 nodemask_t *nodemask, *getnodemask; 226 unsigned long maxnode = NUMA_NUM_NODES; 227 #else 228 struct bitmask *nodemask = numa_allocate_nodemask(); 229 struct bitmask *getnodemask = numa_allocate_nodemask(); 230 #endif 231 char *p = NULL; 232 unsigned long len = MEM_LENGTH; 233 int test_node = -1; 234 235 ret = get_allowed_nodes(NH_MEMS, 1, &test_node); 236 if (ret < 0) 237 tst_brkm(TBROK | TERRNO, cleanup, "get_allowed_nodes: %d", ret); 238 #if !defined(LIBNUMA_API_VERSION) || LIBNUMA_API_VERSION < 2 239 nodemask = malloc(sizeof(nodemask_t)); 240 nodemask_zero(nodemask); 241 nodemask_set(nodemask, test_node); 242 getnodemask = malloc(sizeof(nodemask_t)); 243 nodemask_zero(getnodemask); 244 #else 245 numa_bitmask_setbit(nodemask, test_node); 246 #endif 247 switch (tc->ttype) { 248 case DEFAULT: 249 flags = 0; 250 p = NULL; 251 if (tc->from_node == NONE) 252 TEST(ltp_syscall(__NR_set_mempolicy, tc->policy, 253 NULL, 0)); 254 else 255 #if !defined(LIBNUMA_API_VERSION) || LIBNUMA_API_VERSION < 2 256 TEST(ltp_syscall(__NR_set_mempolicy, tc->policy, 257 nodemask, maxnode)); 258 #else 259 TEST(ltp_syscall(__NR_set_mempolicy, tc->policy, 260 nodemask->maskp, nodemask->size)); 261 #endif 262 if (TEST_RETURN < 0) { 263 tst_resm(TBROK | TERRNO, "set_mempolicy"); 264 return -1; 265 } 266 267 break; 268 default: 269 flags = MPOL_F_ADDR; 270 p = mmap(NULL, len, PROT_READ | PROT_WRITE, 271 MAP_PRIVATE | MAP_ANONYMOUS, 0, 0); 272 if (p == MAP_FAILED) 273 tst_brkm(TBROK | TERRNO, cleanup, "mmap"); 274 if (tc->from_node == NONE) 275 TEST(ltp_syscall(__NR_mbind, p, len, tc->policy, 276 NULL, 0, 0)); 277 else 278 #if !defined(LIBNUMA_API_VERSION) || LIBNUMA_API_VERSION < 2 279 TEST(ltp_syscall(__NR_mbind, p, len, tc->policy, 280 nodemask, maxnode, 0)); 281 #else 282 TEST(ltp_syscall(__NR_mbind, p, len, tc->policy, 283 nodemask->maskp, nodemask->size, 0)); 284 #endif 285 if (TEST_RETURN < 0) { 286 tst_resm(TBROK | TERRNO, "mbind"); 287 return -1; 288 } 289 290 if (tc->ttype == INVALID_POINTER) 291 #ifdef __ia64__ 292 p = (char *)0x8000000000000000UL; 293 #else 294 p = 0; 295 #endif 296 297 if (tc->ttype == INVALID_FLAGS) 298 flags = -1; 299 } 300 errno = 0; 301 cmp_ok = 1; 302 #if !defined(LIBNUMA_API_VERSION) || LIBNUMA_API_VERSION < 2 303 TEST(ret = ltp_syscall(__NR_get_mempolicy, &policy, getnodemask, 304 maxnode, p, flags)); 305 #else 306 TEST(ret = ltp_syscall(__NR_get_mempolicy, &policy, getnodemask->maskp, 307 getnodemask->size, p, flags)); 308 #endif 309 err = TEST_ERRNO; 310 if (ret < 0) 311 goto TEST_END; 312 313 /* if policy == MPOL_DEFAULT, get_mempolicy doesn't return nodemask */ 314 if (tc->policy == MPOL_DEFAULT) 315 #if !defined(LIBNUMA_API_VERSION) || LIBNUMA_API_VERSION < 2 316 nodemask_zero(nodemask); 317 cmp_ok = (tc->policy == policy && (tc->from_node == NONE || 318 nodemask_equal(nodemask, 319 getnodemask))); 320 #else 321 numa_bitmask_clearall(nodemask); 322 cmp_ok = (tc->policy == policy && (tc->from_node == NONE || 323 numa_bitmask_equal(nodemask, 324 getnodemask))); 325 #endif 326 TEST_END: 327 result = (err != tc->err) || !cmp_ok; 328 PRINT_RESULT_CMP(0, tc->ret, tc->err, ret, err, cmp_ok); 329 return result; 330 } 331 332 static void cleanup(void) 333 { 334 tst_rmdir(); 335 } 336 337 static void setup(void) 338 { 339 /* check syscall availability */ 340 ltp_syscall(__NR_get_mempolicy, NULL, NULL, 0, NULL, 0); 341 342 if (!is_numa(NULL, NH_MEMS, 1)) 343 tst_brkm(TCONF, NULL, "requires NUMA with at least 1 node"); 344 345 TEST_PAUSE; 346 tst_tmpdir(); 347 } 348 #else 349 int main(void) 350 { 351 tst_brkm(TCONF, NULL, "System doesn't have required numa support"); 352 } 353 #endif 354