17b6abcfaSDavid Vernet // SPDX-License-Identifier: GPL-2.0
27b6abcfaSDavid Vernet /* Copyright (c) 2023 Meta Platforms, Inc. and affiliates. */
37b6abcfaSDavid Vernet 
47b6abcfaSDavid Vernet #include <vmlinux.h>
57b6abcfaSDavid Vernet #include <bpf/bpf_tracing.h>
67b6abcfaSDavid Vernet #include <bpf/bpf_helpers.h>
77b6abcfaSDavid Vernet 
8f904c678SDavid Vernet #include "bpf_misc.h"
97b6abcfaSDavid Vernet #include "cpumask_common.h"
107b6abcfaSDavid Vernet 
117b6abcfaSDavid Vernet char _license[] SEC("license") = "GPL";
127b6abcfaSDavid Vernet 
137b6abcfaSDavid Vernet int pid, nr_cpus;
147b6abcfaSDavid Vernet 
is_test_task(void)157b6abcfaSDavid Vernet static bool is_test_task(void)
167b6abcfaSDavid Vernet {
177b6abcfaSDavid Vernet 	int cur_pid = bpf_get_current_pid_tgid() >> 32;
187b6abcfaSDavid Vernet 
197b6abcfaSDavid Vernet 	return pid == cur_pid;
207b6abcfaSDavid Vernet }
217b6abcfaSDavid Vernet 
create_cpumask_set(struct bpf_cpumask ** out1,struct bpf_cpumask ** out2,struct bpf_cpumask ** out3,struct bpf_cpumask ** out4)227b6abcfaSDavid Vernet static bool create_cpumask_set(struct bpf_cpumask **out1,
237b6abcfaSDavid Vernet 			       struct bpf_cpumask **out2,
247b6abcfaSDavid Vernet 			       struct bpf_cpumask **out3,
257b6abcfaSDavid Vernet 			       struct bpf_cpumask **out4)
267b6abcfaSDavid Vernet {
277b6abcfaSDavid Vernet 	struct bpf_cpumask *mask1, *mask2, *mask3, *mask4;
287b6abcfaSDavid Vernet 
297b6abcfaSDavid Vernet 	mask1 = create_cpumask();
307b6abcfaSDavid Vernet 	if (!mask1)
317b6abcfaSDavid Vernet 		return false;
327b6abcfaSDavid Vernet 
337b6abcfaSDavid Vernet 	mask2 = create_cpumask();
347b6abcfaSDavid Vernet 	if (!mask2) {
357b6abcfaSDavid Vernet 		bpf_cpumask_release(mask1);
367b6abcfaSDavid Vernet 		err = 3;
377b6abcfaSDavid Vernet 		return false;
387b6abcfaSDavid Vernet 	}
397b6abcfaSDavid Vernet 
407b6abcfaSDavid Vernet 	mask3 = create_cpumask();
417b6abcfaSDavid Vernet 	if (!mask3) {
427b6abcfaSDavid Vernet 		bpf_cpumask_release(mask1);
437b6abcfaSDavid Vernet 		bpf_cpumask_release(mask2);
447b6abcfaSDavid Vernet 		err = 4;
457b6abcfaSDavid Vernet 		return false;
467b6abcfaSDavid Vernet 	}
477b6abcfaSDavid Vernet 
487b6abcfaSDavid Vernet 	mask4 = create_cpumask();
497b6abcfaSDavid Vernet 	if (!mask4) {
507b6abcfaSDavid Vernet 		bpf_cpumask_release(mask1);
517b6abcfaSDavid Vernet 		bpf_cpumask_release(mask2);
527b6abcfaSDavid Vernet 		bpf_cpumask_release(mask3);
537b6abcfaSDavid Vernet 		err = 5;
547b6abcfaSDavid Vernet 		return false;
557b6abcfaSDavid Vernet 	}
567b6abcfaSDavid Vernet 
577b6abcfaSDavid Vernet 	*out1 = mask1;
587b6abcfaSDavid Vernet 	*out2 = mask2;
597b6abcfaSDavid Vernet 	*out3 = mask3;
607b6abcfaSDavid Vernet 	*out4 = mask4;
617b6abcfaSDavid Vernet 
627b6abcfaSDavid Vernet 	return true;
637b6abcfaSDavid Vernet }
647b6abcfaSDavid Vernet 
657b6abcfaSDavid Vernet SEC("tp_btf/task_newtask")
BPF_PROG(test_alloc_free_cpumask,struct task_struct * task,u64 clone_flags)667b6abcfaSDavid Vernet int BPF_PROG(test_alloc_free_cpumask, struct task_struct *task, u64 clone_flags)
677b6abcfaSDavid Vernet {
687b6abcfaSDavid Vernet 	struct bpf_cpumask *cpumask;
697b6abcfaSDavid Vernet 
707b6abcfaSDavid Vernet 	if (!is_test_task())
717b6abcfaSDavid Vernet 		return 0;
727b6abcfaSDavid Vernet 
737b6abcfaSDavid Vernet 	cpumask = create_cpumask();
747b6abcfaSDavid Vernet 	if (!cpumask)
757b6abcfaSDavid Vernet 		return 0;
767b6abcfaSDavid Vernet 
777b6abcfaSDavid Vernet 	bpf_cpumask_release(cpumask);
787b6abcfaSDavid Vernet 	return 0;
797b6abcfaSDavid Vernet }
807b6abcfaSDavid Vernet 
817b6abcfaSDavid Vernet SEC("tp_btf/task_newtask")
BPF_PROG(test_set_clear_cpu,struct task_struct * task,u64 clone_flags)827b6abcfaSDavid Vernet int BPF_PROG(test_set_clear_cpu, struct task_struct *task, u64 clone_flags)
837b6abcfaSDavid Vernet {
847b6abcfaSDavid Vernet 	struct bpf_cpumask *cpumask;
857b6abcfaSDavid Vernet 
867b6abcfaSDavid Vernet 	if (!is_test_task())
877b6abcfaSDavid Vernet 		return 0;
887b6abcfaSDavid Vernet 
897b6abcfaSDavid Vernet 	cpumask = create_cpumask();
907b6abcfaSDavid Vernet 	if (!cpumask)
917b6abcfaSDavid Vernet 		return 0;
927b6abcfaSDavid Vernet 
937b6abcfaSDavid Vernet 	bpf_cpumask_set_cpu(0, cpumask);
947b6abcfaSDavid Vernet 	if (!bpf_cpumask_test_cpu(0, cast(cpumask))) {
957b6abcfaSDavid Vernet 		err = 3;
967b6abcfaSDavid Vernet 		goto release_exit;
977b6abcfaSDavid Vernet 	}
987b6abcfaSDavid Vernet 
997b6abcfaSDavid Vernet 	bpf_cpumask_clear_cpu(0, cpumask);
1007b6abcfaSDavid Vernet 	if (bpf_cpumask_test_cpu(0, cast(cpumask))) {
1017b6abcfaSDavid Vernet 		err = 4;
1027b6abcfaSDavid Vernet 		goto release_exit;
1037b6abcfaSDavid Vernet 	}
1047b6abcfaSDavid Vernet 
1057b6abcfaSDavid Vernet release_exit:
1067b6abcfaSDavid Vernet 	bpf_cpumask_release(cpumask);
1077b6abcfaSDavid Vernet 	return 0;
1087b6abcfaSDavid Vernet }
1097b6abcfaSDavid Vernet 
1107b6abcfaSDavid Vernet SEC("tp_btf/task_newtask")
BPF_PROG(test_setall_clear_cpu,struct task_struct * task,u64 clone_flags)1117b6abcfaSDavid Vernet int BPF_PROG(test_setall_clear_cpu, struct task_struct *task, u64 clone_flags)
1127b6abcfaSDavid Vernet {
1137b6abcfaSDavid Vernet 	struct bpf_cpumask *cpumask;
1147b6abcfaSDavid Vernet 
1157b6abcfaSDavid Vernet 	if (!is_test_task())
1167b6abcfaSDavid Vernet 		return 0;
1177b6abcfaSDavid Vernet 
1187b6abcfaSDavid Vernet 	cpumask = create_cpumask();
1197b6abcfaSDavid Vernet 	if (!cpumask)
1207b6abcfaSDavid Vernet 		return 0;
1217b6abcfaSDavid Vernet 
1227b6abcfaSDavid Vernet 	bpf_cpumask_setall(cpumask);
1237b6abcfaSDavid Vernet 	if (!bpf_cpumask_full(cast(cpumask))) {
1247b6abcfaSDavid Vernet 		err = 3;
1257b6abcfaSDavid Vernet 		goto release_exit;
1267b6abcfaSDavid Vernet 	}
1277b6abcfaSDavid Vernet 
1287b6abcfaSDavid Vernet 	bpf_cpumask_clear(cpumask);
1297b6abcfaSDavid Vernet 	if (!bpf_cpumask_empty(cast(cpumask))) {
1307b6abcfaSDavid Vernet 		err = 4;
1317b6abcfaSDavid Vernet 		goto release_exit;
1327b6abcfaSDavid Vernet 	}
1337b6abcfaSDavid Vernet 
1347b6abcfaSDavid Vernet release_exit:
1357b6abcfaSDavid Vernet 	bpf_cpumask_release(cpumask);
1367b6abcfaSDavid Vernet 	return 0;
1377b6abcfaSDavid Vernet }
1387b6abcfaSDavid Vernet 
1397b6abcfaSDavid Vernet SEC("tp_btf/task_newtask")
BPF_PROG(test_first_firstzero_cpu,struct task_struct * task,u64 clone_flags)1407b6abcfaSDavid Vernet int BPF_PROG(test_first_firstzero_cpu, struct task_struct *task, u64 clone_flags)
1417b6abcfaSDavid Vernet {
1427b6abcfaSDavid Vernet 	struct bpf_cpumask *cpumask;
1437b6abcfaSDavid Vernet 
1447b6abcfaSDavid Vernet 	if (!is_test_task())
1457b6abcfaSDavid Vernet 		return 0;
1467b6abcfaSDavid Vernet 
1477b6abcfaSDavid Vernet 	cpumask = create_cpumask();
1487b6abcfaSDavid Vernet 	if (!cpumask)
1497b6abcfaSDavid Vernet 		return 0;
1507b6abcfaSDavid Vernet 
1517b6abcfaSDavid Vernet 	if (bpf_cpumask_first(cast(cpumask)) < nr_cpus) {
1527b6abcfaSDavid Vernet 		err = 3;
1537b6abcfaSDavid Vernet 		goto release_exit;
1547b6abcfaSDavid Vernet 	}
1557b6abcfaSDavid Vernet 
1567b6abcfaSDavid Vernet 	if (bpf_cpumask_first_zero(cast(cpumask)) != 0) {
1577b6abcfaSDavid Vernet 		bpf_printk("first zero: %d", bpf_cpumask_first_zero(cast(cpumask)));
1587b6abcfaSDavid Vernet 		err = 4;
1597b6abcfaSDavid Vernet 		goto release_exit;
1607b6abcfaSDavid Vernet 	}
1617b6abcfaSDavid Vernet 
1627b6abcfaSDavid Vernet 	bpf_cpumask_set_cpu(0, cpumask);
1637b6abcfaSDavid Vernet 	if (bpf_cpumask_first(cast(cpumask)) != 0) {
1647b6abcfaSDavid Vernet 		err = 5;
1657b6abcfaSDavid Vernet 		goto release_exit;
1667b6abcfaSDavid Vernet 	}
1677b6abcfaSDavid Vernet 
1687b6abcfaSDavid Vernet 	if (bpf_cpumask_first_zero(cast(cpumask)) != 1) {
1697b6abcfaSDavid Vernet 		err = 6;
1707b6abcfaSDavid Vernet 		goto release_exit;
1717b6abcfaSDavid Vernet 	}
1727b6abcfaSDavid Vernet 
1737b6abcfaSDavid Vernet release_exit:
1747b6abcfaSDavid Vernet 	bpf_cpumask_release(cpumask);
1757b6abcfaSDavid Vernet 	return 0;
1767b6abcfaSDavid Vernet }
1777b6abcfaSDavid Vernet 
1787b6abcfaSDavid Vernet SEC("tp_btf/task_newtask")
BPF_PROG(test_firstand_nocpu,struct task_struct * task,u64 clone_flags)17958476d8aSDavid Vernet int BPF_PROG(test_firstand_nocpu, struct task_struct *task, u64 clone_flags)
18058476d8aSDavid Vernet {
18158476d8aSDavid Vernet 	struct bpf_cpumask *mask1, *mask2;
18258476d8aSDavid Vernet 	u32 first;
18358476d8aSDavid Vernet 
18458476d8aSDavid Vernet 	if (!is_test_task())
18558476d8aSDavid Vernet 		return 0;
18658476d8aSDavid Vernet 
18758476d8aSDavid Vernet 	mask1 = create_cpumask();
18858476d8aSDavid Vernet 	if (!mask1)
18958476d8aSDavid Vernet 		return 0;
19058476d8aSDavid Vernet 
19158476d8aSDavid Vernet 	mask2 = create_cpumask();
19258476d8aSDavid Vernet 	if (!mask2)
19358476d8aSDavid Vernet 		goto release_exit;
19458476d8aSDavid Vernet 
19558476d8aSDavid Vernet 	bpf_cpumask_set_cpu(0, mask1);
19658476d8aSDavid Vernet 	bpf_cpumask_set_cpu(1, mask2);
19758476d8aSDavid Vernet 
19858476d8aSDavid Vernet 	first = bpf_cpumask_first_and(cast(mask1), cast(mask2));
19958476d8aSDavid Vernet 	if (first <= 1)
20058476d8aSDavid Vernet 		err = 3;
20158476d8aSDavid Vernet 
20258476d8aSDavid Vernet release_exit:
20358476d8aSDavid Vernet 	if (mask1)
20458476d8aSDavid Vernet 		bpf_cpumask_release(mask1);
20558476d8aSDavid Vernet 	if (mask2)
20658476d8aSDavid Vernet 		bpf_cpumask_release(mask2);
20758476d8aSDavid Vernet 	return 0;
20858476d8aSDavid Vernet }
20958476d8aSDavid Vernet 
21058476d8aSDavid Vernet SEC("tp_btf/task_newtask")
BPF_PROG(test_test_and_set_clear,struct task_struct * task,u64 clone_flags)2117b6abcfaSDavid Vernet int BPF_PROG(test_test_and_set_clear, struct task_struct *task, u64 clone_flags)
2127b6abcfaSDavid Vernet {
2137b6abcfaSDavid Vernet 	struct bpf_cpumask *cpumask;
2147b6abcfaSDavid Vernet 
2157b6abcfaSDavid Vernet 	if (!is_test_task())
2167b6abcfaSDavid Vernet 		return 0;
2177b6abcfaSDavid Vernet 
2187b6abcfaSDavid Vernet 	cpumask = create_cpumask();
2197b6abcfaSDavid Vernet 	if (!cpumask)
2207b6abcfaSDavid Vernet 		return 0;
2217b6abcfaSDavid Vernet 
2227b6abcfaSDavid Vernet 	if (bpf_cpumask_test_and_set_cpu(0, cpumask)) {
2237b6abcfaSDavid Vernet 		err = 3;
2247b6abcfaSDavid Vernet 		goto release_exit;
2257b6abcfaSDavid Vernet 	}
2267b6abcfaSDavid Vernet 
2277b6abcfaSDavid Vernet 	if (!bpf_cpumask_test_and_set_cpu(0, cpumask)) {
2287b6abcfaSDavid Vernet 		err = 4;
2297b6abcfaSDavid Vernet 		goto release_exit;
2307b6abcfaSDavid Vernet 	}
2317b6abcfaSDavid Vernet 
2327b6abcfaSDavid Vernet 	if (!bpf_cpumask_test_and_clear_cpu(0, cpumask)) {
2337b6abcfaSDavid Vernet 		err = 5;
2347b6abcfaSDavid Vernet 		goto release_exit;
2357b6abcfaSDavid Vernet 	}
2367b6abcfaSDavid Vernet 
2377b6abcfaSDavid Vernet release_exit:
2387b6abcfaSDavid Vernet 	bpf_cpumask_release(cpumask);
2397b6abcfaSDavid Vernet 	return 0;
2407b6abcfaSDavid Vernet }
2417b6abcfaSDavid Vernet 
2427b6abcfaSDavid Vernet SEC("tp_btf/task_newtask")
BPF_PROG(test_and_or_xor,struct task_struct * task,u64 clone_flags)2437b6abcfaSDavid Vernet int BPF_PROG(test_and_or_xor, struct task_struct *task, u64 clone_flags)
2447b6abcfaSDavid Vernet {
2457b6abcfaSDavid Vernet 	struct bpf_cpumask *mask1, *mask2, *dst1, *dst2;
2467b6abcfaSDavid Vernet 
2477b6abcfaSDavid Vernet 	if (!is_test_task())
2487b6abcfaSDavid Vernet 		return 0;
2497b6abcfaSDavid Vernet 
2507b6abcfaSDavid Vernet 	if (!create_cpumask_set(&mask1, &mask2, &dst1, &dst2))
2517b6abcfaSDavid Vernet 		return 0;
2527b6abcfaSDavid Vernet 
2537b6abcfaSDavid Vernet 	bpf_cpumask_set_cpu(0, mask1);
2547b6abcfaSDavid Vernet 	bpf_cpumask_set_cpu(1, mask2);
2557b6abcfaSDavid Vernet 
2567b6abcfaSDavid Vernet 	if (bpf_cpumask_and(dst1, cast(mask1), cast(mask2))) {
2577b6abcfaSDavid Vernet 		err = 6;
2587b6abcfaSDavid Vernet 		goto release_exit;
2597b6abcfaSDavid Vernet 	}
2607b6abcfaSDavid Vernet 	if (!bpf_cpumask_empty(cast(dst1))) {
2617b6abcfaSDavid Vernet 		err = 7;
2627b6abcfaSDavid Vernet 		goto release_exit;
2637b6abcfaSDavid Vernet 	}
2647b6abcfaSDavid Vernet 
2657b6abcfaSDavid Vernet 	bpf_cpumask_or(dst1, cast(mask1), cast(mask2));
2667b6abcfaSDavid Vernet 	if (!bpf_cpumask_test_cpu(0, cast(dst1))) {
2677b6abcfaSDavid Vernet 		err = 8;
2687b6abcfaSDavid Vernet 		goto release_exit;
2697b6abcfaSDavid Vernet 	}
2707b6abcfaSDavid Vernet 	if (!bpf_cpumask_test_cpu(1, cast(dst1))) {
2717b6abcfaSDavid Vernet 		err = 9;
2727b6abcfaSDavid Vernet 		goto release_exit;
2737b6abcfaSDavid Vernet 	}
2747b6abcfaSDavid Vernet 
2757b6abcfaSDavid Vernet 	bpf_cpumask_xor(dst2, cast(mask1), cast(mask2));
2767b6abcfaSDavid Vernet 	if (!bpf_cpumask_equal(cast(dst1), cast(dst2))) {
2777b6abcfaSDavid Vernet 		err = 10;
2787b6abcfaSDavid Vernet 		goto release_exit;
2797b6abcfaSDavid Vernet 	}
2807b6abcfaSDavid Vernet 
2817b6abcfaSDavid Vernet release_exit:
2827b6abcfaSDavid Vernet 	bpf_cpumask_release(mask1);
2837b6abcfaSDavid Vernet 	bpf_cpumask_release(mask2);
2847b6abcfaSDavid Vernet 	bpf_cpumask_release(dst1);
2857b6abcfaSDavid Vernet 	bpf_cpumask_release(dst2);
2867b6abcfaSDavid Vernet 	return 0;
2877b6abcfaSDavid Vernet }
2887b6abcfaSDavid Vernet 
2897b6abcfaSDavid Vernet SEC("tp_btf/task_newtask")
BPF_PROG(test_intersects_subset,struct task_struct * task,u64 clone_flags)2907b6abcfaSDavid Vernet int BPF_PROG(test_intersects_subset, struct task_struct *task, u64 clone_flags)
2917b6abcfaSDavid Vernet {
2927b6abcfaSDavid Vernet 	struct bpf_cpumask *mask1, *mask2, *dst1, *dst2;
2937b6abcfaSDavid Vernet 
2947b6abcfaSDavid Vernet 	if (!is_test_task())
2957b6abcfaSDavid Vernet 		return 0;
2967b6abcfaSDavid Vernet 
2977b6abcfaSDavid Vernet 	if (!create_cpumask_set(&mask1, &mask2, &dst1, &dst2))
2987b6abcfaSDavid Vernet 		return 0;
2997b6abcfaSDavid Vernet 
3007b6abcfaSDavid Vernet 	bpf_cpumask_set_cpu(0, mask1);
3017b6abcfaSDavid Vernet 	bpf_cpumask_set_cpu(1, mask2);
3027b6abcfaSDavid Vernet 	if (bpf_cpumask_intersects(cast(mask1), cast(mask2))) {
3037b6abcfaSDavid Vernet 		err = 6;
3047b6abcfaSDavid Vernet 		goto release_exit;
3057b6abcfaSDavid Vernet 	}
3067b6abcfaSDavid Vernet 
3077b6abcfaSDavid Vernet 	bpf_cpumask_or(dst1, cast(mask1), cast(mask2));
3087b6abcfaSDavid Vernet 	if (!bpf_cpumask_subset(cast(mask1), cast(dst1))) {
3097b6abcfaSDavid Vernet 		err = 7;
3107b6abcfaSDavid Vernet 		goto release_exit;
3117b6abcfaSDavid Vernet 	}
3127b6abcfaSDavid Vernet 
3137b6abcfaSDavid Vernet 	if (!bpf_cpumask_subset(cast(mask2), cast(dst1))) {
3147b6abcfaSDavid Vernet 		err = 8;
3157b6abcfaSDavid Vernet 		goto release_exit;
3167b6abcfaSDavid Vernet 	}
3177b6abcfaSDavid Vernet 
3187b6abcfaSDavid Vernet 	if (bpf_cpumask_subset(cast(dst1), cast(mask1))) {
3197b6abcfaSDavid Vernet 		err = 9;
3207b6abcfaSDavid Vernet 		goto release_exit;
3217b6abcfaSDavid Vernet 	}
3227b6abcfaSDavid Vernet 
3237b6abcfaSDavid Vernet release_exit:
3247b6abcfaSDavid Vernet 	bpf_cpumask_release(mask1);
3257b6abcfaSDavid Vernet 	bpf_cpumask_release(mask2);
3267b6abcfaSDavid Vernet 	bpf_cpumask_release(dst1);
3277b6abcfaSDavid Vernet 	bpf_cpumask_release(dst2);
3287b6abcfaSDavid Vernet 	return 0;
3297b6abcfaSDavid Vernet }
3307b6abcfaSDavid Vernet 
3317b6abcfaSDavid Vernet SEC("tp_btf/task_newtask")
BPF_PROG(test_copy_any_anyand,struct task_struct * task,u64 clone_flags)3327b6abcfaSDavid Vernet int BPF_PROG(test_copy_any_anyand, struct task_struct *task, u64 clone_flags)
3337b6abcfaSDavid Vernet {
3347b6abcfaSDavid Vernet 	struct bpf_cpumask *mask1, *mask2, *dst1, *dst2;
3357b6abcfaSDavid Vernet 	u32 cpu;
3367b6abcfaSDavid Vernet 
3377b6abcfaSDavid Vernet 	if (!is_test_task())
3387b6abcfaSDavid Vernet 		return 0;
3397b6abcfaSDavid Vernet 
3407b6abcfaSDavid Vernet 	if (!create_cpumask_set(&mask1, &mask2, &dst1, &dst2))
3417b6abcfaSDavid Vernet 		return 0;
3427b6abcfaSDavid Vernet 
3437b6abcfaSDavid Vernet 	bpf_cpumask_set_cpu(0, mask1);
3447b6abcfaSDavid Vernet 	bpf_cpumask_set_cpu(1, mask2);
3457b6abcfaSDavid Vernet 	bpf_cpumask_or(dst1, cast(mask1), cast(mask2));
3467b6abcfaSDavid Vernet 
347*5a73efc7SDavid Vernet 	cpu = bpf_cpumask_any_distribute(cast(mask1));
3487b6abcfaSDavid Vernet 	if (cpu != 0) {
3497b6abcfaSDavid Vernet 		err = 6;
3507b6abcfaSDavid Vernet 		goto release_exit;
3517b6abcfaSDavid Vernet 	}
3527b6abcfaSDavid Vernet 
353*5a73efc7SDavid Vernet 	cpu = bpf_cpumask_any_distribute(cast(dst2));
3547b6abcfaSDavid Vernet 	if (cpu < nr_cpus) {
3557b6abcfaSDavid Vernet 		err = 7;
3567b6abcfaSDavid Vernet 		goto release_exit;
3577b6abcfaSDavid Vernet 	}
3587b6abcfaSDavid Vernet 
3597b6abcfaSDavid Vernet 	bpf_cpumask_copy(dst2, cast(dst1));
3607b6abcfaSDavid Vernet 	if (!bpf_cpumask_equal(cast(dst1), cast(dst2))) {
3617b6abcfaSDavid Vernet 		err = 8;
3627b6abcfaSDavid Vernet 		goto release_exit;
3637b6abcfaSDavid Vernet 	}
3647b6abcfaSDavid Vernet 
365*5a73efc7SDavid Vernet 	cpu = bpf_cpumask_any_distribute(cast(dst2));
3667b6abcfaSDavid Vernet 	if (cpu > 1) {
3677b6abcfaSDavid Vernet 		err = 9;
3687b6abcfaSDavid Vernet 		goto release_exit;
3697b6abcfaSDavid Vernet 	}
3707b6abcfaSDavid Vernet 
371*5a73efc7SDavid Vernet 	cpu = bpf_cpumask_any_and_distribute(cast(mask1), cast(mask2));
3727b6abcfaSDavid Vernet 	if (cpu < nr_cpus) {
3737b6abcfaSDavid Vernet 		err = 10;
3747b6abcfaSDavid Vernet 		goto release_exit;
3757b6abcfaSDavid Vernet 	}
3767b6abcfaSDavid Vernet 
3777b6abcfaSDavid Vernet release_exit:
3787b6abcfaSDavid Vernet 	bpf_cpumask_release(mask1);
3797b6abcfaSDavid Vernet 	bpf_cpumask_release(mask2);
3807b6abcfaSDavid Vernet 	bpf_cpumask_release(dst1);
3817b6abcfaSDavid Vernet 	bpf_cpumask_release(dst2);
3827b6abcfaSDavid Vernet 	return 0;
3837b6abcfaSDavid Vernet }
3847b6abcfaSDavid Vernet 
3857b6abcfaSDavid Vernet SEC("tp_btf/task_newtask")
BPF_PROG(test_insert_leave,struct task_struct * task,u64 clone_flags)3867b6abcfaSDavid Vernet int BPF_PROG(test_insert_leave, struct task_struct *task, u64 clone_flags)
3877b6abcfaSDavid Vernet {
3887b6abcfaSDavid Vernet 	struct bpf_cpumask *cpumask;
3897b6abcfaSDavid Vernet 
3907b6abcfaSDavid Vernet 	cpumask = create_cpumask();
3917b6abcfaSDavid Vernet 	if (!cpumask)
3927b6abcfaSDavid Vernet 		return 0;
3937b6abcfaSDavid Vernet 
3947b6abcfaSDavid Vernet 	if (cpumask_map_insert(cpumask))
3957b6abcfaSDavid Vernet 		err = 3;
3967b6abcfaSDavid Vernet 
3977b6abcfaSDavid Vernet 	return 0;
3987b6abcfaSDavid Vernet }
3997b6abcfaSDavid Vernet 
4007b6abcfaSDavid Vernet SEC("tp_btf/task_newtask")
BPF_PROG(test_insert_remove_release,struct task_struct * task,u64 clone_flags)4017b6abcfaSDavid Vernet int BPF_PROG(test_insert_remove_release, struct task_struct *task, u64 clone_flags)
4027b6abcfaSDavid Vernet {
4037b6abcfaSDavid Vernet 	struct bpf_cpumask *cpumask;
4047b6abcfaSDavid Vernet 	struct __cpumask_map_value *v;
4057b6abcfaSDavid Vernet 
4067b6abcfaSDavid Vernet 	cpumask = create_cpumask();
4077b6abcfaSDavid Vernet 	if (!cpumask)
4087b6abcfaSDavid Vernet 		return 0;
4097b6abcfaSDavid Vernet 
4107b6abcfaSDavid Vernet 	if (cpumask_map_insert(cpumask)) {
4117b6abcfaSDavid Vernet 		err = 3;
4127b6abcfaSDavid Vernet 		return 0;
4137b6abcfaSDavid Vernet 	}
4147b6abcfaSDavid Vernet 
4157b6abcfaSDavid Vernet 	v = cpumask_map_value_lookup();
4167b6abcfaSDavid Vernet 	if (!v) {
4177b6abcfaSDavid Vernet 		err = 4;
4187b6abcfaSDavid Vernet 		return 0;
4197b6abcfaSDavid Vernet 	}
4207b6abcfaSDavid Vernet 
4217b6abcfaSDavid Vernet 	cpumask = bpf_kptr_xchg(&v->cpumask, NULL);
4227b6abcfaSDavid Vernet 	if (cpumask)
4237b6abcfaSDavid Vernet 		bpf_cpumask_release(cpumask);
4247b6abcfaSDavid Vernet 	else
4257b6abcfaSDavid Vernet 		err = 5;
4267b6abcfaSDavid Vernet 
4277b6abcfaSDavid Vernet 	return 0;
4287b6abcfaSDavid Vernet }
4297b6abcfaSDavid Vernet 
4307b6abcfaSDavid Vernet SEC("tp_btf/task_newtask")
BPF_PROG(test_global_mask_rcu,struct task_struct * task,u64 clone_flags)431a5a197dfSDavid Vernet int BPF_PROG(test_global_mask_rcu, struct task_struct *task, u64 clone_flags)
432a5a197dfSDavid Vernet {
433a5a197dfSDavid Vernet 	struct bpf_cpumask *local, *prev;
434a5a197dfSDavid Vernet 
435a5a197dfSDavid Vernet 	if (!is_test_task())
436a5a197dfSDavid Vernet 		return 0;
437a5a197dfSDavid Vernet 
438a5a197dfSDavid Vernet 	local = create_cpumask();
439a5a197dfSDavid Vernet 	if (!local)
440a5a197dfSDavid Vernet 		return 0;
441a5a197dfSDavid Vernet 
442a5a197dfSDavid Vernet 	prev = bpf_kptr_xchg(&global_mask, local);
443a5a197dfSDavid Vernet 	if (prev) {
444a5a197dfSDavid Vernet 		bpf_cpumask_release(prev);
445a5a197dfSDavid Vernet 		err = 3;
446a5a197dfSDavid Vernet 		return 0;
447a5a197dfSDavid Vernet 	}
448a5a197dfSDavid Vernet 
449a5a197dfSDavid Vernet 	bpf_rcu_read_lock();
450a5a197dfSDavid Vernet 	local = global_mask;
451a5a197dfSDavid Vernet 	if (!local) {
452a5a197dfSDavid Vernet 		err = 4;
453a5a197dfSDavid Vernet 		bpf_rcu_read_unlock();
454a5a197dfSDavid Vernet 		return 0;
455a5a197dfSDavid Vernet 	}
456a5a197dfSDavid Vernet 
457a5a197dfSDavid Vernet 	bpf_cpumask_test_cpu(0, (const struct cpumask *)local);
458a5a197dfSDavid Vernet 	bpf_rcu_read_unlock();
459a5a197dfSDavid Vernet 
460a5a197dfSDavid Vernet 	return 0;
461a5a197dfSDavid Vernet }
462f904c678SDavid Vernet 
463f904c678SDavid Vernet SEC("tp_btf/task_newtask")
464f904c678SDavid Vernet __success
BPF_PROG(test_refcount_null_tracking,struct task_struct * task,u64 clone_flags)465f904c678SDavid Vernet int BPF_PROG(test_refcount_null_tracking, struct task_struct *task, u64 clone_flags)
466f904c678SDavid Vernet {
467f904c678SDavid Vernet 	struct bpf_cpumask *mask1, *mask2;
468f904c678SDavid Vernet 
469f904c678SDavid Vernet 	mask1 = bpf_cpumask_create();
470f904c678SDavid Vernet 	mask2 = bpf_cpumask_create();
471f904c678SDavid Vernet 
472f904c678SDavid Vernet 	if (!mask1 || !mask2)
473f904c678SDavid Vernet 		goto free_masks_return;
474f904c678SDavid Vernet 
475f904c678SDavid Vernet 	bpf_cpumask_test_cpu(0, (const struct cpumask *)mask1);
476f904c678SDavid Vernet 	bpf_cpumask_test_cpu(0, (const struct cpumask *)mask2);
477f904c678SDavid Vernet 
478f904c678SDavid Vernet free_masks_return:
479f904c678SDavid Vernet 	if (mask1)
480f904c678SDavid Vernet 		bpf_cpumask_release(mask1);
481f904c678SDavid Vernet 	if (mask2)
482f904c678SDavid Vernet 		bpf_cpumask_release(mask2);
483f904c678SDavid Vernet 	return 0;
484f904c678SDavid Vernet }
485