Skip to content

Commit ef8c84e

Browse files
fomichevAlexei Starovoitov
authored andcommitted
selftests/bpf: De-flake test_tcpbpf
It looks like BPF program that handles BPF_SOCK_OPS_STATE_CB state can race with the bpf_map_lookup_elem("global_map"); I sometimes see the failures in this test and re-running helps. Since we know that we expect the callback to be called 3 times (one time for listener socket, two times for both ends of the connection), let's export this number and add simple retry logic around that. Also, let's make EXPECT_EQ() not return on failure, but continue evaluating all conditions; that should make potential debugging easier. With this fix in place I don't observe the flakiness anymore. Signed-off-by: Stanislav Fomichev <[email protected]> Signed-off-by: Alexei Starovoitov <[email protected]> Cc: Lawrence Brakmo <[email protected]> Link: https://lore.kernel.org/bpf/[email protected]
1 parent 6bf6aff commit ef8c84e

File tree

3 files changed

+20
-7
lines changed

3 files changed

+20
-7
lines changed

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,7 @@ int bpf_testcb(struct bpf_sock_ops *skops)
131131
g.bytes_received = skops->bytes_received;
132132
g.bytes_acked = skops->bytes_acked;
133133
}
134+
g.num_close_events++;
134135
bpf_map_update_elem(&global_map, &key, &g,
135136
BPF_ANY);
136137
}

tools/testing/selftests/bpf/test_tcpbpf.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,5 +13,6 @@ struct tcpbpf_globals {
1313
__u64 bytes_received;
1414
__u64 bytes_acked;
1515
__u32 num_listen;
16+
__u32 num_close_events;
1617
};
1718
#endif

tools/testing/selftests/bpf/test_tcpbpf_user.c

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,20 +16,24 @@
1616

1717
#include "test_tcpbpf.h"
1818

19+
/* 3 comes from one listening socket + both ends of the connection */
20+
#define EXPECTED_CLOSE_EVENTS 3
21+
1922
#define EXPECT_EQ(expected, actual, fmt) \
2023
do { \
2124
if ((expected) != (actual)) { \
2225
printf(" Value of: " #actual "\n" \
2326
" Actual: %" fmt "\n" \
2427
" Expected: %" fmt "\n", \
2528
(actual), (expected)); \
26-
goto err; \
29+
ret--; \
2730
} \
2831
} while (0)
2932

3033
int verify_result(const struct tcpbpf_globals *result)
3134
{
3235
__u32 expected_events;
36+
int ret = 0;
3337

3438
expected_events = ((1 << BPF_SOCK_OPS_TIMEOUT_INIT) |
3539
(1 << BPF_SOCK_OPS_RWND_INIT) |
@@ -48,15 +52,15 @@ int verify_result(const struct tcpbpf_globals *result)
4852
EXPECT_EQ(0x80, result->bad_cb_test_rv, PRIu32);
4953
EXPECT_EQ(0, result->good_cb_test_rv, PRIu32);
5054
EXPECT_EQ(1, result->num_listen, PRIu32);
55+
EXPECT_EQ(EXPECTED_CLOSE_EVENTS, result->num_close_events, PRIu32);
5156

52-
return 0;
53-
err:
54-
return -1;
57+
return ret;
5558
}
5659

5760
int verify_sockopt_result(int sock_map_fd)
5861
{
5962
__u32 key = 0;
63+
int ret = 0;
6064
int res;
6165
int rv;
6266

@@ -69,9 +73,7 @@ int verify_sockopt_result(int sock_map_fd)
6973
rv = bpf_map_lookup_elem(sock_map_fd, &key, &res);
7074
EXPECT_EQ(0, rv, "d");
7175
EXPECT_EQ(1, res, "d");
72-
return 0;
73-
err:
74-
return -1;
76+
return ret;
7577
}
7678

7779
static int bpf_find_map(const char *test, struct bpf_object *obj,
@@ -96,6 +98,7 @@ int main(int argc, char **argv)
9698
int error = EXIT_FAILURE;
9799
struct bpf_object *obj;
98100
int cg_fd = -1;
101+
int retry = 10;
99102
__u32 key = 0;
100103
int rv;
101104

@@ -134,12 +137,20 @@ int main(int argc, char **argv)
134137
if (sock_map_fd < 0)
135138
goto err;
136139

140+
retry_lookup:
137141
rv = bpf_map_lookup_elem(map_fd, &key, &g);
138142
if (rv != 0) {
139143
printf("FAILED: bpf_map_lookup_elem returns %d\n", rv);
140144
goto err;
141145
}
142146

147+
if (g.num_close_events != EXPECTED_CLOSE_EVENTS && retry--) {
148+
printf("Unexpected number of close events (%d), retrying!\n",
149+
g.num_close_events);
150+
usleep(100);
151+
goto retry_lookup;
152+
}
153+
143154
if (verify_result(&g)) {
144155
printf("FAILED: Wrong stats\n");
145156
goto err;

0 commit comments

Comments
 (0)