Message ID | 20200626001332.1554603-5-songliubraving@fb.com |
---|---|
State | Changes Requested |
Delegated to: | BPF Maintainers |
Headers | show |
Series | bpf: introduce bpf_get_task_stack() | expand |
On 6/25/20 5:13 PM, Song Liu wrote: > The new test is similar to other bpf_iter tests. > > Signed-off-by: Song Liu <songliubraving@fb.com> > --- > .../selftests/bpf/prog_tests/bpf_iter.c | 17 ++++++ > .../selftests/bpf/progs/bpf_iter_task_stack.c | 60 +++++++++++++++++++ > 2 files changed, 77 insertions(+) > create mode 100644 tools/testing/selftests/bpf/progs/bpf_iter_task_stack.c > > diff --git a/tools/testing/selftests/bpf/prog_tests/bpf_iter.c b/tools/testing/selftests/bpf/prog_tests/bpf_iter.c > index 87c29dde1cf96..baa83328f810d 100644 > --- a/tools/testing/selftests/bpf/prog_tests/bpf_iter.c > +++ b/tools/testing/selftests/bpf/prog_tests/bpf_iter.c > @@ -5,6 +5,7 @@ > #include "bpf_iter_netlink.skel.h" > #include "bpf_iter_bpf_map.skel.h" > #include "bpf_iter_task.skel.h" > +#include "bpf_iter_task_stack.skel.h" > #include "bpf_iter_task_file.skel.h" > #include "bpf_iter_test_kern1.skel.h" > #include "bpf_iter_test_kern2.skel.h" > @@ -106,6 +107,20 @@ static void test_task(void) > bpf_iter_task__destroy(skel); > } > > +static void test_task_stack(void) > +{ > + struct bpf_iter_task_stack *skel; > + > + skel = bpf_iter_task_stack__open_and_load(); > + if (CHECK(!skel, "bpf_iter_task_stack__open_and_load", > + "skeleton open_and_load failed\n")) > + return; > + > + do_dummy_read(skel->progs.dump_task_stack); > + > + bpf_iter_task_stack__destroy(skel); > +} > + > static void test_task_file(void) > { > struct bpf_iter_task_file *skel; > @@ -392,6 +407,8 @@ void test_bpf_iter(void) > test_bpf_map(); > if (test__start_subtest("task")) > test_task(); > + if (test__start_subtest("task_stack")) > + test_task_stack(); > if (test__start_subtest("task_file")) > test_task_file(); > if (test__start_subtest("anon")) > diff --git a/tools/testing/selftests/bpf/progs/bpf_iter_task_stack.c b/tools/testing/selftests/bpf/progs/bpf_iter_task_stack.c > new file mode 100644 > index 0000000000000..83aca5b1a7965 > --- /dev/null > +++ b/tools/testing/selftests/bpf/progs/bpf_iter_task_stack.c > @@ -0,0 +1,60 @@ > +// SPDX-License-Identifier: GPL-2.0 > +/* Copyright (c) 2020 Facebook */ > +/* "undefine" structs in vmlinux.h, because we "override" them below */ > +#define bpf_iter_meta bpf_iter_meta___not_used > +#define bpf_iter__task bpf_iter__task___not_used > +#include "vmlinux.h" > +#undef bpf_iter_meta > +#undef bpf_iter__task > +#include <bpf/bpf_helpers.h> > +#include <bpf/bpf_tracing.h> Could you rebase on top of latest bpf-next? A new header bpf_iter.h is introduced and it will make code simpler. > + > +char _license[] SEC("license") = "GPL"; > + > +/* bpf_get_task_stack needs a stackmap to work */ > +struct { > + __uint(type, BPF_MAP_TYPE_STACK_TRACE); > + __uint(max_entries, 16384); > + __uint(key_size, sizeof(__u32)); > + __uint(value_size, sizeof(__u64) * 20); > +} stackmap SEC(".maps"); > + > +struct bpf_iter_meta { > + struct seq_file *seq; > + __u64 session_id; > + __u64 seq_num; > +} __attribute__((preserve_access_index)); > + > +struct bpf_iter__task { > + struct bpf_iter_meta *meta; > + struct task_struct *task; > +} __attribute__((preserve_access_index)); > + > +#define MAX_STACK_TRACE_DEPTH 64 > +unsigned long entries[MAX_STACK_TRACE_DEPTH]; > + > +SEC("iter/task") > +int dump_task_stack(struct bpf_iter__task *ctx) > +{ > + struct seq_file *seq = ctx->meta->seq; > + struct task_struct *task = ctx->task; > + int i, retlen; long retlen after rebase? > + > + if (task == (void *)0) > + return 0; > + > + retlen = bpf_get_task_stack(task, entries, > + MAX_STACK_TRACE_DEPTH * sizeof(unsigned long), 0); > + if (retlen < 0) > + return 0; > + > + BPF_SEQ_PRINTF(seq, "pid: %8u num_entries: %8u\n", task->pid, > + retlen / sizeof(unsigned long)); sizeof(unsigned long) is used a few times. It is worthwhile to have a variable for it. > + for (i = 0; i < MAX_STACK_TRACE_DEPTH / sizeof(unsigned long); i++) { > + if (retlen > i * sizeof(unsigned long)) > + BPF_SEQ_PRINTF(seq, "[<0>] %pB\n", (void *)entries[i]); > + } > + BPF_SEQ_PRINTF(seq, "\n"); > + > + return 0; > +} >
On Thu, Jun 25, 2020 at 5:15 PM Song Liu <songliubraving@fb.com> wrote: > > The new test is similar to other bpf_iter tests. > > Signed-off-by: Song Liu <songliubraving@fb.com> > --- > .../selftests/bpf/prog_tests/bpf_iter.c | 17 ++++++ > .../selftests/bpf/progs/bpf_iter_task_stack.c | 60 +++++++++++++++++++ > 2 files changed, 77 insertions(+) > create mode 100644 tools/testing/selftests/bpf/progs/bpf_iter_task_stack.c > > diff --git a/tools/testing/selftests/bpf/prog_tests/bpf_iter.c b/tools/testing/selftests/bpf/prog_tests/bpf_iter.c > index 87c29dde1cf96..baa83328f810d 100644 > --- a/tools/testing/selftests/bpf/prog_tests/bpf_iter.c > +++ b/tools/testing/selftests/bpf/prog_tests/bpf_iter.c > @@ -5,6 +5,7 @@ > #include "bpf_iter_netlink.skel.h" > #include "bpf_iter_bpf_map.skel.h" > #include "bpf_iter_task.skel.h" > +#include "bpf_iter_task_stack.skel.h" > #include "bpf_iter_task_file.skel.h" > #include "bpf_iter_test_kern1.skel.h" > #include "bpf_iter_test_kern2.skel.h" > @@ -106,6 +107,20 @@ static void test_task(void) > bpf_iter_task__destroy(skel); > } > > +static void test_task_stack(void) > +{ > + struct bpf_iter_task_stack *skel; > + > + skel = bpf_iter_task_stack__open_and_load(); > + if (CHECK(!skel, "bpf_iter_task_stack__open_and_load", > + "skeleton open_and_load failed\n")) > + return; > + > + do_dummy_read(skel->progs.dump_task_stack); > + > + bpf_iter_task_stack__destroy(skel); > +} > + > static void test_task_file(void) > { > struct bpf_iter_task_file *skel; > @@ -392,6 +407,8 @@ void test_bpf_iter(void) > test_bpf_map(); > if (test__start_subtest("task")) > test_task(); > + if (test__start_subtest("task_stack")) > + test_task_stack(); > if (test__start_subtest("task_file")) > test_task_file(); > if (test__start_subtest("anon")) > diff --git a/tools/testing/selftests/bpf/progs/bpf_iter_task_stack.c b/tools/testing/selftests/bpf/progs/bpf_iter_task_stack.c > new file mode 100644 > index 0000000000000..83aca5b1a7965 > --- /dev/null > +++ b/tools/testing/selftests/bpf/progs/bpf_iter_task_stack.c > @@ -0,0 +1,60 @@ > +// SPDX-License-Identifier: GPL-2.0 > +/* Copyright (c) 2020 Facebook */ > +/* "undefine" structs in vmlinux.h, because we "override" them below */ > +#define bpf_iter_meta bpf_iter_meta___not_used > +#define bpf_iter__task bpf_iter__task___not_used > +#include "vmlinux.h" > +#undef bpf_iter_meta > +#undef bpf_iter__task > +#include <bpf/bpf_helpers.h> > +#include <bpf/bpf_tracing.h> > + > +char _license[] SEC("license") = "GPL"; > + > +/* bpf_get_task_stack needs a stackmap to work */ no it doesn't anymore :) please drop [...]
> On Jun 26, 2020, at 1:21 PM, Andrii Nakryiko <andrii.nakryiko@gmail.com> wrote: > > On Thu, Jun 25, 2020 at 5:15 PM Song Liu <songliubraving@fb.com> wrote: >> >> The new test is similar to other bpf_iter tests. >> >> Signed-off-by: Song Liu <songliubraving@fb.com> >> --- >> .../selftests/bpf/prog_tests/bpf_iter.c | 17 ++++++ >> .../selftests/bpf/progs/bpf_iter_task_stack.c | 60 +++++++++++++++++++ >> 2 files changed, 77 insertions(+) >> create mode 100644 tools/testing/selftests/bpf/progs/bpf_iter_task_stack.c >> >> diff --git a/tools/testing/selftests/bpf/prog_tests/bpf_iter.c b/tools/testing/selftests/bpf/prog_tests/bpf_iter.c >> index 87c29dde1cf96..baa83328f810d 100644 >> --- a/tools/testing/selftests/bpf/prog_tests/bpf_iter.c >> +++ b/tools/testing/selftests/bpf/prog_tests/bpf_iter.c >> @@ -5,6 +5,7 @@ >> #include "bpf_iter_netlink.skel.h" >> #include "bpf_iter_bpf_map.skel.h" >> #include "bpf_iter_task.skel.h" >> +#include "bpf_iter_task_stack.skel.h" >> #include "bpf_iter_task_file.skel.h" >> #include "bpf_iter_test_kern1.skel.h" >> #include "bpf_iter_test_kern2.skel.h" >> @@ -106,6 +107,20 @@ static void test_task(void) >> bpf_iter_task__destroy(skel); >> } >> >> +static void test_task_stack(void) >> +{ >> + struct bpf_iter_task_stack *skel; >> + >> + skel = bpf_iter_task_stack__open_and_load(); >> + if (CHECK(!skel, "bpf_iter_task_stack__open_and_load", >> + "skeleton open_and_load failed\n")) >> + return; >> + >> + do_dummy_read(skel->progs.dump_task_stack); >> + >> + bpf_iter_task_stack__destroy(skel); >> +} >> + >> static void test_task_file(void) >> { >> struct bpf_iter_task_file *skel; >> @@ -392,6 +407,8 @@ void test_bpf_iter(void) >> test_bpf_map(); >> if (test__start_subtest("task")) >> test_task(); >> + if (test__start_subtest("task_stack")) >> + test_task_stack(); >> if (test__start_subtest("task_file")) >> test_task_file(); >> if (test__start_subtest("anon")) >> diff --git a/tools/testing/selftests/bpf/progs/bpf_iter_task_stack.c b/tools/testing/selftests/bpf/progs/bpf_iter_task_stack.c >> new file mode 100644 >> index 0000000000000..83aca5b1a7965 >> --- /dev/null >> +++ b/tools/testing/selftests/bpf/progs/bpf_iter_task_stack.c >> @@ -0,0 +1,60 @@ >> +// SPDX-License-Identifier: GPL-2.0 >> +/* Copyright (c) 2020 Facebook */ >> +/* "undefine" structs in vmlinux.h, because we "override" them below */ >> +#define bpf_iter_meta bpf_iter_meta___not_used >> +#define bpf_iter__task bpf_iter__task___not_used >> +#include "vmlinux.h" >> +#undef bpf_iter_meta >> +#undef bpf_iter__task >> +#include <bpf/bpf_helpers.h> >> +#include <bpf/bpf_tracing.h> >> + >> +char _license[] SEC("license") = "GPL"; >> + >> +/* bpf_get_task_stack needs a stackmap to work */ > > no it doesn't anymore :) please drop We still need stack_map_alloc() to call get_callchain_buffers() in this case. Without an active stack map, get_callchain_buffers() may fail. Thanks, Song
On Fri, Jun 26, 2020 at 4:05 PM Song Liu <songliubraving@fb.com> wrote: > > > > > On Jun 26, 2020, at 1:21 PM, Andrii Nakryiko <andrii.nakryiko@gmail.com> wrote: > > > > On Thu, Jun 25, 2020 at 5:15 PM Song Liu <songliubraving@fb.com> wrote: > >> > >> The new test is similar to other bpf_iter tests. > >> > >> Signed-off-by: Song Liu <songliubraving@fb.com> > >> --- > >> .../selftests/bpf/prog_tests/bpf_iter.c | 17 ++++++ > >> .../selftests/bpf/progs/bpf_iter_task_stack.c | 60 +++++++++++++++++++ > >> 2 files changed, 77 insertions(+) > >> create mode 100644 tools/testing/selftests/bpf/progs/bpf_iter_task_stack.c > >> > >> diff --git a/tools/testing/selftests/bpf/prog_tests/bpf_iter.c b/tools/testing/selftests/bpf/prog_tests/bpf_iter.c > >> index 87c29dde1cf96..baa83328f810d 100644 > >> --- a/tools/testing/selftests/bpf/prog_tests/bpf_iter.c > >> +++ b/tools/testing/selftests/bpf/prog_tests/bpf_iter.c > >> @@ -5,6 +5,7 @@ > >> #include "bpf_iter_netlink.skel.h" > >> #include "bpf_iter_bpf_map.skel.h" > >> #include "bpf_iter_task.skel.h" > >> +#include "bpf_iter_task_stack.skel.h" > >> #include "bpf_iter_task_file.skel.h" > >> #include "bpf_iter_test_kern1.skel.h" > >> #include "bpf_iter_test_kern2.skel.h" > >> @@ -106,6 +107,20 @@ static void test_task(void) > >> bpf_iter_task__destroy(skel); > >> } > >> > >> +static void test_task_stack(void) > >> +{ > >> + struct bpf_iter_task_stack *skel; > >> + > >> + skel = bpf_iter_task_stack__open_and_load(); > >> + if (CHECK(!skel, "bpf_iter_task_stack__open_and_load", > >> + "skeleton open_and_load failed\n")) > >> + return; > >> + > >> + do_dummy_read(skel->progs.dump_task_stack); > >> + > >> + bpf_iter_task_stack__destroy(skel); > >> +} > >> + > >> static void test_task_file(void) > >> { > >> struct bpf_iter_task_file *skel; > >> @@ -392,6 +407,8 @@ void test_bpf_iter(void) > >> test_bpf_map(); > >> if (test__start_subtest("task")) > >> test_task(); > >> + if (test__start_subtest("task_stack")) > >> + test_task_stack(); > >> if (test__start_subtest("task_file")) > >> test_task_file(); > >> if (test__start_subtest("anon")) > >> diff --git a/tools/testing/selftests/bpf/progs/bpf_iter_task_stack.c b/tools/testing/selftests/bpf/progs/bpf_iter_task_stack.c > >> new file mode 100644 > >> index 0000000000000..83aca5b1a7965 > >> --- /dev/null > >> +++ b/tools/testing/selftests/bpf/progs/bpf_iter_task_stack.c > >> @@ -0,0 +1,60 @@ > >> +// SPDX-License-Identifier: GPL-2.0 > >> +/* Copyright (c) 2020 Facebook */ > >> +/* "undefine" structs in vmlinux.h, because we "override" them below */ > >> +#define bpf_iter_meta bpf_iter_meta___not_used > >> +#define bpf_iter__task bpf_iter__task___not_used > >> +#include "vmlinux.h" > >> +#undef bpf_iter_meta > >> +#undef bpf_iter__task > >> +#include <bpf/bpf_helpers.h> > >> +#include <bpf/bpf_tracing.h> > >> + > >> +char _license[] SEC("license") = "GPL"; > >> + > >> +/* bpf_get_task_stack needs a stackmap to work */ > > > > no it doesn't anymore :) please drop > > We still need stack_map_alloc() to call get_callchain_buffers() in this > case. Without an active stack map, get_callchain_buffers() may fail. Oh... um... is it possible to do it some other way? It's extremely confusing dependency. Does bpf_get_stack() also require stackmap? > > Thanks, > Song
> On Jun 26, 2020, at 4:11 PM, Andrii Nakryiko <andrii.nakryiko@gmail.com> wrote: > > On Fri, Jun 26, 2020 at 4:05 PM Song Liu <songliubraving@fb.com> wrote: >> >> >> >>> On Jun 26, 2020, at 1:21 PM, Andrii Nakryiko <andrii.nakryiko@gmail.com> wrote: >>> >>> On Thu, Jun 25, 2020 at 5:15 PM Song Liu <songliubraving@fb.com> wrote: >>>> >>>> The new test is similar to other bpf_iter tests. >>>> >>>> Signed-off-by: Song Liu <songliubraving@fb.com> >>>> --- >>>> .../selftests/bpf/prog_tests/bpf_iter.c | 17 ++++++ >>>> .../selftests/bpf/progs/bpf_iter_task_stack.c | 60 +++++++++++++++++++ >>>> 2 files changed, 77 insertions(+) >>>> create mode 100644 tools/testing/selftests/bpf/progs/bpf_iter_task_stack.c >>>> >>>> diff --git a/tools/testing/selftests/bpf/prog_tests/bpf_iter.c b/tools/testing/selftests/bpf/prog_tests/bpf_iter.c >>>> index 87c29dde1cf96..baa83328f810d 100644 >>>> --- a/tools/testing/selftests/bpf/prog_tests/bpf_iter.c >>>> +++ b/tools/testing/selftests/bpf/prog_tests/bpf_iter.c >>>> @@ -5,6 +5,7 @@ >>>> #include "bpf_iter_netlink.skel.h" >>>> #include "bpf_iter_bpf_map.skel.h" >>>> #include "bpf_iter_task.skel.h" >>>> +#include "bpf_iter_task_stack.skel.h" >>>> #include "bpf_iter_task_file.skel.h" >>>> #include "bpf_iter_test_kern1.skel.h" >>>> #include "bpf_iter_test_kern2.skel.h" >>>> @@ -106,6 +107,20 @@ static void test_task(void) >>>> bpf_iter_task__destroy(skel); >>>> } >>>> >>>> +static void test_task_stack(void) >>>> +{ >>>> + struct bpf_iter_task_stack *skel; >>>> + >>>> + skel = bpf_iter_task_stack__open_and_load(); >>>> + if (CHECK(!skel, "bpf_iter_task_stack__open_and_load", >>>> + "skeleton open_and_load failed\n")) >>>> + return; >>>> + >>>> + do_dummy_read(skel->progs.dump_task_stack); >>>> + >>>> + bpf_iter_task_stack__destroy(skel); >>>> +} >>>> + >>>> static void test_task_file(void) >>>> { >>>> struct bpf_iter_task_file *skel; >>>> @@ -392,6 +407,8 @@ void test_bpf_iter(void) >>>> test_bpf_map(); >>>> if (test__start_subtest("task")) >>>> test_task(); >>>> + if (test__start_subtest("task_stack")) >>>> + test_task_stack(); >>>> if (test__start_subtest("task_file")) >>>> test_task_file(); >>>> if (test__start_subtest("anon")) >>>> diff --git a/tools/testing/selftests/bpf/progs/bpf_iter_task_stack.c b/tools/testing/selftests/bpf/progs/bpf_iter_task_stack.c >>>> new file mode 100644 >>>> index 0000000000000..83aca5b1a7965 >>>> --- /dev/null >>>> +++ b/tools/testing/selftests/bpf/progs/bpf_iter_task_stack.c >>>> @@ -0,0 +1,60 @@ >>>> +// SPDX-License-Identifier: GPL-2.0 >>>> +/* Copyright (c) 2020 Facebook */ >>>> +/* "undefine" structs in vmlinux.h, because we "override" them below */ >>>> +#define bpf_iter_meta bpf_iter_meta___not_used >>>> +#define bpf_iter__task bpf_iter__task___not_used >>>> +#include "vmlinux.h" >>>> +#undef bpf_iter_meta >>>> +#undef bpf_iter__task >>>> +#include <bpf/bpf_helpers.h> >>>> +#include <bpf/bpf_tracing.h> >>>> + >>>> +char _license[] SEC("license") = "GPL"; >>>> + >>>> +/* bpf_get_task_stack needs a stackmap to work */ >>> >>> no it doesn't anymore :) please drop >> >> We still need stack_map_alloc() to call get_callchain_buffers() in this >> case. Without an active stack map, get_callchain_buffers() may fail. > > Oh... um... is it possible to do it some other way? It's extremely > confusing dependency. Does bpf_get_stack() also require stackmap? > Aha, I thought bpf_get_stack() also requires stackmap, but it doesn't. The fix is in check_helper_call(). Let me do the same for bpf_get_task_stack(). Thanks, Song
diff --git a/tools/testing/selftests/bpf/prog_tests/bpf_iter.c b/tools/testing/selftests/bpf/prog_tests/bpf_iter.c index 87c29dde1cf96..baa83328f810d 100644 --- a/tools/testing/selftests/bpf/prog_tests/bpf_iter.c +++ b/tools/testing/selftests/bpf/prog_tests/bpf_iter.c @@ -5,6 +5,7 @@ #include "bpf_iter_netlink.skel.h" #include "bpf_iter_bpf_map.skel.h" #include "bpf_iter_task.skel.h" +#include "bpf_iter_task_stack.skel.h" #include "bpf_iter_task_file.skel.h" #include "bpf_iter_test_kern1.skel.h" #include "bpf_iter_test_kern2.skel.h" @@ -106,6 +107,20 @@ static void test_task(void) bpf_iter_task__destroy(skel); } +static void test_task_stack(void) +{ + struct bpf_iter_task_stack *skel; + + skel = bpf_iter_task_stack__open_and_load(); + if (CHECK(!skel, "bpf_iter_task_stack__open_and_load", + "skeleton open_and_load failed\n")) + return; + + do_dummy_read(skel->progs.dump_task_stack); + + bpf_iter_task_stack__destroy(skel); +} + static void test_task_file(void) { struct bpf_iter_task_file *skel; @@ -392,6 +407,8 @@ void test_bpf_iter(void) test_bpf_map(); if (test__start_subtest("task")) test_task(); + if (test__start_subtest("task_stack")) + test_task_stack(); if (test__start_subtest("task_file")) test_task_file(); if (test__start_subtest("anon")) diff --git a/tools/testing/selftests/bpf/progs/bpf_iter_task_stack.c b/tools/testing/selftests/bpf/progs/bpf_iter_task_stack.c new file mode 100644 index 0000000000000..83aca5b1a7965 --- /dev/null +++ b/tools/testing/selftests/bpf/progs/bpf_iter_task_stack.c @@ -0,0 +1,60 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright (c) 2020 Facebook */ +/* "undefine" structs in vmlinux.h, because we "override" them below */ +#define bpf_iter_meta bpf_iter_meta___not_used +#define bpf_iter__task bpf_iter__task___not_used +#include "vmlinux.h" +#undef bpf_iter_meta +#undef bpf_iter__task +#include <bpf/bpf_helpers.h> +#include <bpf/bpf_tracing.h> + +char _license[] SEC("license") = "GPL"; + +/* bpf_get_task_stack needs a stackmap to work */ +struct { + __uint(type, BPF_MAP_TYPE_STACK_TRACE); + __uint(max_entries, 16384); + __uint(key_size, sizeof(__u32)); + __uint(value_size, sizeof(__u64) * 20); +} stackmap SEC(".maps"); + +struct bpf_iter_meta { + struct seq_file *seq; + __u64 session_id; + __u64 seq_num; +} __attribute__((preserve_access_index)); + +struct bpf_iter__task { + struct bpf_iter_meta *meta; + struct task_struct *task; +} __attribute__((preserve_access_index)); + +#define MAX_STACK_TRACE_DEPTH 64 +unsigned long entries[MAX_STACK_TRACE_DEPTH]; + +SEC("iter/task") +int dump_task_stack(struct bpf_iter__task *ctx) +{ + struct seq_file *seq = ctx->meta->seq; + struct task_struct *task = ctx->task; + int i, retlen; + + if (task == (void *)0) + return 0; + + retlen = bpf_get_task_stack(task, entries, + MAX_STACK_TRACE_DEPTH * sizeof(unsigned long), 0); + if (retlen < 0) + return 0; + + BPF_SEQ_PRINTF(seq, "pid: %8u num_entries: %8u\n", task->pid, + retlen / sizeof(unsigned long)); + for (i = 0; i < MAX_STACK_TRACE_DEPTH / sizeof(unsigned long); i++) { + if (retlen > i * sizeof(unsigned long)) + BPF_SEQ_PRINTF(seq, "[<0>] %pB\n", (void *)entries[i]); + } + BPF_SEQ_PRINTF(seq, "\n"); + + return 0; +}
The new test is similar to other bpf_iter tests. Signed-off-by: Song Liu <songliubraving@fb.com> --- .../selftests/bpf/prog_tests/bpf_iter.c | 17 ++++++ .../selftests/bpf/progs/bpf_iter_task_stack.c | 60 +++++++++++++++++++ 2 files changed, 77 insertions(+) create mode 100644 tools/testing/selftests/bpf/progs/bpf_iter_task_stack.c