162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0
262306a36Sopenharmony_ci/* Copyright (c) 2023 Meta Platforms, Inc. and affiliates. */
362306a36Sopenharmony_ci
462306a36Sopenharmony_ci#include <vmlinux.h>
562306a36Sopenharmony_ci#include <bpf/bpf_tracing.h>
662306a36Sopenharmony_ci#include <bpf/bpf_helpers.h>
762306a36Sopenharmony_ci
862306a36Sopenharmony_ci#include "bpf_misc.h"
962306a36Sopenharmony_ci#include "cpumask_common.h"
1062306a36Sopenharmony_ci
1162306a36Sopenharmony_cichar _license[] SEC("license") = "GPL";
1262306a36Sopenharmony_ci
1362306a36Sopenharmony_ciint pid, nr_cpus;
1462306a36Sopenharmony_ci
1562306a36Sopenharmony_cistatic bool is_test_task(void)
1662306a36Sopenharmony_ci{
1762306a36Sopenharmony_ci	int cur_pid = bpf_get_current_pid_tgid() >> 32;
1862306a36Sopenharmony_ci
1962306a36Sopenharmony_ci	return pid == cur_pid;
2062306a36Sopenharmony_ci}
2162306a36Sopenharmony_ci
2262306a36Sopenharmony_cistatic bool create_cpumask_set(struct bpf_cpumask **out1,
2362306a36Sopenharmony_ci			       struct bpf_cpumask **out2,
2462306a36Sopenharmony_ci			       struct bpf_cpumask **out3,
2562306a36Sopenharmony_ci			       struct bpf_cpumask **out4)
2662306a36Sopenharmony_ci{
2762306a36Sopenharmony_ci	struct bpf_cpumask *mask1, *mask2, *mask3, *mask4;
2862306a36Sopenharmony_ci
2962306a36Sopenharmony_ci	mask1 = create_cpumask();
3062306a36Sopenharmony_ci	if (!mask1)
3162306a36Sopenharmony_ci		return false;
3262306a36Sopenharmony_ci
3362306a36Sopenharmony_ci	mask2 = create_cpumask();
3462306a36Sopenharmony_ci	if (!mask2) {
3562306a36Sopenharmony_ci		bpf_cpumask_release(mask1);
3662306a36Sopenharmony_ci		err = 3;
3762306a36Sopenharmony_ci		return false;
3862306a36Sopenharmony_ci	}
3962306a36Sopenharmony_ci
4062306a36Sopenharmony_ci	mask3 = create_cpumask();
4162306a36Sopenharmony_ci	if (!mask3) {
4262306a36Sopenharmony_ci		bpf_cpumask_release(mask1);
4362306a36Sopenharmony_ci		bpf_cpumask_release(mask2);
4462306a36Sopenharmony_ci		err = 4;
4562306a36Sopenharmony_ci		return false;
4662306a36Sopenharmony_ci	}
4762306a36Sopenharmony_ci
4862306a36Sopenharmony_ci	mask4 = create_cpumask();
4962306a36Sopenharmony_ci	if (!mask4) {
5062306a36Sopenharmony_ci		bpf_cpumask_release(mask1);
5162306a36Sopenharmony_ci		bpf_cpumask_release(mask2);
5262306a36Sopenharmony_ci		bpf_cpumask_release(mask3);
5362306a36Sopenharmony_ci		err = 5;
5462306a36Sopenharmony_ci		return false;
5562306a36Sopenharmony_ci	}
5662306a36Sopenharmony_ci
5762306a36Sopenharmony_ci	*out1 = mask1;
5862306a36Sopenharmony_ci	*out2 = mask2;
5962306a36Sopenharmony_ci	*out3 = mask3;
6062306a36Sopenharmony_ci	*out4 = mask4;
6162306a36Sopenharmony_ci
6262306a36Sopenharmony_ci	return true;
6362306a36Sopenharmony_ci}
6462306a36Sopenharmony_ci
6562306a36Sopenharmony_ciSEC("tp_btf/task_newtask")
6662306a36Sopenharmony_ciint BPF_PROG(test_alloc_free_cpumask, struct task_struct *task, u64 clone_flags)
6762306a36Sopenharmony_ci{
6862306a36Sopenharmony_ci	struct bpf_cpumask *cpumask;
6962306a36Sopenharmony_ci
7062306a36Sopenharmony_ci	if (!is_test_task())
7162306a36Sopenharmony_ci		return 0;
7262306a36Sopenharmony_ci
7362306a36Sopenharmony_ci	cpumask = create_cpumask();
7462306a36Sopenharmony_ci	if (!cpumask)
7562306a36Sopenharmony_ci		return 0;
7662306a36Sopenharmony_ci
7762306a36Sopenharmony_ci	bpf_cpumask_release(cpumask);
7862306a36Sopenharmony_ci	return 0;
7962306a36Sopenharmony_ci}
8062306a36Sopenharmony_ci
8162306a36Sopenharmony_ciSEC("tp_btf/task_newtask")
8262306a36Sopenharmony_ciint BPF_PROG(test_set_clear_cpu, struct task_struct *task, u64 clone_flags)
8362306a36Sopenharmony_ci{
8462306a36Sopenharmony_ci	struct bpf_cpumask *cpumask;
8562306a36Sopenharmony_ci
8662306a36Sopenharmony_ci	if (!is_test_task())
8762306a36Sopenharmony_ci		return 0;
8862306a36Sopenharmony_ci
8962306a36Sopenharmony_ci	cpumask = create_cpumask();
9062306a36Sopenharmony_ci	if (!cpumask)
9162306a36Sopenharmony_ci		return 0;
9262306a36Sopenharmony_ci
9362306a36Sopenharmony_ci	bpf_cpumask_set_cpu(0, cpumask);
9462306a36Sopenharmony_ci	if (!bpf_cpumask_test_cpu(0, cast(cpumask))) {
9562306a36Sopenharmony_ci		err = 3;
9662306a36Sopenharmony_ci		goto release_exit;
9762306a36Sopenharmony_ci	}
9862306a36Sopenharmony_ci
9962306a36Sopenharmony_ci	bpf_cpumask_clear_cpu(0, cpumask);
10062306a36Sopenharmony_ci	if (bpf_cpumask_test_cpu(0, cast(cpumask))) {
10162306a36Sopenharmony_ci		err = 4;
10262306a36Sopenharmony_ci		goto release_exit;
10362306a36Sopenharmony_ci	}
10462306a36Sopenharmony_ci
10562306a36Sopenharmony_cirelease_exit:
10662306a36Sopenharmony_ci	bpf_cpumask_release(cpumask);
10762306a36Sopenharmony_ci	return 0;
10862306a36Sopenharmony_ci}
10962306a36Sopenharmony_ci
11062306a36Sopenharmony_ciSEC("tp_btf/task_newtask")
11162306a36Sopenharmony_ciint BPF_PROG(test_setall_clear_cpu, struct task_struct *task, u64 clone_flags)
11262306a36Sopenharmony_ci{
11362306a36Sopenharmony_ci	struct bpf_cpumask *cpumask;
11462306a36Sopenharmony_ci
11562306a36Sopenharmony_ci	if (!is_test_task())
11662306a36Sopenharmony_ci		return 0;
11762306a36Sopenharmony_ci
11862306a36Sopenharmony_ci	cpumask = create_cpumask();
11962306a36Sopenharmony_ci	if (!cpumask)
12062306a36Sopenharmony_ci		return 0;
12162306a36Sopenharmony_ci
12262306a36Sopenharmony_ci	bpf_cpumask_setall(cpumask);
12362306a36Sopenharmony_ci	if (!bpf_cpumask_full(cast(cpumask))) {
12462306a36Sopenharmony_ci		err = 3;
12562306a36Sopenharmony_ci		goto release_exit;
12662306a36Sopenharmony_ci	}
12762306a36Sopenharmony_ci
12862306a36Sopenharmony_ci	bpf_cpumask_clear(cpumask);
12962306a36Sopenharmony_ci	if (!bpf_cpumask_empty(cast(cpumask))) {
13062306a36Sopenharmony_ci		err = 4;
13162306a36Sopenharmony_ci		goto release_exit;
13262306a36Sopenharmony_ci	}
13362306a36Sopenharmony_ci
13462306a36Sopenharmony_cirelease_exit:
13562306a36Sopenharmony_ci	bpf_cpumask_release(cpumask);
13662306a36Sopenharmony_ci	return 0;
13762306a36Sopenharmony_ci}
13862306a36Sopenharmony_ci
13962306a36Sopenharmony_ciSEC("tp_btf/task_newtask")
14062306a36Sopenharmony_ciint BPF_PROG(test_first_firstzero_cpu, struct task_struct *task, u64 clone_flags)
14162306a36Sopenharmony_ci{
14262306a36Sopenharmony_ci	struct bpf_cpumask *cpumask;
14362306a36Sopenharmony_ci
14462306a36Sopenharmony_ci	if (!is_test_task())
14562306a36Sopenharmony_ci		return 0;
14662306a36Sopenharmony_ci
14762306a36Sopenharmony_ci	cpumask = create_cpumask();
14862306a36Sopenharmony_ci	if (!cpumask)
14962306a36Sopenharmony_ci		return 0;
15062306a36Sopenharmony_ci
15162306a36Sopenharmony_ci	if (bpf_cpumask_first(cast(cpumask)) < nr_cpus) {
15262306a36Sopenharmony_ci		err = 3;
15362306a36Sopenharmony_ci		goto release_exit;
15462306a36Sopenharmony_ci	}
15562306a36Sopenharmony_ci
15662306a36Sopenharmony_ci	if (bpf_cpumask_first_zero(cast(cpumask)) != 0) {
15762306a36Sopenharmony_ci		bpf_printk("first zero: %d", bpf_cpumask_first_zero(cast(cpumask)));
15862306a36Sopenharmony_ci		err = 4;
15962306a36Sopenharmony_ci		goto release_exit;
16062306a36Sopenharmony_ci	}
16162306a36Sopenharmony_ci
16262306a36Sopenharmony_ci	bpf_cpumask_set_cpu(0, cpumask);
16362306a36Sopenharmony_ci	if (bpf_cpumask_first(cast(cpumask)) != 0) {
16462306a36Sopenharmony_ci		err = 5;
16562306a36Sopenharmony_ci		goto release_exit;
16662306a36Sopenharmony_ci	}
16762306a36Sopenharmony_ci
16862306a36Sopenharmony_ci	if (bpf_cpumask_first_zero(cast(cpumask)) != 1) {
16962306a36Sopenharmony_ci		err = 6;
17062306a36Sopenharmony_ci		goto release_exit;
17162306a36Sopenharmony_ci	}
17262306a36Sopenharmony_ci
17362306a36Sopenharmony_cirelease_exit:
17462306a36Sopenharmony_ci	bpf_cpumask_release(cpumask);
17562306a36Sopenharmony_ci	return 0;
17662306a36Sopenharmony_ci}
17762306a36Sopenharmony_ci
17862306a36Sopenharmony_ciSEC("tp_btf/task_newtask")
17962306a36Sopenharmony_ciint BPF_PROG(test_firstand_nocpu, struct task_struct *task, u64 clone_flags)
18062306a36Sopenharmony_ci{
18162306a36Sopenharmony_ci	struct bpf_cpumask *mask1, *mask2;
18262306a36Sopenharmony_ci	u32 first;
18362306a36Sopenharmony_ci
18462306a36Sopenharmony_ci	if (!is_test_task())
18562306a36Sopenharmony_ci		return 0;
18662306a36Sopenharmony_ci
18762306a36Sopenharmony_ci	mask1 = create_cpumask();
18862306a36Sopenharmony_ci	if (!mask1)
18962306a36Sopenharmony_ci		return 0;
19062306a36Sopenharmony_ci
19162306a36Sopenharmony_ci	mask2 = create_cpumask();
19262306a36Sopenharmony_ci	if (!mask2)
19362306a36Sopenharmony_ci		goto release_exit;
19462306a36Sopenharmony_ci
19562306a36Sopenharmony_ci	bpf_cpumask_set_cpu(0, mask1);
19662306a36Sopenharmony_ci	bpf_cpumask_set_cpu(1, mask2);
19762306a36Sopenharmony_ci
19862306a36Sopenharmony_ci	first = bpf_cpumask_first_and(cast(mask1), cast(mask2));
19962306a36Sopenharmony_ci	if (first <= 1)
20062306a36Sopenharmony_ci		err = 3;
20162306a36Sopenharmony_ci
20262306a36Sopenharmony_cirelease_exit:
20362306a36Sopenharmony_ci	if (mask1)
20462306a36Sopenharmony_ci		bpf_cpumask_release(mask1);
20562306a36Sopenharmony_ci	if (mask2)
20662306a36Sopenharmony_ci		bpf_cpumask_release(mask2);
20762306a36Sopenharmony_ci	return 0;
20862306a36Sopenharmony_ci}
20962306a36Sopenharmony_ci
21062306a36Sopenharmony_ciSEC("tp_btf/task_newtask")
21162306a36Sopenharmony_ciint BPF_PROG(test_test_and_set_clear, struct task_struct *task, u64 clone_flags)
21262306a36Sopenharmony_ci{
21362306a36Sopenharmony_ci	struct bpf_cpumask *cpumask;
21462306a36Sopenharmony_ci
21562306a36Sopenharmony_ci	if (!is_test_task())
21662306a36Sopenharmony_ci		return 0;
21762306a36Sopenharmony_ci
21862306a36Sopenharmony_ci	cpumask = create_cpumask();
21962306a36Sopenharmony_ci	if (!cpumask)
22062306a36Sopenharmony_ci		return 0;
22162306a36Sopenharmony_ci
22262306a36Sopenharmony_ci	if (bpf_cpumask_test_and_set_cpu(0, cpumask)) {
22362306a36Sopenharmony_ci		err = 3;
22462306a36Sopenharmony_ci		goto release_exit;
22562306a36Sopenharmony_ci	}
22662306a36Sopenharmony_ci
22762306a36Sopenharmony_ci	if (!bpf_cpumask_test_and_set_cpu(0, cpumask)) {
22862306a36Sopenharmony_ci		err = 4;
22962306a36Sopenharmony_ci		goto release_exit;
23062306a36Sopenharmony_ci	}
23162306a36Sopenharmony_ci
23262306a36Sopenharmony_ci	if (!bpf_cpumask_test_and_clear_cpu(0, cpumask)) {
23362306a36Sopenharmony_ci		err = 5;
23462306a36Sopenharmony_ci		goto release_exit;
23562306a36Sopenharmony_ci	}
23662306a36Sopenharmony_ci
23762306a36Sopenharmony_cirelease_exit:
23862306a36Sopenharmony_ci	bpf_cpumask_release(cpumask);
23962306a36Sopenharmony_ci	return 0;
24062306a36Sopenharmony_ci}
24162306a36Sopenharmony_ci
24262306a36Sopenharmony_ciSEC("tp_btf/task_newtask")
24362306a36Sopenharmony_ciint BPF_PROG(test_and_or_xor, struct task_struct *task, u64 clone_flags)
24462306a36Sopenharmony_ci{
24562306a36Sopenharmony_ci	struct bpf_cpumask *mask1, *mask2, *dst1, *dst2;
24662306a36Sopenharmony_ci
24762306a36Sopenharmony_ci	if (!is_test_task())
24862306a36Sopenharmony_ci		return 0;
24962306a36Sopenharmony_ci
25062306a36Sopenharmony_ci	if (!create_cpumask_set(&mask1, &mask2, &dst1, &dst2))
25162306a36Sopenharmony_ci		return 0;
25262306a36Sopenharmony_ci
25362306a36Sopenharmony_ci	bpf_cpumask_set_cpu(0, mask1);
25462306a36Sopenharmony_ci	bpf_cpumask_set_cpu(1, mask2);
25562306a36Sopenharmony_ci
25662306a36Sopenharmony_ci	if (bpf_cpumask_and(dst1, cast(mask1), cast(mask2))) {
25762306a36Sopenharmony_ci		err = 6;
25862306a36Sopenharmony_ci		goto release_exit;
25962306a36Sopenharmony_ci	}
26062306a36Sopenharmony_ci	if (!bpf_cpumask_empty(cast(dst1))) {
26162306a36Sopenharmony_ci		err = 7;
26262306a36Sopenharmony_ci		goto release_exit;
26362306a36Sopenharmony_ci	}
26462306a36Sopenharmony_ci
26562306a36Sopenharmony_ci	bpf_cpumask_or(dst1, cast(mask1), cast(mask2));
26662306a36Sopenharmony_ci	if (!bpf_cpumask_test_cpu(0, cast(dst1))) {
26762306a36Sopenharmony_ci		err = 8;
26862306a36Sopenharmony_ci		goto release_exit;
26962306a36Sopenharmony_ci	}
27062306a36Sopenharmony_ci	if (!bpf_cpumask_test_cpu(1, cast(dst1))) {
27162306a36Sopenharmony_ci		err = 9;
27262306a36Sopenharmony_ci		goto release_exit;
27362306a36Sopenharmony_ci	}
27462306a36Sopenharmony_ci
27562306a36Sopenharmony_ci	bpf_cpumask_xor(dst2, cast(mask1), cast(mask2));
27662306a36Sopenharmony_ci	if (!bpf_cpumask_equal(cast(dst1), cast(dst2))) {
27762306a36Sopenharmony_ci		err = 10;
27862306a36Sopenharmony_ci		goto release_exit;
27962306a36Sopenharmony_ci	}
28062306a36Sopenharmony_ci
28162306a36Sopenharmony_cirelease_exit:
28262306a36Sopenharmony_ci	bpf_cpumask_release(mask1);
28362306a36Sopenharmony_ci	bpf_cpumask_release(mask2);
28462306a36Sopenharmony_ci	bpf_cpumask_release(dst1);
28562306a36Sopenharmony_ci	bpf_cpumask_release(dst2);
28662306a36Sopenharmony_ci	return 0;
28762306a36Sopenharmony_ci}
28862306a36Sopenharmony_ci
28962306a36Sopenharmony_ciSEC("tp_btf/task_newtask")
29062306a36Sopenharmony_ciint BPF_PROG(test_intersects_subset, struct task_struct *task, u64 clone_flags)
29162306a36Sopenharmony_ci{
29262306a36Sopenharmony_ci	struct bpf_cpumask *mask1, *mask2, *dst1, *dst2;
29362306a36Sopenharmony_ci
29462306a36Sopenharmony_ci	if (!is_test_task())
29562306a36Sopenharmony_ci		return 0;
29662306a36Sopenharmony_ci
29762306a36Sopenharmony_ci	if (!create_cpumask_set(&mask1, &mask2, &dst1, &dst2))
29862306a36Sopenharmony_ci		return 0;
29962306a36Sopenharmony_ci
30062306a36Sopenharmony_ci	bpf_cpumask_set_cpu(0, mask1);
30162306a36Sopenharmony_ci	bpf_cpumask_set_cpu(1, mask2);
30262306a36Sopenharmony_ci	if (bpf_cpumask_intersects(cast(mask1), cast(mask2))) {
30362306a36Sopenharmony_ci		err = 6;
30462306a36Sopenharmony_ci		goto release_exit;
30562306a36Sopenharmony_ci	}
30662306a36Sopenharmony_ci
30762306a36Sopenharmony_ci	bpf_cpumask_or(dst1, cast(mask1), cast(mask2));
30862306a36Sopenharmony_ci	if (!bpf_cpumask_subset(cast(mask1), cast(dst1))) {
30962306a36Sopenharmony_ci		err = 7;
31062306a36Sopenharmony_ci		goto release_exit;
31162306a36Sopenharmony_ci	}
31262306a36Sopenharmony_ci
31362306a36Sopenharmony_ci	if (!bpf_cpumask_subset(cast(mask2), cast(dst1))) {
31462306a36Sopenharmony_ci		err = 8;
31562306a36Sopenharmony_ci		goto release_exit;
31662306a36Sopenharmony_ci	}
31762306a36Sopenharmony_ci
31862306a36Sopenharmony_ci	if (bpf_cpumask_subset(cast(dst1), cast(mask1))) {
31962306a36Sopenharmony_ci		err = 9;
32062306a36Sopenharmony_ci		goto release_exit;
32162306a36Sopenharmony_ci	}
32262306a36Sopenharmony_ci
32362306a36Sopenharmony_cirelease_exit:
32462306a36Sopenharmony_ci	bpf_cpumask_release(mask1);
32562306a36Sopenharmony_ci	bpf_cpumask_release(mask2);
32662306a36Sopenharmony_ci	bpf_cpumask_release(dst1);
32762306a36Sopenharmony_ci	bpf_cpumask_release(dst2);
32862306a36Sopenharmony_ci	return 0;
32962306a36Sopenharmony_ci}
33062306a36Sopenharmony_ci
33162306a36Sopenharmony_ciSEC("tp_btf/task_newtask")
33262306a36Sopenharmony_ciint BPF_PROG(test_copy_any_anyand, struct task_struct *task, u64 clone_flags)
33362306a36Sopenharmony_ci{
33462306a36Sopenharmony_ci	struct bpf_cpumask *mask1, *mask2, *dst1, *dst2;
33562306a36Sopenharmony_ci	u32 cpu;
33662306a36Sopenharmony_ci
33762306a36Sopenharmony_ci	if (!is_test_task())
33862306a36Sopenharmony_ci		return 0;
33962306a36Sopenharmony_ci
34062306a36Sopenharmony_ci	if (!create_cpumask_set(&mask1, &mask2, &dst1, &dst2))
34162306a36Sopenharmony_ci		return 0;
34262306a36Sopenharmony_ci
34362306a36Sopenharmony_ci	bpf_cpumask_set_cpu(0, mask1);
34462306a36Sopenharmony_ci	bpf_cpumask_set_cpu(1, mask2);
34562306a36Sopenharmony_ci	bpf_cpumask_or(dst1, cast(mask1), cast(mask2));
34662306a36Sopenharmony_ci
34762306a36Sopenharmony_ci	cpu = bpf_cpumask_any_distribute(cast(mask1));
34862306a36Sopenharmony_ci	if (cpu != 0) {
34962306a36Sopenharmony_ci		err = 6;
35062306a36Sopenharmony_ci		goto release_exit;
35162306a36Sopenharmony_ci	}
35262306a36Sopenharmony_ci
35362306a36Sopenharmony_ci	cpu = bpf_cpumask_any_distribute(cast(dst2));
35462306a36Sopenharmony_ci	if (cpu < nr_cpus) {
35562306a36Sopenharmony_ci		err = 7;
35662306a36Sopenharmony_ci		goto release_exit;
35762306a36Sopenharmony_ci	}
35862306a36Sopenharmony_ci
35962306a36Sopenharmony_ci	bpf_cpumask_copy(dst2, cast(dst1));
36062306a36Sopenharmony_ci	if (!bpf_cpumask_equal(cast(dst1), cast(dst2))) {
36162306a36Sopenharmony_ci		err = 8;
36262306a36Sopenharmony_ci		goto release_exit;
36362306a36Sopenharmony_ci	}
36462306a36Sopenharmony_ci
36562306a36Sopenharmony_ci	cpu = bpf_cpumask_any_distribute(cast(dst2));
36662306a36Sopenharmony_ci	if (cpu > 1) {
36762306a36Sopenharmony_ci		err = 9;
36862306a36Sopenharmony_ci		goto release_exit;
36962306a36Sopenharmony_ci	}
37062306a36Sopenharmony_ci
37162306a36Sopenharmony_ci	cpu = bpf_cpumask_any_and_distribute(cast(mask1), cast(mask2));
37262306a36Sopenharmony_ci	if (cpu < nr_cpus) {
37362306a36Sopenharmony_ci		err = 10;
37462306a36Sopenharmony_ci		goto release_exit;
37562306a36Sopenharmony_ci	}
37662306a36Sopenharmony_ci
37762306a36Sopenharmony_cirelease_exit:
37862306a36Sopenharmony_ci	bpf_cpumask_release(mask1);
37962306a36Sopenharmony_ci	bpf_cpumask_release(mask2);
38062306a36Sopenharmony_ci	bpf_cpumask_release(dst1);
38162306a36Sopenharmony_ci	bpf_cpumask_release(dst2);
38262306a36Sopenharmony_ci	return 0;
38362306a36Sopenharmony_ci}
38462306a36Sopenharmony_ci
38562306a36Sopenharmony_ciSEC("tp_btf/task_newtask")
38662306a36Sopenharmony_ciint BPF_PROG(test_insert_leave, struct task_struct *task, u64 clone_flags)
38762306a36Sopenharmony_ci{
38862306a36Sopenharmony_ci	struct bpf_cpumask *cpumask;
38962306a36Sopenharmony_ci
39062306a36Sopenharmony_ci	cpumask = create_cpumask();
39162306a36Sopenharmony_ci	if (!cpumask)
39262306a36Sopenharmony_ci		return 0;
39362306a36Sopenharmony_ci
39462306a36Sopenharmony_ci	if (cpumask_map_insert(cpumask))
39562306a36Sopenharmony_ci		err = 3;
39662306a36Sopenharmony_ci
39762306a36Sopenharmony_ci	return 0;
39862306a36Sopenharmony_ci}
39962306a36Sopenharmony_ci
40062306a36Sopenharmony_ciSEC("tp_btf/task_newtask")
40162306a36Sopenharmony_ciint BPF_PROG(test_insert_remove_release, struct task_struct *task, u64 clone_flags)
40262306a36Sopenharmony_ci{
40362306a36Sopenharmony_ci	struct bpf_cpumask *cpumask;
40462306a36Sopenharmony_ci	struct __cpumask_map_value *v;
40562306a36Sopenharmony_ci
40662306a36Sopenharmony_ci	cpumask = create_cpumask();
40762306a36Sopenharmony_ci	if (!cpumask)
40862306a36Sopenharmony_ci		return 0;
40962306a36Sopenharmony_ci
41062306a36Sopenharmony_ci	if (cpumask_map_insert(cpumask)) {
41162306a36Sopenharmony_ci		err = 3;
41262306a36Sopenharmony_ci		return 0;
41362306a36Sopenharmony_ci	}
41462306a36Sopenharmony_ci
41562306a36Sopenharmony_ci	v = cpumask_map_value_lookup();
41662306a36Sopenharmony_ci	if (!v) {
41762306a36Sopenharmony_ci		err = 4;
41862306a36Sopenharmony_ci		return 0;
41962306a36Sopenharmony_ci	}
42062306a36Sopenharmony_ci
42162306a36Sopenharmony_ci	cpumask = bpf_kptr_xchg(&v->cpumask, NULL);
42262306a36Sopenharmony_ci	if (cpumask)
42362306a36Sopenharmony_ci		bpf_cpumask_release(cpumask);
42462306a36Sopenharmony_ci	else
42562306a36Sopenharmony_ci		err = 5;
42662306a36Sopenharmony_ci
42762306a36Sopenharmony_ci	return 0;
42862306a36Sopenharmony_ci}
42962306a36Sopenharmony_ci
43062306a36Sopenharmony_ciSEC("tp_btf/task_newtask")
43162306a36Sopenharmony_ciint BPF_PROG(test_global_mask_rcu, struct task_struct *task, u64 clone_flags)
43262306a36Sopenharmony_ci{
43362306a36Sopenharmony_ci	struct bpf_cpumask *local, *prev;
43462306a36Sopenharmony_ci
43562306a36Sopenharmony_ci	if (!is_test_task())
43662306a36Sopenharmony_ci		return 0;
43762306a36Sopenharmony_ci
43862306a36Sopenharmony_ci	local = create_cpumask();
43962306a36Sopenharmony_ci	if (!local)
44062306a36Sopenharmony_ci		return 0;
44162306a36Sopenharmony_ci
44262306a36Sopenharmony_ci	prev = bpf_kptr_xchg(&global_mask, local);
44362306a36Sopenharmony_ci	if (prev) {
44462306a36Sopenharmony_ci		bpf_cpumask_release(prev);
44562306a36Sopenharmony_ci		err = 3;
44662306a36Sopenharmony_ci		return 0;
44762306a36Sopenharmony_ci	}
44862306a36Sopenharmony_ci
44962306a36Sopenharmony_ci	bpf_rcu_read_lock();
45062306a36Sopenharmony_ci	local = global_mask;
45162306a36Sopenharmony_ci	if (!local) {
45262306a36Sopenharmony_ci		err = 4;
45362306a36Sopenharmony_ci		bpf_rcu_read_unlock();
45462306a36Sopenharmony_ci		return 0;
45562306a36Sopenharmony_ci	}
45662306a36Sopenharmony_ci
45762306a36Sopenharmony_ci	bpf_cpumask_test_cpu(0, (const struct cpumask *)local);
45862306a36Sopenharmony_ci	bpf_rcu_read_unlock();
45962306a36Sopenharmony_ci
46062306a36Sopenharmony_ci	return 0;
46162306a36Sopenharmony_ci}
46262306a36Sopenharmony_ci
46362306a36Sopenharmony_ciSEC("tp_btf/task_newtask")
46462306a36Sopenharmony_ci__success
46562306a36Sopenharmony_ciint BPF_PROG(test_refcount_null_tracking, struct task_struct *task, u64 clone_flags)
46662306a36Sopenharmony_ci{
46762306a36Sopenharmony_ci	struct bpf_cpumask *mask1, *mask2;
46862306a36Sopenharmony_ci
46962306a36Sopenharmony_ci	mask1 = bpf_cpumask_create();
47062306a36Sopenharmony_ci	mask2 = bpf_cpumask_create();
47162306a36Sopenharmony_ci
47262306a36Sopenharmony_ci	if (!mask1 || !mask2)
47362306a36Sopenharmony_ci		goto free_masks_return;
47462306a36Sopenharmony_ci
47562306a36Sopenharmony_ci	bpf_cpumask_test_cpu(0, (const struct cpumask *)mask1);
47662306a36Sopenharmony_ci	bpf_cpumask_test_cpu(0, (const struct cpumask *)mask2);
47762306a36Sopenharmony_ci
47862306a36Sopenharmony_cifree_masks_return:
47962306a36Sopenharmony_ci	if (mask1)
48062306a36Sopenharmony_ci		bpf_cpumask_release(mask1);
48162306a36Sopenharmony_ci	if (mask2)
48262306a36Sopenharmony_ci		bpf_cpumask_release(mask2);
48362306a36Sopenharmony_ci	return 0;
48462306a36Sopenharmony_ci}
485