1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3 * Copyright (c) Crackerjack Project., 2007
4 * Description: This case tests the sched_getaffinity() syscall
5 * History: Porting from Crackerjack to LTP is done by
6 * Manas Kumar Nayak maknayak@in.ibm.com>
7 */
8 #define _GNU_SOURCE
9 #include <errno.h>
10 #include <sched.h>
11 #include <stdlib.h>
12 #include <string.h>
13 #include "tst_test.h"
14 #include "tst_safe_macros.h"
15 #include "lapi/cpuset.h"
16
17 static long ncpu;
18
19 static void *bad_addr;
20
errno_test(pid_t pid,size_t cpusize,void * mask,int exp_errno)21 static void errno_test(pid_t pid, size_t cpusize, void *mask, int exp_errno)
22 {
23 TEST(sched_getaffinity(pid, cpusize, mask));
24
25 if (TST_RET != -1) {
26 tst_res(TFAIL,
27 "sched_getaffinity() returned %ld, expected -1",
28 TST_RET);
29 return;
30 }
31
32 if (TST_ERR != exp_errno) {
33 tst_res(TFAIL | TTERRNO,
34 "sched_getaffinity() should fail with %s",
35 tst_strerrno(exp_errno));
36 return;
37 }
38
39 tst_res(TPASS | TTERRNO, "sched_getaffinity() failed");
40 }
41
do_test(void)42 static void do_test(void)
43 {
44 cpu_set_t *mask;
45 int nrcpus = 1024;
46 unsigned len;
47
48 realloc:
49 mask = CPU_ALLOC(nrcpus);
50 if (!mask)
51 tst_brk(TBROK | TERRNO, "CPU_ALLOC()");
52
53 len = CPU_ALLOC_SIZE(nrcpus);
54 CPU_ZERO_S(len, mask);
55
56 TEST(sched_getaffinity(0, len, mask));
57 if (TST_RET == -1) {
58 CPU_FREE(mask);
59 if (TST_ERR == EINVAL && nrcpus < (1024 << 8)) {
60 nrcpus = nrcpus << 2;
61 goto realloc;
62 }
63 tst_brk(TBROK | TTERRNO, "fail to get cpu affinity");
64 }
65
66 long i, af_cpus = 0;
67
68 for (i = 0; i < nrcpus; i++)
69 af_cpus += !!CPU_ISSET_S(i, len, mask);
70
71 if (af_cpus == 0)
72 tst_res(TFAIL, "No cpus enabled in mask");
73 else if (af_cpus > ncpu)
74 tst_res(TFAIL, "Enabled cpus = %li > system cpus %li", af_cpus, ncpu);
75 else
76 tst_res(TPASS, "cpuset size = %u, enabled cpus %ld", len, af_cpus);
77
78 errno_test(0, len, bad_addr, EFAULT);
79 errno_test(0, 0, mask, EINVAL);
80 errno_test(tst_get_unused_pid(), len, mask, ESRCH);
81
82 CPU_FREE(mask);
83 }
84
setup(void)85 static void setup(void)
86 {
87 ncpu = SAFE_SYSCONF(_SC_NPROCESSORS_CONF);
88 tst_res(TINFO, "system has %ld processor(s).", ncpu);
89
90 bad_addr = tst_get_bad_addr(NULL);
91 }
92
93 static struct tst_test test = {
94 .setup = setup,
95 .test_all = do_test,
96 };
97