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