Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

bpf: Add sleepable prog tests for cgrp local storage

Add three tests for cgrp local storage support for sleepable progs.
Two tests can load and run properly, one for cgroup_iter, another
for passing current->cgroups->dfl_cgrp to bpf_cgrp_storage_get()
helper. One test has bpf_rcu_read_lock() and failed to load.

Signed-off-by: Yonghong Song <yhs@fb.com>
Link: https://lore.kernel.org/r/20221201050449.2785613-1-yhs@fb.com
Signed-off-by: Alexei Starovoitov <ast@kernel.org>

authored by

Yonghong Song and committed by
Alexei Starovoitov
41d76c72 2c40d97d

+174
+94
tools/testing/selftests/bpf/prog_tests/cgrp_local_storage.c
··· 10 10 #include "cgrp_ls_recursion.skel.h" 11 11 #include "cgrp_ls_attach_cgroup.skel.h" 12 12 #include "cgrp_ls_negative.skel.h" 13 + #include "cgrp_ls_sleepable.skel.h" 13 14 #include "network_helpers.h" 15 + #include "cgroup_helpers.h" 14 16 15 17 struct socket_cookie { 16 18 __u64 cookie_key; ··· 152 150 } 153 151 } 154 152 153 + static void test_cgroup_iter_sleepable(int cgroup_fd, __u64 cgroup_id) 154 + { 155 + DECLARE_LIBBPF_OPTS(bpf_iter_attach_opts, opts); 156 + union bpf_iter_link_info linfo; 157 + struct cgrp_ls_sleepable *skel; 158 + struct bpf_link *link; 159 + int err, iter_fd; 160 + char buf[16]; 161 + 162 + skel = cgrp_ls_sleepable__open(); 163 + if (!ASSERT_OK_PTR(skel, "skel_open")) 164 + return; 165 + 166 + bpf_program__set_autoload(skel->progs.cgroup_iter, true); 167 + err = cgrp_ls_sleepable__load(skel); 168 + if (!ASSERT_OK(err, "skel_load")) 169 + goto out; 170 + 171 + memset(&linfo, 0, sizeof(linfo)); 172 + linfo.cgroup.cgroup_fd = cgroup_fd; 173 + linfo.cgroup.order = BPF_CGROUP_ITER_SELF_ONLY; 174 + opts.link_info = &linfo; 175 + opts.link_info_len = sizeof(linfo); 176 + link = bpf_program__attach_iter(skel->progs.cgroup_iter, &opts); 177 + if (!ASSERT_OK_PTR(link, "attach_iter")) 178 + goto out; 179 + 180 + iter_fd = bpf_iter_create(bpf_link__fd(link)); 181 + if (!ASSERT_GE(iter_fd, 0, "iter_create")) 182 + goto out; 183 + 184 + /* trigger the program run */ 185 + (void)read(iter_fd, buf, sizeof(buf)); 186 + 187 + ASSERT_EQ(skel->bss->cgroup_id, cgroup_id, "cgroup_id"); 188 + 189 + close(iter_fd); 190 + out: 191 + cgrp_ls_sleepable__destroy(skel); 192 + } 193 + 194 + static void test_no_rcu_lock(__u64 cgroup_id) 195 + { 196 + struct cgrp_ls_sleepable *skel; 197 + int err; 198 + 199 + skel = cgrp_ls_sleepable__open(); 200 + if (!ASSERT_OK_PTR(skel, "skel_open")) 201 + return; 202 + 203 + skel->bss->target_pid = syscall(SYS_gettid); 204 + 205 + bpf_program__set_autoload(skel->progs.no_rcu_lock, true); 206 + err = cgrp_ls_sleepable__load(skel); 207 + if (!ASSERT_OK(err, "skel_load")) 208 + goto out; 209 + 210 + err = cgrp_ls_sleepable__attach(skel); 211 + if (!ASSERT_OK(err, "skel_attach")) 212 + goto out; 213 + 214 + syscall(SYS_getpgid); 215 + 216 + ASSERT_EQ(skel->bss->cgroup_id, cgroup_id, "cgroup_id"); 217 + out: 218 + cgrp_ls_sleepable__destroy(skel); 219 + } 220 + 221 + static void test_rcu_lock(void) 222 + { 223 + struct cgrp_ls_sleepable *skel; 224 + int err; 225 + 226 + skel = cgrp_ls_sleepable__open(); 227 + if (!ASSERT_OK_PTR(skel, "skel_open")) 228 + return; 229 + 230 + bpf_program__set_autoload(skel->progs.yes_rcu_lock, true); 231 + err = cgrp_ls_sleepable__load(skel); 232 + ASSERT_ERR(err, "skel_load"); 233 + 234 + cgrp_ls_sleepable__destroy(skel); 235 + } 236 + 155 237 void test_cgrp_local_storage(void) 156 238 { 239 + __u64 cgroup_id; 157 240 int cgroup_fd; 158 241 159 242 cgroup_fd = test__join_cgroup("/cgrp_local_storage"); 160 243 if (!ASSERT_GE(cgroup_fd, 0, "join_cgroup /cgrp_local_storage")) 161 244 return; 162 245 246 + cgroup_id = get_cgroup_id("/cgrp_local_storage"); 163 247 if (test__start_subtest("tp_btf")) 164 248 test_tp_btf(cgroup_fd); 165 249 if (test__start_subtest("attach_cgroup")) ··· 254 166 test_recursion(cgroup_fd); 255 167 if (test__start_subtest("negative")) 256 168 test_negative(); 169 + if (test__start_subtest("cgroup_iter_sleepable")) 170 + test_cgroup_iter_sleepable(cgroup_fd, cgroup_id); 171 + if (test__start_subtest("no_rcu_lock")) 172 + test_no_rcu_lock(cgroup_id); 173 + if (test__start_subtest("rcu_lock")) 174 + test_rcu_lock(); 257 175 258 176 close(cgroup_fd); 259 177 }
+80
tools/testing/selftests/bpf/progs/cgrp_ls_sleepable.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* Copyright (c) 2022 Meta Platforms, Inc. and affiliates. */ 3 + 4 + #include "bpf_iter.h" 5 + #include <bpf/bpf_helpers.h> 6 + #include <bpf/bpf_tracing.h> 7 + #include "bpf_misc.h" 8 + 9 + char _license[] SEC("license") = "GPL"; 10 + 11 + struct { 12 + __uint(type, BPF_MAP_TYPE_CGRP_STORAGE); 13 + __uint(map_flags, BPF_F_NO_PREALLOC); 14 + __type(key, int); 15 + __type(value, long); 16 + } map_a SEC(".maps"); 17 + 18 + __u32 target_pid; 19 + __u64 cgroup_id; 20 + 21 + void bpf_rcu_read_lock(void) __ksym; 22 + void bpf_rcu_read_unlock(void) __ksym; 23 + 24 + SEC("?iter.s/cgroup") 25 + int cgroup_iter(struct bpf_iter__cgroup *ctx) 26 + { 27 + struct seq_file *seq = ctx->meta->seq; 28 + struct cgroup *cgrp = ctx->cgroup; 29 + long *ptr; 30 + 31 + if (cgrp == NULL) 32 + return 0; 33 + 34 + ptr = bpf_cgrp_storage_get(&map_a, cgrp, 0, 35 + BPF_LOCAL_STORAGE_GET_F_CREATE); 36 + if (ptr) 37 + cgroup_id = cgrp->kn->id; 38 + return 0; 39 + } 40 + 41 + SEC("?fentry.s/" SYS_PREFIX "sys_getpgid") 42 + int no_rcu_lock(void *ctx) 43 + { 44 + struct task_struct *task; 45 + struct cgroup *cgrp; 46 + long *ptr; 47 + 48 + task = bpf_get_current_task_btf(); 49 + if (task->pid != target_pid) 50 + return 0; 51 + 52 + /* ptr_to_btf_id semantics. should work. */ 53 + cgrp = task->cgroups->dfl_cgrp; 54 + ptr = bpf_cgrp_storage_get(&map_a, cgrp, 0, 55 + BPF_LOCAL_STORAGE_GET_F_CREATE); 56 + if (ptr) 57 + cgroup_id = cgrp->kn->id; 58 + return 0; 59 + } 60 + 61 + SEC("?fentry.s/" SYS_PREFIX "sys_getpgid") 62 + int yes_rcu_lock(void *ctx) 63 + { 64 + struct task_struct *task; 65 + struct cgroup *cgrp; 66 + long *ptr; 67 + 68 + task = bpf_get_current_task_btf(); 69 + if (task->pid != target_pid) 70 + return 0; 71 + 72 + bpf_rcu_read_lock(); 73 + cgrp = task->cgroups->dfl_cgrp; 74 + /* cgrp is untrusted and cannot pass to bpf_cgrp_storage_get() helper. */ 75 + ptr = bpf_cgrp_storage_get(&map_a, cgrp, 0, BPF_LOCAL_STORAGE_GET_F_CREATE); 76 + if (ptr) 77 + cgroup_id = cgrp->kn->id; 78 + bpf_rcu_read_unlock(); 79 + return 0; 80 + }