Skip to content

Commit

Permalink
selftests/bpf: Retry for EAGAIN in udp_redir_to_connected()
Browse files Browse the repository at this point in the history
[ Upstream commit a7e65fe ]

We use non-blocking sockets for testing sockmap redirections,
and got some random EAGAIN errors from UDP tests.

There is no guarantee the packet would be immediately available
to receive as soon as it is sent out, even on the local host.
For UDP, this is especially true because it does not lock the
sock during BH (unlike the TCP path). This is probably why we
only saw this error in UDP cases.

No matter how hard we try to make the queue empty check accurate,
it is always possible for recvmsg() to beat ->sk_data_ready().
Therefore, we should just retry in case of EAGAIN.

Fixes: d6378af ("selftests/bpf: Add a test case for udp sockmap")
Reported-by: Jiang Wang <jiang.wang@bytedance.com>
Signed-off-by: Cong Wang <cong.wang@bytedance.com>
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Acked-by: John Fastabend <john.fastabend@gmail.com>
Acked-by: Jakub Sitnicki <jakub@cloudflare.com>
Link: https://lore.kernel.org/bpf/20210615021342.7416-3-xiyou.wangcong@gmail.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
  • Loading branch information
Cong Wang authored and gregkh committed Jul 14, 2021
1 parent 48c858a commit 600a68d
Showing 1 changed file with 6 additions and 1 deletion.
7 changes: 6 additions & 1 deletion tools/testing/selftests/bpf/prog_tests/sockmap_listen.c
Original file line number Diff line number Diff line change
Expand Up @@ -1610,6 +1610,7 @@ static void udp_redir_to_connected(int family, int sotype, int sock_mapfd,
struct sockaddr_storage addr;
int c0, c1, p0, p1;
unsigned int pass;
int retries = 100;
socklen_t len;
int err, n;
u64 value;
Expand Down Expand Up @@ -1686,9 +1687,13 @@ static void udp_redir_to_connected(int family, int sotype, int sock_mapfd,
if (pass != 1)
FAIL("%s: want pass count 1, have %d", log_prefix, pass);

again:
n = read(mode == REDIR_INGRESS ? p0 : c0, &b, 1);
if (n < 0)
if (n < 0) {
if (errno == EAGAIN && retries--)
goto again;
FAIL_ERRNO("%s: read", log_prefix);
}
if (n == 0)
FAIL("%s: incomplete read", log_prefix);

Expand Down

0 comments on commit 600a68d

Please sign in to comment.