* [PATCH bpf-next v2] selftests/bpf: Track test_xdp_features DUT processes
@ 2026-08-12 8:28 Bochao Cao via B4 Relay
2026-08-12 9:23 ` bot+bpf-ci
2026-08-24 11:31 ` Daniel Borkmann
0 siblings, 2 replies; 4+ messages in thread
From: Bochao Cao via B4 Relay @ 2026-08-12 8:28 UTC (permalink / raw)
To: Andrii Nakryiko, Eduard Zingerman
Cc: Ihor Solodrai, Jiayuan Chen, Lorenzo Bianconi, Alexei Starovoitov,
Daniel Borkmann, David S. Miller, Jakub Kicinski,
Jesper Dangaard Brouer, John Fastabend, Stanislav Fomichev,
Kumar Kartikeya Dwivedi, Martin KaFai Lau, Song Liu,
Yonghong Song, Jiri Olsa, Emil Tsalapatis, Shuah Khan, bpf,
netdev, linux-kselftest, linux-kernel, Bochao Cao
From: Bochao Cao <bochaolucky@gmail.com>
test_xdp_features.sh waits for any xdp_features listener to appear and
uses pidof during cleanup. A concurrent test can therefore make another
test proceed before its own DUT is ready, and cleanup kills every
xdp_features process on the host. The readiness loop also has no timeout,
so a DUT that exits before listening leaves the test hung indefinitely.
Track one active DUT at a time, wait for ss to report that exact PID with
a bounded retry loop, and reap it after each test. Consult the shell job
table before signaling the DUT so a stale PID cannot target an unrelated
process. On failure, terminate the shell job with SIGKILL and reap it so
blocked I/O cannot hang cleanup. Install an EXIT trap and signal handlers
so failure paths also remove network setup.
Fixes: 4dba3e7852b7 ("selftests/bpf: introduce XDP compliance test tool")
Closes: https://bugs.debian.org/1136522
Signed-off-by: Bochao Cao <bochaolucky@gmail.com>
---
Tests:
- bash -n tools/testing/selftests/bpf/test_xdp_features.sh
- make -C tools/testing/selftests/bpf xdp_features
- sudo tools/testing/selftests/bpf/test_xdp_features.sh
- verified cleanup terminates a blocked DUT without affecting an unrelated process
---
Changes in v2:
- Clarify that avoiding name-wide process matching, rather than dropping a dependency, is the motivation.
- Track and reap one active DUT at a time instead of retaining historical PIDs.
- Address PID reuse by signaling only the current Bash job during cleanup.
- Use SIGKILL on failure cleanup so blocked DUT I/O cannot hang wait indefinitely.
- Link to v1: https://patch.msgid.link/20260805-xdp-dut-process-lifecycle-gmail-v1-1-45984df8d295@gmail.com
---
tools/testing/selftests/bpf/test_xdp_features.sh | 82 ++++++++++++++++++------
1 file changed, 62 insertions(+), 20 deletions(-)
diff --git a/tools/testing/selftests/bpf/test_xdp_features.sh b/tools/testing/selftests/bpf/test_xdp_features.sh
index 0aa71c4455c0..35ce0d4e2418 100755
--- a/tools/testing/selftests/bpf/test_xdp_features.sh
+++ b/tools/testing/selftests/bpf/test_xdp_features.sh
@@ -8,6 +8,7 @@ readonly V0_IP6=2001:db8::11
readonly V1_IP6=2001:db8::1
ret=1
+dut_pid=""
setup() {
{
@@ -30,77 +31,118 @@ setup() {
} > /dev/null 2>&1
}
+terminate_dut_server() {
+ [ -z "$dut_pid" ] && return
+
+ # Use the shell job instead of a PID which may have been reused.
+ if [ "$(jobs -pr %% 2> /dev/null)" = "$dut_pid" ]; then
+ kill -KILL %% 2> /dev/null || true
+ fi
+
+ wait "$dut_pid" 2> /dev/null || true
+ dut_pid=""
+}
+
cleanup() {
- ip link del v1 2> /dev/null
- ip netns del ${NS} 2> /dev/null
- [ "$(pidof xdp_features)" = "" ] || kill $(pidof xdp_features) 2> /dev/null
+ terminate_dut_server
+ ip link del v1 2> /dev/null || true
+ ip netns del "${NS}" 2> /dev/null || true
}
wait_for_dut_server() {
- while sleep 1; do
- ss -tlp | grep -q xdp_features
- [ $? -eq 0 ] && break
+ local i
+
+ for ((i = 0; i < 10; i++)); do
+ if [ "$(jobs -pr %% 2> /dev/null)" != "$dut_pid" ]; then
+ echo "xdp_features server $dut_pid exited before accepting connections" >&2
+ return 1
+ fi
+
+ if ss -tlp 2> /dev/null | grep -q "pid=$dut_pid,"; then
+ return 0
+ fi
+
+ sleep 1
done
+
+ echo "Timed out waiting for xdp_features server $dut_pid" >&2
+ return 1
+}
+
+start_dut_server() {
+ ./xdp_features "$@" &
+ dut_pid=$!
+ wait_for_dut_server
+}
+
+reap_dut_server() {
+ local status=0
+
+ wait "$dut_pid" || status=$?
+ dut_pid=""
+ return "$status"
}
test_xdp_features() {
setup
## XDP_PASS
- ./xdp_features -f XDP_PASS -D $V1_IP6 -T $V0_IP6 v1 &
- wait_for_dut_server
+ start_dut_server -f XDP_PASS -D $V1_IP6 -T $V0_IP6 v1
ip netns exec ${NS} ./xdp_features -t -f XDP_PASS \
-D $V1_IP6 -C $V1_IP6 \
-T $V0_IP6 v0
[ $? -ne 0 ] && exit
+ reap_dut_server
## XDP_DROP
- ./xdp_features -f XDP_DROP -D ::ffff:$V1_IP4 -T ::ffff:$V0_IP4 v1 &
- wait_for_dut_server
+ start_dut_server -f XDP_DROP -D ::ffff:$V1_IP4 -T ::ffff:$V0_IP4 v1
ip netns exec ${NS} ./xdp_features -t -f XDP_DROP \
-D ::ffff:$V1_IP4 \
-C ::ffff:$V1_IP4 \
-T ::ffff:$V0_IP4 v0
[ $? -ne 0 ] && exit
+ reap_dut_server
## XDP_ABORTED
- ./xdp_features -f XDP_ABORTED -D $V1_IP6 -T $V0_IP6 v1 &
- wait_for_dut_server
+ start_dut_server -f XDP_ABORTED -D $V1_IP6 -T $V0_IP6 v1
ip netns exec ${NS} ./xdp_features -t -f XDP_ABORTED \
-D $V1_IP6 -C $V1_IP6 \
-T $V0_IP6 v0
[ $? -ne 0 ] && exit
+ reap_dut_server
## XDP_TX
- ./xdp_features -f XDP_TX -D ::ffff:$V1_IP4 -T ::ffff:$V0_IP4 v1 &
- wait_for_dut_server
+ start_dut_server -f XDP_TX -D ::ffff:$V1_IP4 -T ::ffff:$V0_IP4 v1
ip netns exec ${NS} ./xdp_features -t -f XDP_TX \
-D ::ffff:$V1_IP4 \
-C ::ffff:$V1_IP4 \
-T ::ffff:$V0_IP4 v0
[ $? -ne 0 ] && exit
+ reap_dut_server
## XDP_REDIRECT
- ./xdp_features -f XDP_REDIRECT -D $V1_IP6 -T $V0_IP6 v1 &
- wait_for_dut_server
+ start_dut_server -f XDP_REDIRECT -D $V1_IP6 -T $V0_IP6 v1
ip netns exec ${NS} ./xdp_features -t -f XDP_REDIRECT \
-D $V1_IP6 -C $V1_IP6 \
-T $V0_IP6 v0
[ $? -ne 0 ] && exit
+ reap_dut_server
## XDP_NDO_XMIT
- ./xdp_features -f XDP_NDO_XMIT -D ::ffff:$V1_IP4 -T ::ffff:$V0_IP4 v1 &
- wait_for_dut_server
+ start_dut_server -f XDP_NDO_XMIT -D ::ffff:$V1_IP4 -T ::ffff:$V0_IP4 v1
ip netns exec ${NS} ./xdp_features -t -f XDP_NDO_XMIT \
-D ::ffff:$V1_IP4 \
-C ::ffff:$V1_IP4 \
-T ::ffff:$V0_IP4 v0
ret=$?
- cleanup
+ reap_dut_server
}
set -e
-trap cleanup 2 3 6 9
+trap cleanup EXIT
+trap 'exit 129' HUP
+trap 'exit 130' INT
+trap 'exit 143' TERM
test_xdp_features
---
base-commit: 07cb86aa50816b070b99c89bf948762ef035a1f2
change-id: 20260805-xdp-dut-process-lifecycle-gmail-6d60bf8dcdf1
Best regards,
--
Bochao Cao <bochaolucky@gmail.com>
^ permalink raw reply related [flat|nested] 4+ messages in thread* Re: [PATCH bpf-next v2] selftests/bpf: Track test_xdp_features DUT processes
2026-08-12 8:28 [PATCH bpf-next v2] selftests/bpf: Track test_xdp_features DUT processes Bochao Cao via B4 Relay
@ 2026-08-12 9:23 ` bot+bpf-ci
2026-08-24 11:31 ` Daniel Borkmann
1 sibling, 0 replies; 4+ messages in thread
From: bot+bpf-ci @ 2026-08-12 9:23 UTC (permalink / raw)
To: bochaolucky, andrii, eddyz87
Cc: ihor.solodrai, jiayuan.chen, lorenzo, ast, daniel, davem, kuba,
hawk, john.fastabend, sdf, memxor, martin.lau, song,
yonghong.song, jolsa, emil, shuah, bpf, netdev, linux-kselftest,
linux-kernel, bochaolucky, ast, andrii, daniel, martin.lau,
eddyz87, yonghong.song, clm, ihor.solodrai
[-- Attachment #1: Type: text/plain, Size: 1691 bytes --]
> diff --git a/tools/testing/selftests/bpf/test_xdp_features.sh b/tools/testing/selftests/bpf/test_xdp_features.sh
> index 0aa71c4455c0..35ce0d4e2418 100755
> --- a/tools/testing/selftests/bpf/test_xdp_features.sh
> +++ b/tools/testing/selftests/bpf/test_xdp_features.sh
[ ... ]
> +terminate_dut_server() {
> + [ -z "$dut_pid" ] && return
> +
> + # Use the shell job instead of a PID which may have been reused.
> + if [ "$(jobs -pr %% 2> /dev/null)" = "$dut_pid" ]; then
> + kill -KILL %% 2> /dev/null || true
> + fi
> +
> + wait "$dut_pid" 2> /dev/null || true
> + dut_pid=""
> +}
> +
> cleanup() {
> - ip link del v1 2> /dev/null
> - ip netns del ${NS} 2> /dev/null
> - [ "$(pidof xdp_features)" = "" ] || kill $(pidof xdp_features) 2> /dev/null
> + terminate_dut_server
> + ip link del v1 2> /dev/null || true
> + ip netns del "${NS}" 2> /dev/null || true
> }
Jiayuan Chen asked about removing the pidof dependency in v1: "It looks like
part of the motivation here is dropping the pidof dependency? I don't think
that's worth optimizing. Selftests already require a bunch of tools from
non-essential packages (ip, ss and ethtool in this very script)". Does the
removal of pidof serve another purpose beyond reducing dependencies, such as
fixing the concurrent test interference described in the commit message? If
the primary goal is fixing the race condition rather than removing a
dependency, it might be worth clarifying the motivation.
---
AI reviewed your patch. Please fix the bug or email reply why it's not a bug.
See: https://github.com/kernel-patches/vmtest/blob/master/ci/claude/README.md
CI run summary: https://github.com/kernel-patches/bpf/actions/runs/31579454720
^ permalink raw reply [flat|nested] 4+ messages in thread* Re: [PATCH bpf-next v2] selftests/bpf: Track test_xdp_features DUT processes
2026-08-12 8:28 [PATCH bpf-next v2] selftests/bpf: Track test_xdp_features DUT processes Bochao Cao via B4 Relay
2026-08-12 9:23 ` bot+bpf-ci
@ 2026-08-24 11:31 ` Daniel Borkmann
2026-08-24 14:49 ` Alexis Lothoré
1 sibling, 1 reply; 4+ messages in thread
From: Daniel Borkmann @ 2026-08-24 11:31 UTC (permalink / raw)
To: bochaolucky, Andrii Nakryiko, Eduard Zingerman
Cc: Ihor Solodrai, Jiayuan Chen, Alexei Starovoitov, Jakub Kicinski,
Stanislav Fomichev, Kumar Kartikeya Dwivedi, Song Liu,
Emil Tsalapatis, bpf, netdev, linux-kselftest, linux-kernel,
Alexis Lothoré
[ Trimming the excessive Cc list, and adding Alexis ]
On 8/12/26 10:28 AM, Bochao Cao via B4 Relay wrote:
> From: Bochao Cao <bochaolucky@gmail.com>
>
> test_xdp_features.sh waits for any xdp_features listener to appear and
> uses pidof during cleanup. A concurrent test can therefore make another
> test proceed before its own DUT is ready, and cleanup kills every
> xdp_features process on the host. The readiness loop also has no timeout,
> so a DUT that exits before listening leaves the test hung indefinitely.
>
> Track one active DUT at a time, wait for ss to report that exact PID with
> a bounded retry loop, and reap it after each test. Consult the shell job
> table before signaling the DUT so a stale PID cannot target an unrelated
> process. On failure, terminate the shell job with SIGKILL and reap it so
> blocked I/O cannot hang cleanup. Install an EXIT trap and signal handlers
> so failure paths also remove network setup.
>
> Fixes: 4dba3e7852b7 ("selftests/bpf: introduce XDP compliance test tool")
> Closes: https://bugs.debian.org/1136522
> Signed-off-by: Bochao Cao <bochaolucky@gmail.com>
> ---
> Tests:
> - bash -n tools/testing/selftests/bpf/test_xdp_features.sh
> - make -C tools/testing/selftests/bpf xdp_features
> - sudo tools/testing/selftests/bpf/test_xdp_features.sh
> - verified cleanup terminates a blocked DUT without affecting an unrelated process
> ---
> Changes in v2:
> - Clarify that avoiding name-wide process matching, rather than dropping a dependency, is the motivation.
> - Track and reap one active DUT at a time instead of retaining historical PIDs.
> - Address PID reuse by signaling only the current Bash job during cleanup.
> - Use SIGKILL on failure cleanup so blocked DUT I/O cannot hang wait indefinitely.
> - Link to v1: https://patch.msgid.link/20260805-xdp-dut-process-lifecycle-gmail-v1-1-45984df8d295@gmail.com
> ---
> tools/testing/selftests/bpf/test_xdp_features.sh | 82 ++++++++++++++++++------
> 1 file changed, 62 insertions(+), 20 deletions(-)
Sorry for the late reply. With regards to https://bugs.debian.org/1136522, src:linux deb
does not have to depend on this at all, so the src:linux can just get rid of procps in
any case if this is indeed the last dependency. I'm not seeing the test being run in our
BPF CI. I've Cc'ed Alexis as he's in the process of migrating and/or removing tests from
tools/testing/selftests/bpf/ depending on how they fit into test_progs framework. I'll
let him comment if there is already work in progress. It feels like this script could be
reworked into tools/testing/selftests/drivers/net/hw/ tests and removed altogether from
the tools/testing/selftests/bpf/ dir.
^ permalink raw reply [flat|nested] 4+ messages in thread* Re: [PATCH bpf-next v2] selftests/bpf: Track test_xdp_features DUT processes
2026-08-24 11:31 ` Daniel Borkmann
@ 2026-08-24 14:49 ` Alexis Lothoré
0 siblings, 0 replies; 4+ messages in thread
From: Alexis Lothoré @ 2026-08-24 14:49 UTC (permalink / raw)
To: Daniel Borkmann, bochaolucky, Andrii Nakryiko, Eduard Zingerman
Cc: Ihor Solodrai, Jiayuan Chen, Alexei Starovoitov, Jakub Kicinski,
Stanislav Fomichev, Kumar Kartikeya Dwivedi, Song Liu,
Emil Tsalapatis, bpf, netdev, linux-kselftest, linux-kernel,
Alexis Lothoré
Hi Daniel, thanks for the notification
On Mon Aug 24, 2026 at 1:31 PM CEST, Daniel Borkmann wrote:
> [ Trimming the excessive Cc list, and adding Alexis ]
>
> On 8/12/26 10:28 AM, Bochao Cao via B4 Relay wrote:
>> From: Bochao Cao <bochaolucky@gmail.com>
>>
>> test_xdp_features.sh waits for any xdp_features listener to appear and
>> uses pidof during cleanup. A concurrent test can therefore make another
>> test proceed before its own DUT is ready, and cleanup kills every
>> xdp_features process on the host. The readiness loop also has no timeout,
>> so a DUT that exits before listening leaves the test hung indefinitely.
>>
>> Track one active DUT at a time, wait for ss to report that exact PID with
>> a bounded retry loop, and reap it after each test. Consult the shell job
>> table before signaling the DUT so a stale PID cannot target an unrelated
>> process. On failure, terminate the shell job with SIGKILL and reap it so
>> blocked I/O cannot hang cleanup. Install an EXIT trap and signal handlers
>> so failure paths also remove network setup.
>>
>> Fixes: 4dba3e7852b7 ("selftests/bpf: introduce XDP compliance test tool")
>> Closes: https://bugs.debian.org/1136522
>> Signed-off-by: Bochao Cao <bochaolucky@gmail.com>
>> ---
>> Tests:
>> - bash -n tools/testing/selftests/bpf/test_xdp_features.sh
>> - make -C tools/testing/selftests/bpf xdp_features
>> - sudo tools/testing/selftests/bpf/test_xdp_features.sh
>> - verified cleanup terminates a blocked DUT without affecting an unrelated process
>> ---
>> Changes in v2:
>> - Clarify that avoiding name-wide process matching, rather than dropping a dependency, is the motivation.
>> - Track and reap one active DUT at a time instead of retaining historical PIDs.
>> - Address PID reuse by signaling only the current Bash job during cleanup.
>> - Use SIGKILL on failure cleanup so blocked DUT I/O cannot hang wait indefinitely.
>> - Link to v1: https://patch.msgid.link/20260805-xdp-dut-process-lifecycle-gmail-v1-1-45984df8d295@gmail.com
>> ---
>> tools/testing/selftests/bpf/test_xdp_features.sh | 82 ++++++++++++++++++------
>> 1 file changed, 62 insertions(+), 20 deletions(-)
>
> Sorry for the late reply. With regards to https://bugs.debian.org/1136522, src:linux deb
> does not have to depend on this at all, so the src:linux can just get rid of procps in
> any case if this is indeed the last dependency. I'm not seeing the test being run in our
> BPF CI. I've Cc'ed Alexis as he's in the process of migrating and/or removing tests from
> tools/testing/selftests/bpf/ depending on how they fit into test_progs framework. I'll
> let him comment if there is already work in progress. It feels like this script could be
> reworked into tools/testing/selftests/drivers/net/hw/ tests and removed altogether from
> the tools/testing/selftests/bpf/ dir.
There has been an attempt to fully convert and get rid of
test_xdp_features.sh, but discussions around the corresponding series
highlighted the need for the script to remain available for testing on
real hardware. Features covered by the test_xdp_features.sh that were
not covered yet by test_progs have been added to test_progs (in
xdp_cpumap_attach), see [1]. So there's currently no active effort on
this one on my side.
Alexis
[1] https://lore.kernel.org/bpf/20241009-convert_xdp_tests-v3-0-51cea913710c@bootlin.com/
--
Alexis Lothoré, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2026-08-24 14:49 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-08-12 8:28 [PATCH bpf-next v2] selftests/bpf: Track test_xdp_features DUT processes Bochao Cao via B4 Relay
2026-08-12 9:23 ` bot+bpf-ci
2026-08-24 11:31 ` Daniel Borkmann
2026-08-24 14:49 ` Alexis Lothoré
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox