This tests new helper function bpf_get_callchain_stackid(), which is the alternative to bpf_get_stackid() for perf_event with PEBS entry.
Signed-off-by: Song Liu <songliubrav...@fb.com> --- .../bpf/prog_tests/callchain_stackid.c | 61 +++++++++++++++++++ .../selftests/bpf/progs/callchain_stackid.c | 37 +++++++++++ 2 files changed, 98 insertions(+) create mode 100644 tools/testing/selftests/bpf/prog_tests/callchain_stackid.c create mode 100644 tools/testing/selftests/bpf/progs/callchain_stackid.c diff --git a/tools/testing/selftests/bpf/prog_tests/callchain_stackid.c b/tools/testing/selftests/bpf/prog_tests/callchain_stackid.c new file mode 100644 index 0000000000000..ebe6251324a1a --- /dev/null +++ b/tools/testing/selftests/bpf/prog_tests/callchain_stackid.c @@ -0,0 +1,61 @@ +// SPDX-License-Identifier: GPL-2.0 +// Copyright (c) 2020 Facebook +#include <test_progs.h> +#include "callchain_stackid.skel.h" + +void test_callchain_stackid(void) +{ + struct perf_event_attr attr = { + /* .type = PERF_TYPE_SOFTWARE, */ + .type = PERF_TYPE_HARDWARE, + .config = PERF_COUNT_HW_CPU_CYCLES, + .precise_ip = 2, + .sample_type = PERF_SAMPLE_IP | PERF_SAMPLE_BRANCH_STACK | + PERF_SAMPLE_CALLCHAIN, + .branch_sample_type = PERF_SAMPLE_BRANCH_USER | + PERF_SAMPLE_BRANCH_NO_FLAGS | + PERF_SAMPLE_BRANCH_NO_CYCLES | + PERF_SAMPLE_BRANCH_CALL_STACK, + .sample_period = 5000, + .size = sizeof(struct perf_event_attr), + }; + struct callchain_stackid *skel; + __u32 duration = 0; + int pmu_fd, err; + + skel = callchain_stackid__open(); + + if (CHECK(!skel, "skel_open", "skeleton open failed\n")) + return; + + /* override program type */ + bpf_program__set_perf_event(skel->progs.oncpu); + + err = callchain_stackid__load(skel); + if (CHECK(err, "skel_load", "skeleton load failed: %d\n", err)) + goto cleanup; + + pmu_fd = syscall(__NR_perf_event_open, &attr, -1 /* pid */, + 0 /* cpu 0 */, -1 /* group id */, + 0 /* flags */); + if (pmu_fd < 0) { + printf("%s:SKIP:cpu doesn't support the event\n", __func__); + test__skip(); + goto cleanup; + } + + skel->links.oncpu = bpf_program__attach_perf_event(skel->progs.oncpu, + pmu_fd); + if (CHECK(IS_ERR(skel->links.oncpu), "attach_perf_event", + "err %ld\n", PTR_ERR(skel->links.oncpu))) { + close(pmu_fd); + goto cleanup; + } + usleep(500000); + + CHECK(skel->data->total_val == 1, "get_callchain_stack", "failed\n"); + close(pmu_fd); + +cleanup: + callchain_stackid__destroy(skel); +} diff --git a/tools/testing/selftests/bpf/progs/callchain_stackid.c b/tools/testing/selftests/bpf/progs/callchain_stackid.c new file mode 100644 index 0000000000000..aab2c736a0a45 --- /dev/null +++ b/tools/testing/selftests/bpf/progs/callchain_stackid.c @@ -0,0 +1,37 @@ +// SPDX-License-Identifier: GPL-2.0 +// Copyright (c) 2020 Facebook +#include "vmlinux.h" +#include <bpf/bpf_helpers.h> + +#ifndef PERF_MAX_STACK_DEPTH +#define PERF_MAX_STACK_DEPTH 127 +#endif + +#ifndef BPF_F_USER_STACK +#define BPF_F_USER_STACK (1ULL << 8) +#endif + +typedef __u64 stack_trace_t[PERF_MAX_STACK_DEPTH]; +struct { + __uint(type, BPF_MAP_TYPE_STACK_TRACE); + __uint(max_entries, 16384); + __uint(key_size, sizeof(__u32)); + __uint(value_size, sizeof(stack_trace_t)); +} stackmap SEC(".maps"); + +long total_val = 1; + +SEC("perf_event") +int oncpu(struct bpf_perf_event_data *ctx) +{ + long val; + + val = bpf_get_callchain_stackid(ctx->callchain, &stackmap, 0); + + if (val > 0) + total_val += val; + + return 0; +} + +char LICENSE[] SEC("license") = "GPL"; -- 2.24.1