1 // SPDX-License-Identifier: GPL-2.0 2 /* Copyright (c) 2022 Meta Platforms, Inc. and affiliates. */ 3 4 #include <vmlinux.h> 5 #include <bpf/bpf_tracing.h> 6 #include <bpf/bpf_helpers.h> 7 8 #include "task_kfunc_common.h" 9 10 char _license[] SEC("license") = "GPL"; 11 12 int err, pid; 13 14 /* Prototype for all of the program trace events below: 15 * 16 * TRACE_EVENT(task_newtask, 17 * TP_PROTO(struct task_struct *p, u64 clone_flags) 18 */ 19 20 static bool is_test_kfunc_task(void) 21 { 22 int cur_pid = bpf_get_current_pid_tgid() >> 32; 23 24 return pid == cur_pid; 25 } 26 27 static int test_acquire_release(struct task_struct *task) 28 { 29 struct task_struct *acquired; 30 31 acquired = bpf_task_acquire(task); 32 bpf_task_release(acquired); 33 34 return 0; 35 } 36 37 SEC("tp_btf/task_newtask") 38 int BPF_PROG(test_task_acquire_release_argument, struct task_struct *task, u64 clone_flags) 39 { 40 if (!is_test_kfunc_task()) 41 return 0; 42 43 return test_acquire_release(task); 44 } 45 46 SEC("tp_btf/task_newtask") 47 int BPF_PROG(test_task_acquire_release_current, struct task_struct *task, u64 clone_flags) 48 { 49 if (!is_test_kfunc_task()) 50 return 0; 51 52 return test_acquire_release(bpf_get_current_task_btf()); 53 } 54 55 SEC("tp_btf/task_newtask") 56 int BPF_PROG(test_task_acquire_leave_in_map, struct task_struct *task, u64 clone_flags) 57 { 58 long status; 59 60 if (!is_test_kfunc_task()) 61 return 0; 62 63 status = tasks_kfunc_map_insert(task); 64 if (status) 65 err = 1; 66 67 return 0; 68 } 69 70 SEC("tp_btf/task_newtask") 71 int BPF_PROG(test_task_xchg_release, struct task_struct *task, u64 clone_flags) 72 { 73 struct task_struct *kptr; 74 struct __tasks_kfunc_map_value *v; 75 long status; 76 77 if (!is_test_kfunc_task()) 78 return 0; 79 80 status = tasks_kfunc_map_insert(task); 81 if (status) { 82 err = 1; 83 return 0; 84 } 85 86 v = tasks_kfunc_map_value_lookup(task); 87 if (!v) { 88 err = 2; 89 return 0; 90 } 91 92 kptr = bpf_kptr_xchg(&v->task, NULL); 93 if (!kptr) { 94 err = 3; 95 return 0; 96 } 97 98 bpf_task_release(kptr); 99 100 return 0; 101 } 102 103 SEC("tp_btf/task_newtask") 104 int BPF_PROG(test_task_get_release, struct task_struct *task, u64 clone_flags) 105 { 106 struct task_struct *kptr; 107 struct __tasks_kfunc_map_value *v; 108 long status; 109 110 if (!is_test_kfunc_task()) 111 return 0; 112 113 status = tasks_kfunc_map_insert(task); 114 if (status) { 115 err = 1; 116 return 0; 117 } 118 119 v = tasks_kfunc_map_value_lookup(task); 120 if (!v) { 121 err = 2; 122 return 0; 123 } 124 125 kptr = bpf_task_kptr_get(&v->task); 126 if (!kptr) { 127 err = 3; 128 return 0; 129 } 130 131 bpf_task_release(kptr); 132 133 return 0; 134 } 135 136 SEC("tp_btf/task_newtask") 137 int BPF_PROG(test_task_current_acquire_release, struct task_struct *task, u64 clone_flags) 138 { 139 struct task_struct *current, *acquired; 140 141 if (!is_test_kfunc_task()) 142 return 0; 143 144 current = bpf_get_current_task_btf(); 145 acquired = bpf_task_acquire(current); 146 bpf_task_release(acquired); 147 148 return 0; 149 } 150