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

selftests/bpf: Add tests for css_task iter combining with cgroup iter

This patch adds a test which demonstrates how css_task iter can be combined
with cgroup iter and it won't cause deadlock, though cgroup iter is not
sleepable.

Signed-off-by: Chuyi Zhou <zhouchuyi@bytedance.com>
Acked-by: Yonghong Song <yonghong.song@linux.dev>
Link: https://lore.kernel.org/r/20231031050438.93297-3-zhouchuyi@bytedance.com
Signed-off-by: Alexei Starovoitov <ast@kernel.org>

authored by

Chuyi Zhou and committed by
Alexei Starovoitov
f49843af 3091b667

+77
+33
tools/testing/selftests/bpf/prog_tests/cgroup_iter.c
··· 4 4 #include <test_progs.h> 5 5 #include <bpf/libbpf.h> 6 6 #include <bpf/btf.h> 7 + #include "iters_css_task.skel.h" 7 8 #include "cgroup_iter.skel.h" 8 9 #include "cgroup_helpers.h" 9 10 ··· 264 263 close(cgrp_fd); 265 264 } 266 265 266 + static void test_walk_self_only_css_task(void) 267 + { 268 + struct iters_css_task *skel; 269 + int err; 270 + 271 + skel = iters_css_task__open(); 272 + if (!ASSERT_OK_PTR(skel, "skel_open")) 273 + return; 274 + 275 + bpf_program__set_autoload(skel->progs.cgroup_id_printer, true); 276 + 277 + err = iters_css_task__load(skel); 278 + if (!ASSERT_OK(err, "skel_load")) 279 + goto cleanup; 280 + 281 + err = join_cgroup(cg_path[CHILD2]); 282 + if (!ASSERT_OK(err, "join_cgroup")) 283 + goto cleanup; 284 + 285 + skel->bss->target_pid = getpid(); 286 + snprintf(expected_output, sizeof(expected_output), 287 + PROLOGUE "%8llu\n" EPILOGUE, cg_id[CHILD2]); 288 + read_from_cgroup_iter(skel->progs.cgroup_id_printer, cg_fd[CHILD2], 289 + BPF_CGROUP_ITER_SELF_ONLY, "test_walk_self_only_css_task"); 290 + ASSERT_EQ(skel->bss->css_task_cnt, 1, "css_task_cnt"); 291 + cleanup: 292 + iters_css_task__destroy(skel); 293 + } 294 + 267 295 void test_cgroup_iter(void) 268 296 { 269 297 struct cgroup_iter *skel = NULL; ··· 323 293 test_walk_self_only(skel); 324 294 if (test__start_subtest("cgroup_iter__dead_self_only")) 325 295 test_walk_dead_self_only(skel); 296 + if (test__start_subtest("cgroup_iter__self_only_css_task")) 297 + test_walk_self_only_css_task(); 298 + 326 299 out: 327 300 cgroup_iter__destroy(skel); 328 301 cleanup_cgroups();
+44
tools/testing/selftests/bpf/progs/iters_css_task.c
··· 10 10 11 11 char _license[] SEC("license") = "GPL"; 12 12 13 + struct cgroup *bpf_cgroup_acquire(struct cgroup *p) __ksym; 13 14 struct cgroup *bpf_cgroup_from_id(u64 cgid) __ksym; 14 15 void bpf_cgroup_release(struct cgroup *p) __ksym; 15 16 ··· 45 44 bpf_cgroup_release(cgrp); 46 45 47 46 return -EPERM; 47 + } 48 + 49 + static inline u64 cgroup_id(struct cgroup *cgrp) 50 + { 51 + return cgrp->kn->id; 52 + } 53 + 54 + SEC("?iter/cgroup") 55 + int cgroup_id_printer(struct bpf_iter__cgroup *ctx) 56 + { 57 + struct seq_file *seq = ctx->meta->seq; 58 + struct cgroup *cgrp, *acquired; 59 + struct cgroup_subsys_state *css; 60 + struct task_struct *task; 61 + u64 cgrp_id; 62 + 63 + cgrp = ctx->cgroup; 64 + 65 + /* epilogue */ 66 + if (cgrp == NULL) { 67 + BPF_SEQ_PRINTF(seq, "epilogue\n"); 68 + return 0; 69 + } 70 + 71 + /* prologue */ 72 + if (ctx->meta->seq_num == 0) 73 + BPF_SEQ_PRINTF(seq, "prologue\n"); 74 + 75 + cgrp_id = cgroup_id(cgrp); 76 + 77 + BPF_SEQ_PRINTF(seq, "%8llu\n", cgrp_id); 78 + 79 + acquired = bpf_cgroup_from_id(cgrp_id); 80 + if (!acquired) 81 + return 0; 82 + css = &acquired->self; 83 + css_task_cnt = 0; 84 + bpf_for_each(css_task, task, css, CSS_TASK_ITER_PROCS) { 85 + if (task->pid == target_pid) 86 + css_task_cnt++; 87 + } 88 + bpf_cgroup_release(acquired); 89 + return 0; 48 90 }