1 // SPDX-License-Identifier: GPL-2.0
2 /* Copyright (c) 2023 Meta Platforms, Inc. and affiliates. */
5 #include <bpf/bpf_tracing.h>
6 #include <bpf/bpf_helpers.h>
9 #include "cpumask_common.h"
11 char _license[] SEC("license") = "GPL";
15 static bool is_test_task(void)
17 int cur_pid = bpf_get_current_pid_tgid() >> 32;
19 return pid == cur_pid;
22 static bool create_cpumask_set(struct bpf_cpumask **out1,
23 struct bpf_cpumask **out2,
24 struct bpf_cpumask **out3,
25 struct bpf_cpumask **out4)
27 struct bpf_cpumask *mask1, *mask2, *mask3, *mask4;
29 mask1 = create_cpumask();
33 mask2 = create_cpumask();
35 bpf_cpumask_release(mask1);
40 mask3 = create_cpumask();
42 bpf_cpumask_release(mask1);
43 bpf_cpumask_release(mask2);
48 mask4 = create_cpumask();
50 bpf_cpumask_release(mask1);
51 bpf_cpumask_release(mask2);
52 bpf_cpumask_release(mask3);
65 SEC("tp_btf/task_newtask")
66 int BPF_PROG(test_alloc_free_cpumask, struct task_struct *task, u64 clone_flags)
68 struct bpf_cpumask *cpumask;
73 cpumask = create_cpumask();
77 bpf_cpumask_release(cpumask);
81 SEC("tp_btf/task_newtask")
82 int BPF_PROG(test_set_clear_cpu, struct task_struct *task, u64 clone_flags)
84 struct bpf_cpumask *cpumask;
89 cpumask = create_cpumask();
93 bpf_cpumask_set_cpu(0, cpumask);
94 if (!bpf_cpumask_test_cpu(0, cast(cpumask))) {
99 bpf_cpumask_clear_cpu(0, cpumask);
100 if (bpf_cpumask_test_cpu(0, cast(cpumask))) {
106 bpf_cpumask_release(cpumask);
110 SEC("tp_btf/task_newtask")
111 int BPF_PROG(test_setall_clear_cpu, struct task_struct *task, u64 clone_flags)
113 struct bpf_cpumask *cpumask;
118 cpumask = create_cpumask();
122 bpf_cpumask_setall(cpumask);
123 if (!bpf_cpumask_full(cast(cpumask))) {
128 bpf_cpumask_clear(cpumask);
129 if (!bpf_cpumask_empty(cast(cpumask))) {
135 bpf_cpumask_release(cpumask);
139 SEC("tp_btf/task_newtask")
140 int BPF_PROG(test_first_firstzero_cpu, struct task_struct *task, u64 clone_flags)
142 struct bpf_cpumask *cpumask;
147 cpumask = create_cpumask();
151 if (bpf_cpumask_first(cast(cpumask)) < nr_cpus) {
156 if (bpf_cpumask_first_zero(cast(cpumask)) != 0) {
157 bpf_printk("first zero: %d", bpf_cpumask_first_zero(cast(cpumask)));
162 bpf_cpumask_set_cpu(0, cpumask);
163 if (bpf_cpumask_first(cast(cpumask)) != 0) {
168 if (bpf_cpumask_first_zero(cast(cpumask)) != 1) {
174 bpf_cpumask_release(cpumask);
178 SEC("tp_btf/task_newtask")
179 int BPF_PROG(test_firstand_nocpu, struct task_struct *task, u64 clone_flags)
181 struct bpf_cpumask *mask1, *mask2;
187 mask1 = create_cpumask();
191 mask2 = create_cpumask();
195 bpf_cpumask_set_cpu(0, mask1);
196 bpf_cpumask_set_cpu(1, mask2);
198 first = bpf_cpumask_first_and(cast(mask1), cast(mask2));
204 bpf_cpumask_release(mask1);
206 bpf_cpumask_release(mask2);
210 SEC("tp_btf/task_newtask")
211 int BPF_PROG(test_test_and_set_clear, struct task_struct *task, u64 clone_flags)
213 struct bpf_cpumask *cpumask;
218 cpumask = create_cpumask();
222 if (bpf_cpumask_test_and_set_cpu(0, cpumask)) {
227 if (!bpf_cpumask_test_and_set_cpu(0, cpumask)) {
232 if (!bpf_cpumask_test_and_clear_cpu(0, cpumask)) {
238 bpf_cpumask_release(cpumask);
242 SEC("tp_btf/task_newtask")
243 int BPF_PROG(test_and_or_xor, struct task_struct *task, u64 clone_flags)
245 struct bpf_cpumask *mask1, *mask2, *dst1, *dst2;
250 if (!create_cpumask_set(&mask1, &mask2, &dst1, &dst2))
253 bpf_cpumask_set_cpu(0, mask1);
254 bpf_cpumask_set_cpu(1, mask2);
256 if (bpf_cpumask_and(dst1, cast(mask1), cast(mask2))) {
260 if (!bpf_cpumask_empty(cast(dst1))) {
265 bpf_cpumask_or(dst1, cast(mask1), cast(mask2));
266 if (!bpf_cpumask_test_cpu(0, cast(dst1))) {
270 if (!bpf_cpumask_test_cpu(1, cast(dst1))) {
275 bpf_cpumask_xor(dst2, cast(mask1), cast(mask2));
276 if (!bpf_cpumask_equal(cast(dst1), cast(dst2))) {
282 bpf_cpumask_release(mask1);
283 bpf_cpumask_release(mask2);
284 bpf_cpumask_release(dst1);
285 bpf_cpumask_release(dst2);
289 SEC("tp_btf/task_newtask")
290 int BPF_PROG(test_intersects_subset, struct task_struct *task, u64 clone_flags)
292 struct bpf_cpumask *mask1, *mask2, *dst1, *dst2;
297 if (!create_cpumask_set(&mask1, &mask2, &dst1, &dst2))
300 bpf_cpumask_set_cpu(0, mask1);
301 bpf_cpumask_set_cpu(1, mask2);
302 if (bpf_cpumask_intersects(cast(mask1), cast(mask2))) {
307 bpf_cpumask_or(dst1, cast(mask1), cast(mask2));
308 if (!bpf_cpumask_subset(cast(mask1), cast(dst1))) {
313 if (!bpf_cpumask_subset(cast(mask2), cast(dst1))) {
318 if (bpf_cpumask_subset(cast(dst1), cast(mask1))) {
324 bpf_cpumask_release(mask1);
325 bpf_cpumask_release(mask2);
326 bpf_cpumask_release(dst1);
327 bpf_cpumask_release(dst2);
331 SEC("tp_btf/task_newtask")
332 int BPF_PROG(test_copy_any_anyand, struct task_struct *task, u64 clone_flags)
334 struct bpf_cpumask *mask1, *mask2, *dst1, *dst2;
340 if (!create_cpumask_set(&mask1, &mask2, &dst1, &dst2))
343 bpf_cpumask_set_cpu(0, mask1);
344 bpf_cpumask_set_cpu(1, mask2);
345 bpf_cpumask_or(dst1, cast(mask1), cast(mask2));
347 cpu = bpf_cpumask_any_distribute(cast(mask1));
353 cpu = bpf_cpumask_any_distribute(cast(dst2));
359 bpf_cpumask_copy(dst2, cast(dst1));
360 if (!bpf_cpumask_equal(cast(dst1), cast(dst2))) {
365 cpu = bpf_cpumask_any_distribute(cast(dst2));
371 cpu = bpf_cpumask_any_and_distribute(cast(mask1), cast(mask2));
378 bpf_cpumask_release(mask1);
379 bpf_cpumask_release(mask2);
380 bpf_cpumask_release(dst1);
381 bpf_cpumask_release(dst2);
385 SEC("tp_btf/task_newtask")
386 int BPF_PROG(test_insert_leave, struct task_struct *task, u64 clone_flags)
388 struct bpf_cpumask *cpumask;
390 cpumask = create_cpumask();
394 if (cpumask_map_insert(cpumask))
400 SEC("tp_btf/task_newtask")
401 int BPF_PROG(test_insert_remove_release, struct task_struct *task, u64 clone_flags)
403 struct bpf_cpumask *cpumask;
404 struct __cpumask_map_value *v;
406 cpumask = create_cpumask();
410 if (cpumask_map_insert(cpumask)) {
415 v = cpumask_map_value_lookup();
421 cpumask = bpf_kptr_xchg(&v->cpumask, NULL);
423 bpf_cpumask_release(cpumask);
430 SEC("tp_btf/task_newtask")
431 int BPF_PROG(test_global_mask_rcu, struct task_struct *task, u64 clone_flags)
433 struct bpf_cpumask *local, *prev;
438 local = create_cpumask();
442 prev = bpf_kptr_xchg(&global_mask, local);
444 bpf_cpumask_release(prev);
453 bpf_rcu_read_unlock();
457 bpf_cpumask_test_cpu(0, (const struct cpumask *)local);
458 bpf_rcu_read_unlock();
463 SEC("tp_btf/task_newtask")
465 int BPF_PROG(test_refcount_null_tracking, struct task_struct *task, u64 clone_flags)
467 struct bpf_cpumask *mask1, *mask2;
469 mask1 = bpf_cpumask_create();
470 mask2 = bpf_cpumask_create();
472 if (!mask1 || !mask2)
473 goto free_masks_return;
475 bpf_cpumask_test_cpu(0, (const struct cpumask *)mask1);
476 bpf_cpumask_test_cpu(0, (const struct cpumask *)mask2);
480 bpf_cpumask_release(mask1);
482 bpf_cpumask_release(mask2);