From: "Alexis Lothoré" <alexis.lothore@bootlin.com>
To: "Ihor Solodrai" <ihor.solodrai@linux.dev>,
"Alexis Lothoré" <alexis.lothore@bootlin.com>,
"Jiayuan Chen" <jiayuan.chen@linux.dev>,
"Alexei Starovoitov" <ast@kernel.org>,
"Daniel Borkmann" <daniel@iogearbox.net>,
"Andrii Nakryiko" <andrii@kernel.org>,
"Eduard Zingerman" <eddyz87@gmail.com>,
"Kumar Kartikeya Dwivedi" <memxor@gmail.com>,
"Martin KaFai Lau" <martin.lau@linux.dev>,
"Song Liu" <song@kernel.org>,
"Yonghong Song" <yonghong.song@linux.dev>,
"Jiri Olsa" <jolsa@kernel.org>,
"Emil Tsalapatis" <emil@etsalapatis.com>,
"Shuah Khan" <shuah@kernel.org>
Cc: <ebpf@linuxfoundation.org>,
"Bastien Curutchet" <bastien.curutchet@bootlin.com>,
"Thomas Petazzoni" <thomas.petazzoni@bootlin.com>,
<bpf@vger.kernel.org>, <linux-kselftest@vger.kernel.org>,
<linux-kernel@vger.kernel.org>
Subject: Re: [PATCH bpf v3 1/2] selftests/bpf: keep polling connection that is still in progress
Date: Thu, 13 Aug 2026 09:29:14 +0200 [thread overview]
Message-ID: <DKNN0WMD9XW8.MCJAMGS5NPYR@bootlin.com> (raw)
In-Reply-To: <d92da576-4930-4b10-b8bd-ea1158ec08bc@linux.dev>
Hi Ihor,
thanks for the extensive investigation
On Wed Aug 12, 2026 at 8:46 PM CEST, Ihor Solodrai wrote:
> On 8/11/26 9:25 AM, Alexis Lothoré wrote:
>> On Tue Aug 11, 2026 at 5:05 PM CEST, Jiayuan Chen wrote:
>>>
>>> On 8/11/26 10:26 PM, Alexis Lothoré (eBPF Foundation) wrote:
[...]
>>> So IIUC this patch doesn't actually fix the flakiness: connect() on a
>>> blocking socket only
>>> returns EINPROGRESS after SO_SNDTIMEO is fully consumed, so remaining_ms
>>> is always ~0 and the
>>> overall time budget is still 1s, same as before. Am I missing something?
>>
>> Hmmm, I have been assuming that this EINPROGRESS could be returned
>> _before_ the configured timeout depletion, but I may have been mistaken,
>> it indeed happens only the socket is O_NONBLOCK, which is not the case
>> here. So indeed, it does not fix anything for the blocking case, as the
>> budget is already depleted when getting EINPROGRESS...
>>
>> I added this budget mechanism to follow up on Ihor's suggestion, so I
>> either got it wrong, or it can not work.
>
> Hi Alexis,
>
> Looks like my suggestion was bad, sorry. Jiayuan is right. I didn't
> realize what -EINPROGRESS actually means here.
>
> See __inet_stream_connect() in net/ipv4/af_inet.c:697
>
> err = -EINPROGRESS;
> ...
> timeo = sock_sndtimeo(sk, flags & O_NONBLOCK);
> ...
> if (!timeo || !inet_wait_for_connect(sk, timeo, writebias))
> goto out;
>
> -EINPROGRESS is a default that reaches userspace only when the wait
> expires. Every other exit sets a different error code. So on a
> blocking socket -EINPROGRESS does not mean "connection started", it
> means "waited the whole budget, gave up in SYN_SENT". On a nonblocking
> socket it means the opposite, and man 2 connect seems to only document
> the nonblocking case.
>
>> An intermediate solution could
>> be to exceptionally raise the budget by 1s when getting EINPROGRESS.
>
> I believe you're right that the flakiness can be addressed with bigger
> timeout, which is why v2 fixed it for you. But +1s may not be enough.
>
> IIUC the way the helpers are written cause -EINPROGRESS instead of
> -ETIMEDOUT. If SO_SNDTIMEO is not set before connect(), the kernel
> reports plain ETIMEDOUT, but it is set in settimeo().
>
> I vibe-coded a userspace repro: loopback listener with a full accept
> queue drained at t=1500ms, so the handshake completes at ~2040ms.
> Caller asks for timeout_ms=1000, like tc_tunnel:
>
> mainline (blocking) budget 1000 FAIL at 1016ms
> v3 (blocking + leftover poll) budget 1000 FAIL at 1015ms # my suggestion
> O_NONBLOCK + poll(timeout_ms) budget 1000 FAIL at 1001ms # Jiayuan's suggestion
> O_NONBLOCK + poll(3500) budget 3500 OK at 2031ms
> blocking, SO_SNDTIMEO raised to 3500 budget 3500 OK at 2040ms
> v2 (blocking 1000 + fixed 3000 grace) budget 4046 OK at 2067ms
>
> Everything that gave the handshake more than ~2040ms passed. Blocking
> vs nonblocking makes no difference, poll() vs no poll() makes no
> difference. We just need to increase the budget for connect().
Ok, so indeed the poll() loop complexifies the connection helpers
without much gain.
> I don't think swtiching to O_NONBLOCK makes sense. Apparently, it was
> nonblocking in the past, see 99126abec5e5 ("bpf: selftests: A few
> improvements to network_helpers.c")
>
> So I think we can introduce a separate connect() budget, similar to
> your v2. And then use opts->timeout_ms for everything after. Something
> like this:
>
> #define CONNECT_TIMEOUT_MS 5000
>
> static int connect_timeout_ms(const struct network_helper_opts *opts)
> {
> /* don't shorten what the caller asked for: tc_redirect
> * and xdp_synproxy pass 10000
> */
> return MAX(opts->timeout_ms, CONNECT_TIMEOUT_MS);
> }
>
> and in connect_to_addr():
>
> fd = client_socket(addr->ss_family, type, opts);
> if (fd < 0) {
> log_err("Failed to create client socket");
> return -1;
> }
>
> /* SO_SNDTIMEO is a ceiling, not a sleep: a wider handshake
> * budget costs nothing on connections that succeed.
> */
> if (settimeo(fd, connect_timeout_ms(opts)))
> goto close;
>
> if (connect(fd, (const struct sockaddr *)addr, addrlen)) {
> log_err("Failed to connect to server");
> goto close;
> }
>
> if (settimeo(fd, opts->timeout_ms)) /* data I/O budget */
> goto close;
>
> return fd;
>
> close:
> save_errno_close(fd);
> return -1;
>
> This is simpler than poll() and retry loops.
Ok, I'll give it a try with this simpler connect-only-extended-budget,
without the poll loop
> An entirely different alternative that Eduard brought up in an
> off-list discussion, is to drop all the timeout machinery from
> network_helpers.c altogether, and rely solely on the test_progs
> watchdog to kill the subtest processes: d9d4d127e813 ("selftests/bpf:
> watchdog timer for test_progs")
>
> I am not convinced it's a good idea, because I don't know what will
> happen with all the tc_* tests if there is no connection timeouts. If
> you're interested, you could try it and see.
Hmmm, I'm not very familiar with this mechanism, but aside from the
potential issues you are mentioning, wouldn't it make us loose a bit of
info here, when the watchdog kicks the runner out ? We may know from the
stacktrace that the subtest was in connect(), but we would loose any
formal error/errno on connection timeout I guess, and I am not sure how
confident we can get about any watchdog kick being a connect timeout.
>> That potentially brings back part of the issues he has been mentioning
>> with selftests duration possibly increasing by a non negligeable amount,
>> but maybe 1s is a better compromise, compared to my initial 3s proposal
>> ?
>>
--
Alexis Lothoré, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com
next prev parent reply other threads:[~2026-08-13 7:29 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-08-11 14:26 [PATCH bpf v3 0/2] selftest/bpf: make test_tc_tunnel and test_tc_edt more robust to CI load Alexis Lothoré (eBPF Foundation)
2026-08-11 14:26 ` [PATCH bpf v3 1/2] selftests/bpf: keep polling connection that is still in progress Alexis Lothoré (eBPF Foundation)
2026-08-11 15:05 ` Jiayuan Chen
2026-08-11 16:25 ` Alexis Lothoré
2026-08-12 18:46 ` Ihor Solodrai
2026-08-13 7:29 ` Alexis Lothoré [this message]
2026-08-11 15:30 ` bot+bpf-ci
2026-08-11 16:01 ` Alexis Lothoré
2026-08-11 14:26 ` [PATCH bpf v3 2/2] selftests/bpf: add connect timeout to test_tc_edt Alexis Lothoré (eBPF Foundation)
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=DKNN0WMD9XW8.MCJAMGS5NPYR@bootlin.com \
--to=alexis.lothore@bootlin.com \
--cc=andrii@kernel.org \
--cc=ast@kernel.org \
--cc=bastien.curutchet@bootlin.com \
--cc=bpf@vger.kernel.org \
--cc=daniel@iogearbox.net \
--cc=ebpf@linuxfoundation.org \
--cc=eddyz87@gmail.com \
--cc=emil@etsalapatis.com \
--cc=ihor.solodrai@linux.dev \
--cc=jiayuan.chen@linux.dev \
--cc=jolsa@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-kselftest@vger.kernel.org \
--cc=martin.lau@linux.dev \
--cc=memxor@gmail.com \
--cc=shuah@kernel.org \
--cc=song@kernel.org \
--cc=thomas.petazzoni@bootlin.com \
--cc=yonghong.song@linux.dev \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.