Message ID | 20231007124522.34834-4-zhouchuyi@bytedance.com (mailing list archive) |
---|---|
State | Superseded |
Delegated to: | BPF |
Headers | show |
Series | Add Open-coded task, css_task and css iters | expand |
Hi Chuyi, kernel test robot noticed the following build warnings: [auto build test WARNING on bpf-next/master] url: https://github.com/intel-lab-lkp/linux/commits/Chuyi-Zhou/cgroup-Prepare-for-using-css_task_iter_-in-BPF/20231007-204750 base: https://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf-next.git master patch link: https://lore.kernel.org/r/20231007124522.34834-4-zhouchuyi%40bytedance.com patch subject: [PATCH bpf-next v4 3/8] bpf: Introduce task open coded iterator kfuncs config: m68k-allyesconfig (https://download.01.org/0day-ci/archive/20231007/202310072354.0oARP80g-lkp@intel.com/config) compiler: m68k-linux-gcc (GCC) 13.2.0 reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20231007/202310072354.0oARP80g-lkp@intel.com/reproduce) If you fix the issue in a separate patch/commit (i.e. not just a new version of the same patch/commit), kindly add following tags | Reported-by: kernel test robot <lkp@intel.com> | Closes: https://lore.kernel.org/oe-kbuild-all/202310072354.0oARP80g-lkp@intel.com/ All warnings (new ones prefixed by >>): kernel/bpf/task_iter.c:815:17: warning: no previous prototype for 'bpf_iter_css_task_new' [-Wmissing-prototypes] 815 | __bpf_kfunc int bpf_iter_css_task_new(struct bpf_iter_css_task *it, | ^~~~~~~~~~~~~~~~~~~~~ kernel/bpf/task_iter.c:840:33: warning: no previous prototype for 'bpf_iter_css_task_next' [-Wmissing-prototypes] 840 | __bpf_kfunc struct task_struct *bpf_iter_css_task_next(struct bpf_iter_css_task *it) | ^~~~~~~~~~~~~~~~~~~~~~ kernel/bpf/task_iter.c:849:18: warning: no previous prototype for 'bpf_iter_css_task_destroy' [-Wmissing-prototypes] 849 | __bpf_kfunc void bpf_iter_css_task_destroy(struct bpf_iter_css_task *it) | ^~~~~~~~~~~~~~~~~~~~~~~~~ >> kernel/bpf/task_iter.c:875:17: warning: no previous prototype for 'bpf_iter_task_new' [-Wmissing-prototypes] 875 | __bpf_kfunc int bpf_iter_task_new(struct bpf_iter_task *it, | ^~~~~~~~~~~~~~~~~ >> kernel/bpf/task_iter.c:903:33: warning: no previous prototype for 'bpf_iter_task_next' [-Wmissing-prototypes] 903 | __bpf_kfunc struct task_struct *bpf_iter_task_next(struct bpf_iter_task *it) | ^~~~~~~~~~~~~~~~~~ >> kernel/bpf/task_iter.c:937:18: warning: no previous prototype for 'bpf_iter_task_destroy' [-Wmissing-prototypes] 937 | __bpf_kfunc void bpf_iter_task_destroy(struct bpf_iter_task *it) | ^~~~~~~~~~~~~~~~~~~~~ In file included from <command-line>: kernel/bpf/task_iter.c: In function 'bpf_iter_task_new': include/linux/compiler_types.h:425:45: error: call to '__compiletime_assert_438' declared with attribute error: BUILD_BUG_ON failed: sizeof(struct bpf_iter_task_kern) != sizeof(struct bpf_iter_task) 425 | _compiletime_assert(condition, msg, __compiletime_assert_, __COUNTER__) | ^ include/linux/compiler_types.h:406:25: note: in definition of macro '__compiletime_assert' 406 | prefix ## suffix(); \ | ^~~~~~ include/linux/compiler_types.h:425:9: note: in expansion of macro '_compiletime_assert' 425 | _compiletime_assert(condition, msg, __compiletime_assert_, __COUNTER__) | ^~~~~~~~~~~~~~~~~~~ include/linux/build_bug.h:39:37: note: in expansion of macro 'compiletime_assert' 39 | #define BUILD_BUG_ON_MSG(cond, msg) compiletime_assert(!(cond), msg) | ^~~~~~~~~~~~~~~~~~ include/linux/build_bug.h:50:9: note: in expansion of macro 'BUILD_BUG_ON_MSG' 50 | BUILD_BUG_ON_MSG(condition, "BUILD_BUG_ON failed: " #condition) | ^~~~~~~~~~~~~~~~ kernel/bpf/task_iter.c:880:9: note: in expansion of macro 'BUILD_BUG_ON' 880 | BUILD_BUG_ON(sizeof(struct bpf_iter_task_kern) != sizeof(struct bpf_iter_task)); | ^~~~~~~~~~~~ vim +/bpf_iter_task_new +875 kernel/bpf/task_iter.c 814 > 815 __bpf_kfunc int bpf_iter_css_task_new(struct bpf_iter_css_task *it, 816 struct cgroup_subsys_state *css, unsigned int flags) 817 { 818 struct bpf_iter_css_task_kern *kit = (void *)it; 819 820 BUILD_BUG_ON(sizeof(struct bpf_iter_css_task_kern) != sizeof(struct bpf_iter_css_task)); 821 BUILD_BUG_ON(__alignof__(struct bpf_iter_css_task_kern) != 822 __alignof__(struct bpf_iter_css_task)); 823 kit->css_it = NULL; 824 switch (flags) { 825 case CSS_TASK_ITER_PROCS | CSS_TASK_ITER_THREADED: 826 case CSS_TASK_ITER_PROCS: 827 case 0: 828 break; 829 default: 830 return -EINVAL; 831 } 832 833 kit->css_it = bpf_mem_alloc(&bpf_global_ma, sizeof(struct css_task_iter)); 834 if (!kit->css_it) 835 return -ENOMEM; 836 css_task_iter_start(css, flags, kit->css_it); 837 return 0; 838 } 839 > 840 __bpf_kfunc struct task_struct *bpf_iter_css_task_next(struct bpf_iter_css_task *it) 841 { 842 struct bpf_iter_css_task_kern *kit = (void *)it; 843 844 if (!kit->css_it) 845 return NULL; 846 return css_task_iter_next(kit->css_it); 847 } 848 > 849 __bpf_kfunc void bpf_iter_css_task_destroy(struct bpf_iter_css_task *it) 850 { 851 struct bpf_iter_css_task_kern *kit = (void *)it; 852 853 if (!kit->css_it) 854 return; 855 css_task_iter_end(kit->css_it); 856 bpf_mem_free(&bpf_global_ma, kit->css_it); 857 } 858 859 struct bpf_iter_task { 860 __u64 __opaque[3]; 861 } __attribute__((aligned(8))); 862 863 struct bpf_iter_task_kern { 864 struct task_struct *task; 865 struct task_struct *pos; 866 unsigned int flags; 867 } __attribute__((aligned(8))); 868 869 enum { 870 BPF_TASK_ITER_ALL_PROCS, 871 BPF_TASK_ITER_ALL_THREADS, 872 BPF_TASK_ITER_PROC_THREADS 873 }; 874 > 875 __bpf_kfunc int bpf_iter_task_new(struct bpf_iter_task *it, 876 struct task_struct *task, unsigned int flags) 877 { 878 struct bpf_iter_task_kern *kit = (void *)it; 879 880 BUILD_BUG_ON(sizeof(struct bpf_iter_task_kern) != sizeof(struct bpf_iter_task)); 881 BUILD_BUG_ON(__alignof__(struct bpf_iter_task_kern) != 882 __alignof__(struct bpf_iter_task)); 883 884 kit->task = kit->pos = NULL; 885 switch (flags) { 886 case BPF_TASK_ITER_ALL_THREADS: 887 case BPF_TASK_ITER_ALL_PROCS: 888 case BPF_TASK_ITER_PROC_THREADS: 889 break; 890 default: 891 return -EINVAL; 892 } 893 894 if (flags == BPF_TASK_ITER_PROC_THREADS) 895 kit->task = task; 896 else 897 kit->task = &init_task; 898 kit->pos = kit->task; 899 kit->flags = flags; 900 return 0; 901 } 902 > 903 __bpf_kfunc struct task_struct *bpf_iter_task_next(struct bpf_iter_task *it) 904 { 905 struct bpf_iter_task_kern *kit = (void *)it; 906 struct task_struct *pos; 907 unsigned int flags; 908 909 flags = kit->flags; 910 pos = kit->pos; 911 912 if (!pos) 913 goto out; 914 915 if (flags == BPF_TASK_ITER_ALL_PROCS) 916 goto get_next_task; 917 918 kit->pos = next_thread(kit->pos); 919 if (kit->pos == kit->task) { 920 if (flags == BPF_TASK_ITER_PROC_THREADS) { 921 kit->pos = NULL; 922 goto out; 923 } 924 } else 925 goto out; 926 927 get_next_task: 928 kit->pos = next_task(kit->pos); 929 kit->task = kit->pos; 930 if (kit->pos == &init_task) 931 kit->pos = NULL; 932 933 out: 934 return pos; 935 } 936 > 937 __bpf_kfunc void bpf_iter_task_destroy(struct bpf_iter_task *it) 938 { 939 } 940
diff --git a/kernel/bpf/helpers.c b/kernel/bpf/helpers.c index 8699cabb52b2..8111437a999e 100644 --- a/kernel/bpf/helpers.c +++ b/kernel/bpf/helpers.c @@ -2552,6 +2552,9 @@ BTF_ID_FLAGS(func, bpf_iter_num_destroy, KF_ITER_DESTROY) BTF_ID_FLAGS(func, bpf_iter_css_task_new, KF_ITER_NEW | KF_TRUSTED_ARGS) BTF_ID_FLAGS(func, bpf_iter_css_task_next, KF_ITER_NEXT | KF_RET_NULL) BTF_ID_FLAGS(func, bpf_iter_css_task_destroy, KF_ITER_DESTROY) +BTF_ID_FLAGS(func, bpf_iter_task_new, KF_ITER_NEW | KF_TRUSTED_ARGS) +BTF_ID_FLAGS(func, bpf_iter_task_next, KF_ITER_NEXT | KF_RET_NULL) +BTF_ID_FLAGS(func, bpf_iter_task_destroy, KF_ITER_DESTROY) BTF_ID_FLAGS(func, bpf_dynptr_adjust) BTF_ID_FLAGS(func, bpf_dynptr_is_null) BTF_ID_FLAGS(func, bpf_dynptr_is_rdonly) diff --git a/kernel/bpf/task_iter.c b/kernel/bpf/task_iter.c index 2cfcb4dd8a37..c2e1c3cbffea 100644 --- a/kernel/bpf/task_iter.c +++ b/kernel/bpf/task_iter.c @@ -856,6 +856,88 @@ __bpf_kfunc void bpf_iter_css_task_destroy(struct bpf_iter_css_task *it) bpf_mem_free(&bpf_global_ma, kit->css_it); } +struct bpf_iter_task { + __u64 __opaque[3]; +} __attribute__((aligned(8))); + +struct bpf_iter_task_kern { + struct task_struct *task; + struct task_struct *pos; + unsigned int flags; +} __attribute__((aligned(8))); + +enum { + BPF_TASK_ITER_ALL_PROCS, + BPF_TASK_ITER_ALL_THREADS, + BPF_TASK_ITER_PROC_THREADS +}; + +__bpf_kfunc int bpf_iter_task_new(struct bpf_iter_task *it, + struct task_struct *task, unsigned int flags) +{ + struct bpf_iter_task_kern *kit = (void *)it; + + BUILD_BUG_ON(sizeof(struct bpf_iter_task_kern) != sizeof(struct bpf_iter_task)); + BUILD_BUG_ON(__alignof__(struct bpf_iter_task_kern) != + __alignof__(struct bpf_iter_task)); + + kit->task = kit->pos = NULL; + switch (flags) { + case BPF_TASK_ITER_ALL_THREADS: + case BPF_TASK_ITER_ALL_PROCS: + case BPF_TASK_ITER_PROC_THREADS: + break; + default: + return -EINVAL; + } + + if (flags == BPF_TASK_ITER_PROC_THREADS) + kit->task = task; + else + kit->task = &init_task; + kit->pos = kit->task; + kit->flags = flags; + return 0; +} + +__bpf_kfunc struct task_struct *bpf_iter_task_next(struct bpf_iter_task *it) +{ + struct bpf_iter_task_kern *kit = (void *)it; + struct task_struct *pos; + unsigned int flags; + + flags = kit->flags; + pos = kit->pos; + + if (!pos) + goto out; + + if (flags == BPF_TASK_ITER_ALL_PROCS) + goto get_next_task; + + kit->pos = next_thread(kit->pos); + if (kit->pos == kit->task) { + if (flags == BPF_TASK_ITER_PROC_THREADS) { + kit->pos = NULL; + goto out; + } + } else + goto out; + +get_next_task: + kit->pos = next_task(kit->pos); + kit->task = kit->pos; + if (kit->pos == &init_task) + kit->pos = NULL; + +out: + return pos; +} + +__bpf_kfunc void bpf_iter_task_destroy(struct bpf_iter_task *it) +{ +} + DEFINE_PER_CPU(struct mmap_unlock_irq_work, mmap_unlock_work); static void do_mmap_read_unlock(struct irq_work *entry) diff --git a/tools/testing/selftests/bpf/bpf_experimental.h b/tools/testing/selftests/bpf/bpf_experimental.h index 8b53537e0f27..1ec82997cce7 100644 --- a/tools/testing/selftests/bpf/bpf_experimental.h +++ b/tools/testing/selftests/bpf/bpf_experimental.h @@ -457,5 +457,10 @@ extern int bpf_iter_css_task_new(struct bpf_iter_css_task *it, extern struct task_struct *bpf_iter_css_task_next(struct bpf_iter_css_task *it) __weak __ksym; extern void bpf_iter_css_task_destroy(struct bpf_iter_css_task *it) __weak __ksym; +struct bpf_iter_task; +extern int bpf_iter_task_new(struct bpf_iter_task *it, + struct task_struct *task, unsigned int flags) __weak __ksym; +extern struct task_struct *bpf_iter_task_next(struct bpf_iter_task *it) __weak __ksym; +extern void bpf_iter_task_destroy(struct bpf_iter_task *it) __weak __ksym; #endif
This patch adds kfuncs bpf_iter_task_{new,next,destroy} which allow creation and manipulation of struct bpf_iter_task in open-coded iterator style. BPF programs can use these kfuncs or through bpf_for_each macro to iterate all processes in the system. The API design keep consistent with SEC("iter/task"). bpf_iter_task_new() accepts a specific task and iterating type which allows: 1. iterating all process in the system(BPF_TASK_ITER_ALL_PROCS) 2. iterating all threads in the system(BPF_TASK_ITER_ALL_THREADS) 3. iterating all threads of a specific task(BPF_TASK_ITER_PROC_THREADS) Signed-off-by: Chuyi Zhou <zhouchuyi@bytedance.com> --- kernel/bpf/helpers.c | 3 + kernel/bpf/task_iter.c | 82 +++++++++++++++++++ .../testing/selftests/bpf/bpf_experimental.h | 5 ++ 3 files changed, 90 insertions(+)