Skip to content

Commit aa21554

Browse files
mattbobrowskiKernel Patches Daemon
authored andcommitted
selftests/bpf: improve reliability of test_perf_branches_no_hw()
Currently, test_perf_branches_no_hw() relies on the busy loop within test_perf_branches_common() being slow enough to allow at least one perf event sample tick to occur before starting to tear down the backing perf event BPF program. With a relatively small fixed iteration count of 1,000,000, this is not guaranteed on modern fast CPUs, resulting in the test run to subsequently fail with the following: bpf_testmod.ko is already unloaded. Loading bpf_testmod.ko... Successfully loaded bpf_testmod.ko. test_perf_branches_common:PASS:test_perf_branches_load 0 nsec test_perf_branches_common:PASS:attach_perf_event 0 nsec test_perf_branches_common:PASS:set_affinity 0 nsec check_good_sample:PASS:output not valid 0 nsec check_good_sample:PASS:read_branches_size 0 nsec check_good_sample:PASS:read_branches_stack 0 nsec check_good_sample:PASS:read_branches_stack 0 nsec check_good_sample:PASS:read_branches_global 0 nsec check_good_sample:PASS:read_branches_global 0 nsec check_good_sample:PASS:read_branches_size 0 nsec test_perf_branches_no_hw:PASS:perf_event_open 0 nsec test_perf_branches_common:PASS:test_perf_branches_load 0 nsec test_perf_branches_common:PASS:attach_perf_event 0 nsec test_perf_branches_common:PASS:set_affinity 0 nsec check_bad_sample:FAIL:output not valid no valid sample from prog Summary: 0/1 PASSED, 0 SKIPPED, 1 FAILED Successfully unloaded bpf_testmod.ko. On a modern CPU (i.e. one with a 3.5 GHz clock rate), executing 1 million increments of a volatile integer can take significantly less than 1 millisecond. If the spin loop and detachment of the perf event BPF program elapses before the first 1 ms sampling interval elapses, the perf event will never end up firing. Fix this by bumping the loop iteration counter a little within test_perf_branches_common(), along with ensuring adding another loop termination condition which is directly influenced by the backing perf event BPF program executing. Notably, a concious decision was made to not adjust the sample_freq value as that is just not a reliable way to go about fixing the problem. It effectively still leaves the race window open. Fixes: 67306f8 ("selftests/bpf: Add bpf_read_branch_records() selftest") Signed-off-by: Matt Bobrowski <[email protected]>
1 parent 2412df8 commit aa21554

File tree

2 files changed

+17
-2
lines changed

2 files changed

+17
-2
lines changed

tools/testing/selftests/bpf/prog_tests/perf_branches.c

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,10 @@ static void check_good_sample(struct test_perf_branches *skel)
1515
int pbe_size = sizeof(struct perf_branch_entry);
1616
int duration = 0;
1717

18+
if (CHECK(!skel->bss->run_cnt, "invalid run_cnt",
19+
"checked sample validity before prog run"))
20+
return;
21+
1822
if (CHECK(!skel->bss->valid, "output not valid",
1923
"no valid sample from prog"))
2024
return;
@@ -45,6 +49,10 @@ static void check_bad_sample(struct test_perf_branches *skel)
4549
int written_stack = skel->bss->written_stack_out;
4650
int duration = 0;
4751

52+
if (CHECK(!skel->bss->run_cnt, "invalid run_cnt",
53+
"checked sample validity before prog run"))
54+
return;
55+
4856
if (CHECK(!skel->bss->valid, "output not valid",
4957
"no valid sample from prog"))
5058
return;
@@ -83,8 +91,12 @@ static void test_perf_branches_common(int perf_fd,
8391
err = pthread_setaffinity_np(pthread_self(), sizeof(cpu_set), &cpu_set);
8492
if (CHECK(err, "set_affinity", "cpu #0, err %d\n", err))
8593
goto out_destroy;
86-
/* spin the loop for a while (random high number) */
87-
for (i = 0; i < 1000000; ++i)
94+
95+
/* Spin the loop for a while by using a high iteration count, and by
96+
* checking whether the specific run count marker has been explicitly
97+
* incremented at least once by the backing perf_event BPF program.
98+
*/
99+
for (i = 0; i < 100000000 && !*(volatile int *)&skel->bss->run_cnt; ++i)
88100
++j;
89101

90102
test_perf_branches__detach(skel);

tools/testing/selftests/bpf/progs/test_perf_branches.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#include <bpf/bpf_tracing.h>
99

1010
int valid = 0;
11+
int run_cnt = 0;
1112
int required_size_out = 0;
1213
int written_stack_out = 0;
1314
int written_global_out = 0;
@@ -24,6 +25,8 @@ int perf_branches(void *ctx)
2425
__u64 entries[4 * 3] = {0};
2526
int required_size, written_stack, written_global;
2627

28+
++run_cnt;
29+
2730
/* write to stack */
2831
written_stack = bpf_read_branch_records(ctx, entries, sizeof(entries), 0);
2932
/* ignore spurious events */

0 commit comments

Comments
 (0)