]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - tests/sys/kern/sched_affinity.c
sqlite3: Vendor import of sqlite3 3.38.5
[FreeBSD/FreeBSD.git] / tests / sys / kern / sched_affinity.c
1 /*-
2  * Copyright (c) 2022 Dmitry Chagin <dchagin@FreeBSD.org>
3  *
4  * SPDX-License-Identifier: BSD-2-Clause
5  */
6 #include <sys/cdefs.h>
7 __FBSDID("$FreeBSD$");
8
9 #include <sys/types.h>
10 #include <sys/stdint.h>
11 #include <sys/sysctl.h>
12
13 #include <errno.h>
14 #include <sched.h>
15
16 #include <atf-c.h>
17
18 static uint32_t maxcpuid;
19 static uint32_t maxcpus;
20 static uint32_t cpus;
21
22 static uint32_t
23 support_getcpus(void)
24 {
25         uint32_t val;
26         size_t sz = sizeof(val);
27
28         ATF_REQUIRE(sysctlbyname("kern.smp.cpus", &val, &sz, NULL, 0) == 0);
29         return (val);
30 }
31
32 static uint32_t
33 support_getmaxcpus(void)
34 {
35         uint32_t val;
36         size_t sz = sizeof(val);
37
38         ATF_REQUIRE(sysctlbyname("kern.smp.maxcpus", &val, &sz, NULL, 0) == 0);
39         return (val);
40 }
41
42 static uint32_t
43 support_getmaxcpuid(void)
44 {
45         cpuset_t *set;
46         int setsize, rv;
47         uint32_t i, id;
48
49         for (i = 1; i < maxcpus; i++) {
50                 setsize = CPU_ALLOC_SIZE(i);
51                 set = CPU_ALLOC(i);
52                 ATF_REQUIRE(set != NULL);
53                 CPU_ZERO_S(i, set);
54                 rv = cpuset_getaffinity(CPU_LEVEL_WHICH, CPU_WHICH_PID,
55                     -1, setsize, set);
56                 if (rv == 0) {
57                         id = __BIT_FLS(i, set) - 1;
58                         CPU_FREE(set);
59                         break;
60                 }
61                 CPU_FREE(set);
62         }
63         ATF_REQUIRE(rv == 0);
64         return (id);
65 }
66
67 ATF_TC_WITHOUT_HEAD(test_setinvalidcpu);
68 ATF_TC_BODY(test_setinvalidcpu, tc)
69 {
70         size_t cpusetsize;
71         cpuset_t *set;
72
73         cpusetsize = CPU_ALLOC_SIZE(maxcpuid + 1);
74         set = CPU_ALLOC(maxcpuid + 1);
75         ATF_REQUIRE(set != NULL);
76         CPU_ZERO_S(maxcpuid + 1, set);
77         CPU_SET_S(maxcpuid + 1, maxcpuid + 1, set);
78         CPU_SET_S(maxcpuid - 1, maxcpuid + 1, set);
79         ATF_REQUIRE(sched_setaffinity(0, cpusetsize, set) == 0);
80         CPU_FREE(set);
81
82         cpusetsize = CPU_ALLOC_SIZE(maxcpus + 1);
83         set = CPU_ALLOC(maxcpus + 1);
84         ATF_REQUIRE(set != NULL);
85         CPU_ZERO_S(maxcpus + 1, set);
86         CPU_SET_S(maxcpuid + 1, maxcpus + 1, set);
87         CPU_SET_S(maxcpuid - 1, maxcpus + 1, set);
88         ATF_REQUIRE(cpuset_setaffinity(CPU_LEVEL_WHICH, CPU_WHICH_PID,
89             -1, cpusetsize, set) == -1);
90         ATF_REQUIRE_EQ(errno, EINVAL);
91         CPU_FREE(set);
92 }
93
94 ATF_TC_WITHOUT_HEAD(test_setvalidcpu);
95 ATF_TC_BODY(test_setvalidcpu, tc)
96 {
97         size_t cpusetsize;
98         cpuset_t *set;
99         int cpu;
100
101         ATF_REQUIRE(maxcpuid < maxcpus);
102         cpu = maxcpuid > 1 ? maxcpuid - 1 : 0;
103
104         cpusetsize = CPU_ALLOC_SIZE(maxcpus + 1);
105         set = CPU_ALLOC(maxcpus + 1);
106         ATF_REQUIRE(set != NULL);
107         CPU_ZERO_S(maxcpus + 1, set);
108         CPU_SET_S(cpu, maxcpus + 1, set);
109         ATF_REQUIRE(cpuset_setaffinity(CPU_LEVEL_WHICH, CPU_WHICH_PID,
110             -1, cpusetsize, set) == 0);
111         ATF_REQUIRE_EQ(cpu, sched_getcpu());
112         CPU_FREE(set);
113 }
114
115 ATF_TC_WITHOUT_HEAD(test_setzeroset1);
116 ATF_TC_BODY(test_setzeroset1, tc)
117 {
118         size_t cpusetsize;
119         cpuset_t *set;
120
121         cpusetsize = CPU_ALLOC_SIZE(maxcpuid + 1);
122         set = CPU_ALLOC(maxcpuid + 1);
123         ATF_REQUIRE(set != NULL);
124         CPU_ZERO_S(maxcpuid + 1, set);
125         ATF_REQUIRE(sched_setaffinity(0, cpusetsize, set) == -1);
126         ATF_REQUIRE_EQ(errno, EINVAL);
127         CPU_FREE(set);
128 }
129
130 ATF_TC_WITHOUT_HEAD(test_setzeroset2);
131 ATF_TC_BODY(test_setzeroset2, tc)
132 {
133         size_t cpusetsize;
134         cpuset_t *set;
135
136         cpusetsize = CPU_ALLOC_SIZE(maxcpuid + 1);
137         set = CPU_ALLOC(maxcpuid + 1);
138         ATF_REQUIRE(set != NULL);
139         CPU_ZERO_S(maxcpuid + 1, set);
140         ATF_REQUIRE(cpuset_setaffinity(CPU_LEVEL_WHICH, CPU_WHICH_PID,
141             -1, cpusetsize, set) == -1);
142         ATF_REQUIRE_EQ(errno, EDEADLK);
143         CPU_FREE(set);
144 }
145
146 ATF_TC_WITHOUT_HEAD(test_setmaxsetsize);
147 ATF_TC_BODY(test_setmaxsetsize, tc)
148 {
149         size_t cpusetsize;
150         cpuset_t *set;
151
152         cpusetsize = CPU_ALLOC_SIZE(maxcpus * 2);
153         set = CPU_ALLOC(maxcpus * 2);
154         ATF_REQUIRE(set != NULL);
155         CPU_ZERO_S(maxcpus * 2, set);
156         ATF_REQUIRE(CPU_COUNT_S(maxcpus * 2, set) == 0);
157         CPU_SET_S(0, maxcpus * 2, set);
158         ATF_REQUIRE(CPU_COUNT_S(maxcpus * 2, set) == 1);
159         ATF_REQUIRE(cpuset_setaffinity(CPU_LEVEL_WHICH, CPU_WHICH_PID,
160             -1, cpusetsize, set) == 0);
161
162         CPU_ZERO_S(maxcpus * 2, set);
163         CPU_SET_S(maxcpuid, maxcpus * 2, set);
164         ATF_REQUIRE(cpuset_setaffinity(CPU_LEVEL_WHICH, CPU_WHICH_PID,
165             -1, cpusetsize, set) == 0);
166
167         CPU_ZERO_S(maxcpus * 2, set);
168         CPU_SET_S(maxcpuid + 1, maxcpus * 2, set);
169         ATF_REQUIRE(cpuset_setaffinity(CPU_LEVEL_WHICH, CPU_WHICH_PID,
170             -1, cpusetsize, set) == -1);
171         ATF_REQUIRE_EQ(errno, EINVAL);
172         CPU_FREE(set);
173 }
174
175 ATF_TC_WITHOUT_HEAD(test_setminsetsize);
176 ATF_TC_BODY(test_setminsetsize, tc)
177 {
178         size_t cpusetsize = 1;
179         int8_t set;
180
181         if (cpus <= 8)
182                 return;
183
184         set = 1;
185         ATF_REQUIRE(cpuset_setaffinity(CPU_LEVEL_WHICH, CPU_WHICH_PID,
186             -1, cpusetsize, (const cpuset_t *)&set) == 0);
187         set = 0;
188         ATF_REQUIRE(cpuset_setaffinity(CPU_LEVEL_WHICH, CPU_WHICH_PID,
189             -1, cpusetsize, (const cpuset_t *)&set) == -1);
190         ATF_REQUIRE_EQ(errno, EDEADLK);
191 }
192
193 ATF_TC_WITHOUT_HEAD(test_getminsetsize);
194 ATF_TC_BODY(test_getminsetsize, tc)
195 {
196         size_t cpusetsize = 1;
197         int8_t set = 0;
198
199         if (cpus < 9)
200                 return;
201         ATF_REQUIRE(cpuset_getaffinity(CPU_LEVEL_WHICH, CPU_WHICH_PID,
202             -1, cpusetsize, (cpuset_t *)&set) == -1);
203         ATF_REQUIRE_EQ(errno, ERANGE);
204 }
205
206 ATF_TC_WITHOUT_HEAD(test_getsetsize);
207 ATF_TC_BODY(test_getsetsize, tc)
208 {
209         size_t cpusetsize;
210         cpuset_t *set;
211
212         cpusetsize = CPU_ALLOC_SIZE(maxcpuid + 1);
213         set = CPU_ALLOC(maxcpuid + 1);
214         ATF_REQUIRE(set != NULL);
215         CPU_ZERO_S(maxcpuid + 1, set);
216         ATF_REQUIRE(cpuset_getaffinity(CPU_LEVEL_WHICH, CPU_WHICH_PID,
217             -1, cpusetsize, set) == 0);
218         CPU_FREE(set);
219 }
220
221 ATF_TC_WITHOUT_HEAD(test_holes);
222 ATF_TC_BODY(test_holes, tc)
223 {
224         cpuset_t *set;
225         int cpusetsize;
226
227         cpusetsize = CPU_ALLOC_SIZE(maxcpus * 2);
228         set = CPU_ALLOC(maxcpus * 2);
229         ATF_REQUIRE(set != NULL);
230         CPU_ZERO_S(maxcpus * 2, set);
231         ATF_REQUIRE(CPU_COUNT_S(maxcpus * 2, set) == 0);
232         CPU_SET_S(maxcpuid, maxcpus * 2, set);
233         ATF_REQUIRE(CPU_COUNT_S(maxcpus * 2, set) == 1);
234         ATF_REQUIRE(cpuset_setaffinity(CPU_LEVEL_WHICH, CPU_WHICH_PID,
235             -1, cpusetsize, set) == 0);
236
237         CPU_ZERO_S(maxcpus * 2, set);
238         ATF_REQUIRE(CPU_COUNT_S(maxcpus * 2, set) == 0);
239         CPU_SET_S(maxcpuid + 1, maxcpus * 2, set);
240         ATF_REQUIRE(CPU_COUNT_S(maxcpus * 2, set) == 1);
241         ATF_REQUIRE(cpuset_setaffinity(CPU_LEVEL_WHICH, CPU_WHICH_PID,
242             -1, cpusetsize, set) == -1);
243         ATF_REQUIRE_EQ(errno, EINVAL);
244
245         ATF_REQUIRE(CPU_COUNT_S(maxcpus * 2, set) == 1);
246         ATF_REQUIRE(cpuset_getaffinity(CPU_LEVEL_WHICH, CPU_WHICH_PID,
247             -1, cpusetsize, set) == 0);
248         ATF_REQUIRE(CPU_ISSET_S(maxcpuid + 1, maxcpus * 2, set) == false);
249         ATF_REQUIRE(CPU_ISSET_S(maxcpuid, maxcpus * 2, set) == true);
250         ATF_REQUIRE_EQ(maxcpuid, (uint32_t)sched_getcpu());
251 }
252
253 ATF_TP_ADD_TCS(tp)
254 {
255
256         cpus = support_getcpus();
257         maxcpus = support_getmaxcpus();
258         maxcpuid = support_getmaxcpuid();
259
260         ATF_TP_ADD_TC(tp, test_setinvalidcpu);
261         ATF_TP_ADD_TC(tp, test_setvalidcpu);
262         ATF_TP_ADD_TC(tp, test_setzeroset1);
263         ATF_TP_ADD_TC(tp, test_setzeroset2);
264
265         ATF_TP_ADD_TC(tp, test_setminsetsize);
266         ATF_TP_ADD_TC(tp, test_setmaxsetsize);
267
268         ATF_TP_ADD_TC(tp, test_getminsetsize);
269         ATF_TP_ADD_TC(tp, test_getsetsize);
270
271         ATF_TP_ADD_TC(tp, test_holes);
272
273         return (atf_no_error());
274 }