Skip to content

Commit c80d797

Browse files
mattbobrowskiMartin KaFai Lau
authored andcommitted
bpf/selftests: Fix test_tcpnotify_user
Based on a bisect, it appears that commit 7ee9887 ("timers: Implement the hierarchical pull model") has somehow inadvertently broken BPF selftest test_tcpnotify_user. The error that is being generated by this test is as follows: FAILED: Wrong stats Expected 10 calls, got 8 It looks like the change allows timer functions to be run on CPUs different from the one they are armed on. The test had pinned itself to CPU 0, and in the past the retransmit attempts also occurred on CPU 0. The test had set the max_entries attribute for BPF_MAP_TYPE_PERF_EVENT_ARRAY to 2 and was calling bpf_perf_event_output() with BPF_F_CURRENT_CPU, so the entry was likely to be in range. With the change to allow timers to run on other CPUs, the current CPU tasked with performing the retransmit might be bumped and in turn fall out of range, as the event will be filtered out via __bpf_perf_event_output() using: if (unlikely(index >= array->map.max_entries)) return -E2BIG; A possible change would be to explicitly set the max_entries attribute for perf_event_map in test_tcpnotify_kern.c to a value that's at least as large as the number of CPUs. As it turns out however, if the field is left unset, then the libbpf will determine the number of CPUs available on the underlying system and update the max_entries attribute accordingly in map_set_def_max_entries(). A further problem with the test is that it has a thread that continues running up until the program exits. The main thread cleans up some LIBBPF data structures, while the other thread continues to use them, which inevitably will trigger a SIGSEGV. This can be dealt with by telling the thread to run for as long as necessary and doing a pthread_join on it before exiting the program. Finally, I don't think binding the process to CPU 0 is meaningful for this test any more, so get rid of that. Fixes: 435f90a ("selftests/bpf: add a test case for sock_ops perf-event notification") Signed-off-by: Matt Bobrowski <[email protected]> Signed-off-by: Martin KaFai Lau <[email protected]> Acked-by: Stanislav Fomichev <[email protected]> Link: https://patch.msgid.link/[email protected]
1 parent dc0fe95 commit c80d797

File tree

2 files changed

+10
-11
lines changed

2 files changed

+10
-11
lines changed

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

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ struct {
2323

2424
struct {
2525
__uint(type, BPF_MAP_TYPE_PERF_EVENT_ARRAY);
26-
__uint(max_entries, 2);
2726
__type(key, int);
2827
__type(value, __u32);
2928
} perf_event_map SEC(".maps");

tools/testing/selftests/bpf/test_tcpnotify_user.c

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -15,20 +15,18 @@
1515
#include <bpf/libbpf.h>
1616
#include <sys/ioctl.h>
1717
#include <linux/rtnetlink.h>
18-
#include <signal.h>
1918
#include <linux/perf_event.h>
20-
#include <linux/err.h>
2119

22-
#include "bpf_util.h"
2320
#include "cgroup_helpers.h"
2421

2522
#include "test_tcpnotify.h"
26-
#include "trace_helpers.h"
2723
#include "testing_helpers.h"
2824

2925
#define SOCKET_BUFFER_SIZE (getpagesize() < 8192L ? getpagesize() : 8192L)
3026

3127
pthread_t tid;
28+
static bool exit_thread;
29+
3230
int rx_callbacks;
3331

3432
static void dummyfn(void *ctx, int cpu, void *data, __u32 size)
@@ -45,7 +43,7 @@ void tcp_notifier_poller(struct perf_buffer *pb)
4543
{
4644
int err;
4745

48-
while (1) {
46+
while (!exit_thread) {
4947
err = perf_buffer__poll(pb, 100);
5048
if (err < 0 && err != -EINTR) {
5149
printf("failed perf_buffer__poll: %d\n", err);
@@ -78,15 +76,10 @@ int main(int argc, char **argv)
7876
int error = EXIT_FAILURE;
7977
struct bpf_object *obj;
8078
char test_script[80];
81-
cpu_set_t cpuset;
8279
__u32 key = 0;
8380

8481
libbpf_set_strict_mode(LIBBPF_STRICT_ALL);
8582

86-
CPU_ZERO(&cpuset);
87-
CPU_SET(0, &cpuset);
88-
pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset);
89-
9083
cg_fd = cgroup_setup_and_join(cg_path);
9184
if (cg_fd < 0)
9285
goto err;
@@ -151,6 +144,13 @@ int main(int argc, char **argv)
151144

152145
sleep(10);
153146

147+
exit_thread = true;
148+
int ret = pthread_join(tid, NULL);
149+
if (ret) {
150+
printf("FAILED: pthread_join\n");
151+
goto err;
152+
}
153+
154154
if (verify_result(&g)) {
155155
printf("FAILED: Wrong stats Expected %d calls, got %d\n",
156156
g.ncalls, rx_callbacks);

0 commit comments

Comments
 (0)