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 "cgrp_kfunc_common.h" 9 10 char _license[] SEC("license") = "GPL"; 11 12 int err, pid, invocations; 13 14 /* Prototype for all of the program trace events below: 15 * 16 * TRACE_EVENT(cgroup_mkdir, 17 * TP_PROTO(struct cgroup *cgrp, const char *path), 18 * TP_ARGS(cgrp, path) 19 */ 20 21 static bool is_test_kfunc_task(void) 22 { 23 int cur_pid = bpf_get_current_pid_tgid() >> 32; 24 bool same = pid == cur_pid; 25 26 if (same) 27 __sync_fetch_and_add(&invocations, 1); 28 29 return same; 30 } 31 32 SEC("tp_btf/cgroup_mkdir") 33 int BPF_PROG(test_cgrp_acquire_release_argument, struct cgroup *cgrp, const char *path) 34 { 35 struct cgroup *acquired; 36 37 if (!is_test_kfunc_task()) 38 return 0; 39 40 acquired = bpf_cgroup_acquire(cgrp); 41 bpf_cgroup_release(acquired); 42 43 return 0; 44 } 45 46 SEC("tp_btf/cgroup_mkdir") 47 int BPF_PROG(test_cgrp_acquire_leave_in_map, struct cgroup *cgrp, const char *path) 48 { 49 long status; 50 51 if (!is_test_kfunc_task()) 52 return 0; 53 54 status = cgrps_kfunc_map_insert(cgrp); 55 if (status) 56 err = 1; 57 58 return 0; 59 } 60 61 SEC("tp_btf/cgroup_mkdir") 62 int BPF_PROG(test_cgrp_xchg_release, struct cgroup *cgrp, const char *path) 63 { 64 struct cgroup *kptr; 65 struct __cgrps_kfunc_map_value *v; 66 long status; 67 68 if (!is_test_kfunc_task()) 69 return 0; 70 71 status = cgrps_kfunc_map_insert(cgrp); 72 if (status) { 73 err = 1; 74 return 0; 75 } 76 77 v = cgrps_kfunc_map_value_lookup(cgrp); 78 if (!v) { 79 err = 2; 80 return 0; 81 } 82 83 kptr = bpf_kptr_xchg(&v->cgrp, NULL); 84 if (!kptr) { 85 err = 3; 86 return 0; 87 } 88 89 bpf_cgroup_release(kptr); 90 91 return 0; 92 } 93 94 SEC("tp_btf/cgroup_mkdir") 95 int BPF_PROG(test_cgrp_get_release, struct cgroup *cgrp, const char *path) 96 { 97 struct cgroup *kptr; 98 struct __cgrps_kfunc_map_value *v; 99 long status; 100 101 if (!is_test_kfunc_task()) 102 return 0; 103 104 status = cgrps_kfunc_map_insert(cgrp); 105 if (status) { 106 err = 1; 107 return 0; 108 } 109 110 v = cgrps_kfunc_map_value_lookup(cgrp); 111 if (!v) { 112 err = 2; 113 return 0; 114 } 115 116 kptr = bpf_cgroup_kptr_get(&v->cgrp); 117 if (!kptr) { 118 err = 3; 119 return 0; 120 } 121 122 bpf_cgroup_release(kptr); 123 124 return 0; 125 } 126 127 SEC("tp_btf/cgroup_mkdir") 128 int BPF_PROG(test_cgrp_get_ancestors, struct cgroup *cgrp, const char *path) 129 { 130 struct cgroup *self, *ancestor1, *invalid; 131 132 if (!is_test_kfunc_task()) 133 return 0; 134 135 self = bpf_cgroup_ancestor(cgrp, cgrp->level); 136 if (!self) { 137 err = 1; 138 return 0; 139 } 140 141 if (self->self.id != cgrp->self.id) { 142 bpf_cgroup_release(self); 143 err = 2; 144 return 0; 145 } 146 bpf_cgroup_release(self); 147 148 ancestor1 = bpf_cgroup_ancestor(cgrp, cgrp->level - 1); 149 if (!ancestor1) { 150 err = 3; 151 return 0; 152 } 153 bpf_cgroup_release(ancestor1); 154 155 invalid = bpf_cgroup_ancestor(cgrp, 10000); 156 if (invalid) { 157 bpf_cgroup_release(invalid); 158 err = 4; 159 return 0; 160 } 161 162 invalid = bpf_cgroup_ancestor(cgrp, -1); 163 if (invalid) { 164 bpf_cgroup_release(invalid); 165 err = 5; 166 return 0; 167 } 168 169 return 0; 170 } 171