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