Message ID | 20200504062609.2049143-1-yhs@fb.com |
---|---|
State | Changes Requested |
Delegated to: | BPF Maintainers |
Headers | show |
Series | bpf: implement bpf iterator for kernel data | expand |
On Sun, May 3, 2020 at 11:27 PM Yonghong Song <yhs@fb.com> wrote: > > The implementation is arbitrary, just to show how the bpf programs > can be written for bpf_map/task/task_file. They can be costomized > for specific needs. > > For example, for bpf_map, the iterator prints out: > $ cat /sys/fs/bpf/my_bpf_map > id refcnt usercnt locked_vm > 3 2 0 20 > 6 2 0 20 > 9 2 0 20 > 12 2 0 20 > 13 2 0 20 > 16 2 0 20 > 19 2 0 20 > === END === > > For task, the iterator prints out: > $ cat /sys/fs/bpf/my_task > tgid gid > 1 1 > 2 2 > .... > 1944 1944 > 1948 1948 > 1949 1949 > 1953 1953 > === END === > > For task/file, the iterator prints out: > $ cat /sys/fs/bpf/my_task_file > tgid gid fd file > 1 1 0 ffffffff95c97600 > 1 1 1 ffffffff95c97600 > 1 1 2 ffffffff95c97600 > .... > 1895 1895 255 ffffffff95c8fe00 > 1932 1932 0 ffffffff95c8fe00 > 1932 1932 1 ffffffff95c8fe00 > 1932 1932 2 ffffffff95c8fe00 > 1932 1932 3 ffffffff95c185c0 > > This is able to print out all open files (fd and file->f_op), so user can compare > f_op against a particular kernel file operations to find what it is. > For example, from /proc/kallsyms, we can find > ffffffff95c185c0 r eventfd_fops > so we will know tgid 1932 fd 3 is an eventfd file descriptor. > > Signed-off-by: Yonghong Song <yhs@fb.com> > --- LGTM. Acked-by: Andrii Nakryiko <andriin@fb.com> > .../selftests/bpf/progs/bpf_iter_bpf_map.c | 29 +++++++++++++++++++ > .../selftests/bpf/progs/bpf_iter_task.c | 26 +++++++++++++++++ > .../selftests/bpf/progs/bpf_iter_task_file.c | 27 +++++++++++++++++ > 3 files changed, 82 insertions(+) > create mode 100644 tools/testing/selftests/bpf/progs/bpf_iter_bpf_map.c > create mode 100644 tools/testing/selftests/bpf/progs/bpf_iter_task.c > create mode 100644 tools/testing/selftests/bpf/progs/bpf_iter_task_file.c > > diff --git a/tools/testing/selftests/bpf/progs/bpf_iter_bpf_map.c b/tools/testing/selftests/bpf/progs/bpf_iter_bpf_map.c > new file mode 100644 > index 000000000000..d0af0e82b74c > --- /dev/null > +++ b/tools/testing/selftests/bpf/progs/bpf_iter_bpf_map.c > @@ -0,0 +1,29 @@ > +// SPDX-License-Identifier: GPL-2.0 > +/* Copyright (c) 2020 Facebook */ > +#include "vmlinux.h" > +#include <bpf/bpf_helpers.h> > +#include <bpf/bpf_tracing.h> > +#include <bpf/bpf_endian.h> bpf_endian.h doesn't seem to be really used and it's actually incompatible with vmlinux.h, so maybe let's drop it? Same for previous patch, I believe. > + > +char _license[] SEC("license") = "GPL"; > + [...]
diff --git a/tools/testing/selftests/bpf/progs/bpf_iter_bpf_map.c b/tools/testing/selftests/bpf/progs/bpf_iter_bpf_map.c new file mode 100644 index 000000000000..d0af0e82b74c --- /dev/null +++ b/tools/testing/selftests/bpf/progs/bpf_iter_bpf_map.c @@ -0,0 +1,29 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright (c) 2020 Facebook */ +#include "vmlinux.h" +#include <bpf/bpf_helpers.h> +#include <bpf/bpf_tracing.h> +#include <bpf/bpf_endian.h> + +char _license[] SEC("license") = "GPL"; + +SEC("iter/bpf_map") +int dump_bpf_map(struct bpf_iter__bpf_map *ctx) +{ + struct seq_file *seq = ctx->meta->seq; + __u64 seq_num = ctx->meta->seq_num; + struct bpf_map *map = ctx->map; + + if (map == (void *)0) { + BPF_SEQ_PRINTF(seq, " === END ===\n"); + return 0; + } + + if (seq_num == 0) + BPF_SEQ_PRINTF(seq, " id refcnt usercnt locked_vm\n"); + + BPF_SEQ_PRINTF(seq, "%8u %8ld %8ld %10lu\n", map->id, map->refcnt.counter, + map->usercnt.counter, + map->memory.user->locked_vm.counter); + return 0; +} diff --git a/tools/testing/selftests/bpf/progs/bpf_iter_task.c b/tools/testing/selftests/bpf/progs/bpf_iter_task.c new file mode 100644 index 000000000000..ea3c28e46aa5 --- /dev/null +++ b/tools/testing/selftests/bpf/progs/bpf_iter_task.c @@ -0,0 +1,26 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright (c) 2020 Facebook */ +#include "vmlinux.h" +#include <bpf/bpf_helpers.h> +#include <bpf/bpf_tracing.h> +#include <bpf/bpf_endian.h> + +char _license[] SEC("license") = "GPL"; + +SEC("iter/task") +int dump_task(struct bpf_iter__task *ctx) +{ + struct seq_file *seq = ctx->meta->seq; + struct task_struct *task = ctx->task; + + if (task == (void *)0) { + BPF_SEQ_PRINTF(seq, " === END ===\n"); + return 0; + } + + if (ctx->meta->seq_num == 0) + BPF_SEQ_PRINTF(seq, " tgid gid\n"); + + BPF_SEQ_PRINTF(seq, "%8d %8d\n", task->tgid, task->pid); + return 0; +} diff --git a/tools/testing/selftests/bpf/progs/bpf_iter_task_file.c b/tools/testing/selftests/bpf/progs/bpf_iter_task_file.c new file mode 100644 index 000000000000..7c6d3cfe733b --- /dev/null +++ b/tools/testing/selftests/bpf/progs/bpf_iter_task_file.c @@ -0,0 +1,27 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright (c) 2020 Facebook */ +#include "vmlinux.h" +#include <bpf/bpf_helpers.h> +#include <bpf/bpf_tracing.h> +#include <bpf/bpf_endian.h> + +char _license[] SEC("license") = "GPL"; + +SEC("iter/task_file") +int dump_task_file(struct bpf_iter__task_file *ctx) +{ + struct seq_file *seq = ctx->meta->seq; + struct task_struct *task = ctx->task; + __u32 fd = ctx->fd; + struct file *file = ctx->file; + + if (task == (void *)0 || file == (void *)0) + return 0; + + if (ctx->meta->seq_num == 0) + BPF_SEQ_PRINTF(seq, " tgid gid fd file\n"); + + BPF_SEQ_PRINTF(seq, "%8d %8d %8d %lx\n", task->tgid, task->pid, fd, + (long)file->f_op); + return 0; +}
The implementation is arbitrary, just to show how the bpf programs can be written for bpf_map/task/task_file. They can be costomized for specific needs. For example, for bpf_map, the iterator prints out: $ cat /sys/fs/bpf/my_bpf_map id refcnt usercnt locked_vm 3 2 0 20 6 2 0 20 9 2 0 20 12 2 0 20 13 2 0 20 16 2 0 20 19 2 0 20 === END === For task, the iterator prints out: $ cat /sys/fs/bpf/my_task tgid gid 1 1 2 2 .... 1944 1944 1948 1948 1949 1949 1953 1953 === END === For task/file, the iterator prints out: $ cat /sys/fs/bpf/my_task_file tgid gid fd file 1 1 0 ffffffff95c97600 1 1 1 ffffffff95c97600 1 1 2 ffffffff95c97600 .... 1895 1895 255 ffffffff95c8fe00 1932 1932 0 ffffffff95c8fe00 1932 1932 1 ffffffff95c8fe00 1932 1932 2 ffffffff95c8fe00 1932 1932 3 ffffffff95c185c0 This is able to print out all open files (fd and file->f_op), so user can compare f_op against a particular kernel file operations to find what it is. For example, from /proc/kallsyms, we can find ffffffff95c185c0 r eventfd_fops so we will know tgid 1932 fd 3 is an eventfd file descriptor. Signed-off-by: Yonghong Song <yhs@fb.com> --- .../selftests/bpf/progs/bpf_iter_bpf_map.c | 29 +++++++++++++++++++ .../selftests/bpf/progs/bpf_iter_task.c | 26 +++++++++++++++++ .../selftests/bpf/progs/bpf_iter_task_file.c | 27 +++++++++++++++++ 3 files changed, 82 insertions(+) create mode 100644 tools/testing/selftests/bpf/progs/bpf_iter_bpf_map.c create mode 100644 tools/testing/selftests/bpf/progs/bpf_iter_task.c create mode 100644 tools/testing/selftests/bpf/progs/bpf_iter_task_file.c