forked from torvalds/linux
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
bpf: lbr: enable reading LBR from tracing bpf programs
The typical way to access LBR is via hardware perf_event. For CPUs with FREEZE_LBRS_ON_PMI support, PMI could capture reliable LBR. On the other hand, LBR could also be useful in non-PMI scenario. For example, in kretprobe or bpf fexit program, LBR could provide a lot of information on what happened with the function. In this RFC, we try to enable LBR for BPF program. This works like: 1. Create a hardware perf_event with PERF_SAMPLE_BRANCH_* on each CPU; 2. Call a new bpf helper (bpf_get_branch_trace) from the BPF program; 3. Before calling this bpf program, the kernel stops LBR on local CPU, make a copy of LBR, and resumes LBR; 4. In the bpf program, the helper access the copy from #3. Please see tools/testing/selftests/bpf/[progs|prog_tests]/get_call_trace.c for a detailed example. Not that, this process is far from ideal, but it allows quick prototype of this feature. AFAICT, the biggest challenge here is that we are now sharing LBR in PMI and out of PMI, which could trigger some interesting race conditions. However, if we allow some level of missed/corrupted samples, this should still be very useful. Please share your thoughts and comments on this. Thanks in advance! Cc: Kan Liang <kan.liang@linux.intel.com> Cc: Like Xu <like.xu@linux.intel.com> Cc: Alexey Budankov <alexey.budankov@linux.intel.com> Signed-off-by: Song Liu <songliubraving@fb.com>
- Loading branch information
1 parent
8cacfc8
commit bdd1320
Showing
14 changed files
with
245 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
// SPDX-License-Identifier: GPL-2.0 | ||
/* Copyright (c) 2021 Facebook */ | ||
#include <test_progs.h> | ||
#include "get_branch_trace.skel.h" | ||
|
||
static int pfd_array[128] = {-1}; /* TODO remove hardcodded 128 */ | ||
|
||
static int create_perf_events(void) | ||
{ | ||
struct perf_event_attr attr = {0}; | ||
int cpu; | ||
|
||
/* create perf event */ | ||
attr.size = sizeof(attr); | ||
attr.type = PERF_TYPE_HARDWARE; | ||
attr.config = PERF_COUNT_HW_CPU_CYCLES; | ||
attr.freq = 1; | ||
attr.sample_freq = 4000; | ||
attr.sample_type = PERF_SAMPLE_BRANCH_STACK; | ||
attr.branch_sample_type = PERF_SAMPLE_BRANCH_KERNEL | | ||
PERF_SAMPLE_BRANCH_USER | PERF_SAMPLE_BRANCH_ANY; | ||
for (cpu = 0; cpu < libbpf_num_possible_cpus(); cpu++) { | ||
pfd_array[cpu] = syscall(__NR_perf_event_open, &attr, | ||
-1, cpu, -1, PERF_FLAG_FD_CLOEXEC); | ||
if (pfd_array[cpu] < 0) | ||
break; | ||
} | ||
return cpu == 0; | ||
} | ||
|
||
static void close_perf_events(void) | ||
{ | ||
int cpu = 0; | ||
int fd; | ||
|
||
while (cpu < 128) { | ||
fd = pfd_array[cpu]; | ||
if (fd < 0) | ||
break; | ||
close(fd); | ||
} | ||
} | ||
|
||
void test_get_branch_trace(void) | ||
{ | ||
struct get_branch_trace *skel; | ||
int err, prog_fd; | ||
__u32 retval; | ||
|
||
if (create_perf_events()) { | ||
test__skip(); /* system doesn't support LBR */ | ||
goto cleanup; | ||
} | ||
|
||
skel = get_branch_trace__open_and_load(); | ||
if (!ASSERT_OK_PTR(skel, "get_branch_trace__open_and_load")) | ||
goto cleanup; | ||
|
||
err = kallsyms_find("bpf_fexit_loop_test1", &skel->bss->address_low); | ||
if (!ASSERT_OK(err, "kallsyms_find")) | ||
goto cleanup; | ||
|
||
err = kallsyms_find_next("bpf_fexit_loop_test1", &skel->bss->address_high); | ||
if (!ASSERT_OK(err, "kallsyms_find_next")) | ||
goto cleanup; | ||
|
||
err = get_branch_trace__attach(skel); | ||
if (!ASSERT_OK(err, "get_branch_trace__attach")) | ||
goto cleanup; | ||
|
||
prog_fd = bpf_program__fd(skel->progs.test1); | ||
err = bpf_prog_test_run(prog_fd, 1, NULL, 0, | ||
NULL, 0, &retval, NULL); | ||
|
||
if (!ASSERT_OK(err, "bpf_prog_test_run")) | ||
goto cleanup; | ||
ASSERT_GT(skel->bss->test1_hits, 5, "find_test1_in_lbr"); | ||
|
||
cleanup: | ||
get_branch_trace__destroy(skel); | ||
close_perf_events(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
// SPDX-License-Identifier: GPL-2.0 | ||
/* Copyright (c) 2021 Facebook */ | ||
#include "vmlinux.h" | ||
#include <bpf/bpf_helpers.h> | ||
#include <bpf/bpf_tracing.h> | ||
|
||
char _license[] SEC("license") = "GPL"; | ||
|
||
__u64 test1_hits = 0; | ||
__u64 address_low = 0; | ||
__u64 address_high = 0; | ||
|
||
#define MAX_LBR_ENTRIES 32 | ||
|
||
struct perf_branch_entry entries[MAX_LBR_ENTRIES] = {}; | ||
|
||
static inline bool in_range(__u64 val) | ||
{ | ||
return (val >= address_low) && (val < address_high); | ||
} | ||
|
||
SEC("fexit/bpf_fexit_loop_test1") | ||
int BPF_PROG(test1, int n, int ret) | ||
{ | ||
long cnt, i; | ||
|
||
cnt = bpf_get_branch_trace(entries, sizeof(entries), 0); | ||
|
||
for (i = 0; i < MAX_LBR_ENTRIES; i++) { | ||
if (i >= cnt) | ||
break; | ||
if (in_range(entries[i].from) && in_range(entries[i].to)) | ||
test1_hits++; | ||
} | ||
return 0; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters