* [PATCH mptcp-next 0/5] selftests: mptcp: get counters from nstat history
@ 2025-11-03 19:19 Matthieu Baerts (NGI0)
2025-11-03 19:19 ` [PATCH mptcp-next 1/5] selftests: mptcp: lib: introduce 'nstat_{init,get}' Matthieu Baerts (NGI0)
` (5 more replies)
0 siblings, 6 replies; 9+ messages in thread
From: Matthieu Baerts (NGI0) @ 2025-11-03 19:19 UTC (permalink / raw)
To: MPTCP Upstream; +Cc: Matthieu Baerts (NGI0)
When debugging MPTCP Join selftest with a "debug" kernel config, I
noticed checking all the different counters was sometimes slower than
the test itself. Fetching the counters once, then reading them from the
history file that was already there seems to save more than 5 minutes
when running the whole MPTCP Join selftest.
- Patch 1: move code to mptcp_lib.sh to prepare the new features.
- Patch 2: simplify mptcp_lib_pr_err_stats helper use.
- Patch 3: remove unused last column from nstat output.
- Patch 4: improve stats dump in mptcp_join.sh.
- Patch 5: get counters from nstat history.
Based-on: <20251102-slft-join-inst-v2-0-b4f3ba15a7c4@kernel.org>
Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
---
Matthieu Baerts (NGI0) (5):
selftests: mptcp: lib: introduce 'nstat_{init,get}'
selftests: mptcp: lib: remove stats files args
selftests: mptcp: lib: stats: remove nstat rate columns
selftests: mptcp: join: dump stats from history
selftests: mptcp: lib: get counters from nstat history
tools/testing/selftests/net/mptcp/mptcp_connect.sh | 100 ++++++++-------------
tools/testing/selftests/net/mptcp/mptcp_join.sh | 31 ++++---
tools/testing/selftests/net/mptcp/mptcp_lib.sh | 45 ++++++++--
tools/testing/selftests/net/mptcp/mptcp_sockopt.sh | 15 ++--
tools/testing/selftests/net/mptcp/simult_flows.sh | 15 ++--
5 files changed, 104 insertions(+), 102 deletions(-)
---
base-commit: 1b41f9e417a8db60baf3686b81346131d2d81f30
change-id: 20251101-slft-nstat-cache-db4d2962c5ce
Best regards,
--
Matthieu Baerts (NGI0) <matttbe@kernel.org>
^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH mptcp-next 1/5] selftests: mptcp: lib: introduce 'nstat_{init,get}'
2025-11-03 19:19 [PATCH mptcp-next 0/5] selftests: mptcp: get counters from nstat history Matthieu Baerts (NGI0)
@ 2025-11-03 19:19 ` Matthieu Baerts (NGI0)
2025-11-03 19:19 ` [PATCH mptcp-next 2/5] selftests: mptcp: lib: remove stats files args Matthieu Baerts (NGI0)
` (4 subsequent siblings)
5 siblings, 0 replies; 9+ messages in thread
From: Matthieu Baerts (NGI0) @ 2025-11-03 19:19 UTC (permalink / raw)
To: MPTCP Upstream; +Cc: Matthieu Baerts (NGI0)
These new helpers are easier to read than the long and multi lines
commands. Plus it will ease the addition of new features related to that
in the next commits.
No behavioural changes intended.
Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
---
tools/testing/selftests/net/mptcp/mptcp_connect.sh | 12 ++++--------
tools/testing/selftests/net/mptcp/mptcp_join.sh | 12 ++++--------
tools/testing/selftests/net/mptcp/mptcp_lib.sh | 14 ++++++++++++++
tools/testing/selftests/net/mptcp/mptcp_sockopt.sh | 12 ++++--------
tools/testing/selftests/net/mptcp/simult_flows.sh | 12 ++++--------
5 files changed, 30 insertions(+), 32 deletions(-)
diff --git a/tools/testing/selftests/net/mptcp/mptcp_connect.sh b/tools/testing/selftests/net/mptcp/mptcp_connect.sh
index 9b7b93f8eb0c..e1f34508490a 100755
--- a/tools/testing/selftests/net/mptcp/mptcp_connect.sh
+++ b/tools/testing/selftests/net/mptcp/mptcp_connect.sh
@@ -384,11 +384,9 @@ do_transfer()
sleep 1
fi
- NSTAT_HISTORY=/tmp/${listener_ns}.nstat ip netns exec ${listener_ns} \
- nstat -n
+ mptcp_lib_nstat_init "${listener_ns}"
if [ ${listener_ns} != ${connector_ns} ]; then
- NSTAT_HISTORY=/tmp/${connector_ns}.nstat ip netns exec ${connector_ns} \
- nstat -n
+ mptcp_lib_nstat_init "${connector_ns}"
fi
local stat_synrx_last_l
@@ -436,11 +434,9 @@ do_transfer()
kill ${cappid_connector}
fi
- NSTAT_HISTORY=/tmp/${listener_ns}.nstat ip netns exec ${listener_ns} \
- nstat | grep Tcp > /tmp/${listener_ns}.out
+ mptcp_lib_nstat_get "${listener_ns}"
if [ ${listener_ns} != ${connector_ns} ]; then
- NSTAT_HISTORY=/tmp/${connector_ns}.nstat ip netns exec ${connector_ns} \
- nstat | grep Tcp > /tmp/${connector_ns}.out
+ mptcp_lib_nstat_get "${connector_ns}"
fi
local duration
diff --git a/tools/testing/selftests/net/mptcp/mptcp_join.sh b/tools/testing/selftests/net/mptcp/mptcp_join.sh
index 495b14baccba..ee24adbcfb0c 100755
--- a/tools/testing/selftests/net/mptcp/mptcp_join.sh
+++ b/tools/testing/selftests/net/mptcp/mptcp_join.sh
@@ -1000,10 +1000,8 @@ do_transfer()
cond_start_capture ${listener_ns}
- NSTAT_HISTORY=/tmp/${listener_ns}.nstat ip netns exec ${listener_ns} \
- nstat -n
- NSTAT_HISTORY=/tmp/${connector_ns}.nstat ip netns exec ${connector_ns} \
- nstat -n
+ mptcp_lib_nstat_init "${listener_ns}"
+ mptcp_lib_nstat_init "${connector_ns}"
local extra_args
if [ $speed = "fast" ]; then
@@ -1085,10 +1083,8 @@ do_transfer()
cond_stop_capture
- NSTAT_HISTORY=/tmp/${listener_ns}.nstat ip netns exec ${listener_ns} \
- nstat | grep Tcp > /tmp/${listener_ns}.out
- NSTAT_HISTORY=/tmp/${connector_ns}.nstat ip netns exec ${connector_ns} \
- nstat | grep Tcp > /tmp/${connector_ns}.out
+ mptcp_lib_nstat_get "${listener_ns}"
+ mptcp_lib_nstat_get "${connector_ns}"
if [ ${rets} -ne 0 ] || [ ${retc} -ne 0 ]; then
fail_test "client exit code $retc, server $rets"
diff --git a/tools/testing/selftests/net/mptcp/mptcp_lib.sh b/tools/testing/selftests/net/mptcp/mptcp_lib.sh
index d62e653d48b0..d03aa817ac27 100644
--- a/tools/testing/selftests/net/mptcp/mptcp_lib.sh
+++ b/tools/testing/selftests/net/mptcp/mptcp_lib.sh
@@ -355,6 +355,20 @@ mptcp_lib_is_v6() {
[ -z "${1##*:*}" ]
}
+mptcp_lib_nstat_init() {
+ local ns="${1}"
+
+ NSTAT_HISTORY="/tmp/${ns}.nstat" ip netns exec "${ns}" nstat -n
+}
+
+mptcp_lib_nstat_get() {
+ local ns="${1}"
+
+ # filter out non-*TCP stats
+ NSTAT_HISTORY="/tmp/${ns}.nstat" ip netns exec "${ns}" nstat |
+ grep Tcp > "/tmp/${ns}.out"
+}
+
# $1: ns, $2: MIB counter
mptcp_lib_get_counter() {
local ns="${1}"
diff --git a/tools/testing/selftests/net/mptcp/mptcp_sockopt.sh b/tools/testing/selftests/net/mptcp/mptcp_sockopt.sh
index f01989be6e9b..343615908558 100755
--- a/tools/testing/selftests/net/mptcp/mptcp_sockopt.sh
+++ b/tools/testing/selftests/net/mptcp/mptcp_sockopt.sh
@@ -169,10 +169,8 @@ do_transfer()
cmsg+=",TCPINQ"
fi
- NSTAT_HISTORY=/tmp/${listener_ns}.nstat ip netns exec ${listener_ns} \
- nstat -n
- NSTAT_HISTORY=/tmp/${connector_ns}.nstat ip netns exec ${connector_ns} \
- nstat -n
+ mptcp_lib_nstat_init "${listener_ns}"
+ mptcp_lib_nstat_init "${connector_ns}"
timeout ${timeout_test} \
ip netns exec ${listener_ns} \
@@ -194,10 +192,8 @@ do_transfer()
wait $spid
local rets=$?
- NSTAT_HISTORY=/tmp/${listener_ns}.nstat ip netns exec ${listener_ns} \
- nstat | grep Tcp > /tmp/${listener_ns}.out
- NSTAT_HISTORY=/tmp/${connector_ns}.nstat ip netns exec ${connector_ns} \
- nstat | grep Tcp > /tmp/${connector_ns}.out
+ mptcp_lib_nstat_get "${listener_ns}"
+ mptcp_lib_nstat_get "${connector_ns}"
print_title "Transfer ${ip:2}"
if [ ${rets} -ne 0 ] || [ ${retc} -ne 0 ]; then
diff --git a/tools/testing/selftests/net/mptcp/simult_flows.sh b/tools/testing/selftests/net/mptcp/simult_flows.sh
index 1903e8e84a31..fbd1685d1adc 100755
--- a/tools/testing/selftests/net/mptcp/simult_flows.sh
+++ b/tools/testing/selftests/net/mptcp/simult_flows.sh
@@ -155,10 +155,8 @@ do_transfer()
sleep 1
fi
- NSTAT_HISTORY=/tmp/${ns3}.nstat ip netns exec ${ns3} \
- nstat -n
- NSTAT_HISTORY=/tmp/${ns1}.nstat ip netns exec ${ns1} \
- nstat -n
+ mptcp_lib_nstat_init "${ns3}"
+ mptcp_lib_nstat_init "${ns1}"
timeout ${timeout_test} \
ip netns exec ${ns3} \
@@ -185,10 +183,8 @@ do_transfer()
kill ${cappid_connector}
fi
- NSTAT_HISTORY=/tmp/${ns3}.nstat ip netns exec ${ns3} \
- nstat | grep Tcp > /tmp/${ns3}.out
- NSTAT_HISTORY=/tmp/${ns1}.nstat ip netns exec ${ns1} \
- nstat | grep Tcp > /tmp/${ns1}.out
+ mptcp_lib_nstat_get "${ns3}"
+ mptcp_lib_nstat_get "${ns1}"
cmp $sin $cout > /dev/null 2>&1
local cmps=$?
--
2.51.0
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH mptcp-next 2/5] selftests: mptcp: lib: remove stats files args
2025-11-03 19:19 [PATCH mptcp-next 0/5] selftests: mptcp: get counters from nstat history Matthieu Baerts (NGI0)
2025-11-03 19:19 ` [PATCH mptcp-next 1/5] selftests: mptcp: lib: introduce 'nstat_{init,get}' Matthieu Baerts (NGI0)
@ 2025-11-03 19:19 ` Matthieu Baerts (NGI0)
2025-11-03 19:19 ` [PATCH mptcp-next 3/5] selftests: mptcp: lib: stats: remove nstat rate columns Matthieu Baerts (NGI0)
` (3 subsequent siblings)
5 siblings, 0 replies; 9+ messages in thread
From: Matthieu Baerts (NGI0) @ 2025-11-03 19:19 UTC (permalink / raw)
To: MPTCP Upstream; +Cc: Matthieu Baerts (NGI0)
Now that these files are written from MPTCP lib helpers, the stats file
paths are uniformed. Then, no need to specify them from the each
selftest.
No behavioural changes intended.
Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
---
tools/testing/selftests/net/mptcp/mptcp_connect.sh | 3 +--
tools/testing/selftests/net/mptcp/mptcp_join.sh | 3 +--
tools/testing/selftests/net/mptcp/mptcp_lib.sh | 15 ++++++++++-----
tools/testing/selftests/net/mptcp/mptcp_sockopt.sh | 3 +--
tools/testing/selftests/net/mptcp/simult_flows.sh | 3 +--
5 files changed, 14 insertions(+), 13 deletions(-)
diff --git a/tools/testing/selftests/net/mptcp/mptcp_connect.sh b/tools/testing/selftests/net/mptcp/mptcp_connect.sh
index e1f34508490a..4ff2d02429d3 100755
--- a/tools/testing/selftests/net/mptcp/mptcp_connect.sh
+++ b/tools/testing/selftests/net/mptcp/mptcp_connect.sh
@@ -444,8 +444,7 @@ do_transfer()
printf "(duration %05sms) " "${duration}"
if [ ${rets} -ne 0 ] || [ ${retc} -ne 0 ]; then
mptcp_lib_pr_fail "client exit code $retc, server $rets"
- mptcp_lib_pr_err_stats "${listener_ns}" "${connector_ns}" "${port}" \
- "/tmp/${listener_ns}.out" "/tmp/${connector_ns}.out"
+ mptcp_lib_pr_err_stats "${listener_ns}" "${connector_ns}" "${port}"
echo
cat "$capout"
diff --git a/tools/testing/selftests/net/mptcp/mptcp_join.sh b/tools/testing/selftests/net/mptcp/mptcp_join.sh
index ee24adbcfb0c..ad0981e0b377 100755
--- a/tools/testing/selftests/net/mptcp/mptcp_join.sh
+++ b/tools/testing/selftests/net/mptcp/mptcp_join.sh
@@ -1088,8 +1088,7 @@ do_transfer()
if [ ${rets} -ne 0 ] || [ ${retc} -ne 0 ]; then
fail_test "client exit code $retc, server $rets"
- mptcp_lib_pr_err_stats "${listener_ns}" "${connector_ns}" "${port}" \
- "/tmp/${listener_ns}.out" "/tmp/${connector_ns}.out"
+ mptcp_lib_pr_err_stats "${listener_ns}" "${connector_ns}" "${port}"
return 1
fi
diff --git a/tools/testing/selftests/net/mptcp/mptcp_lib.sh b/tools/testing/selftests/net/mptcp/mptcp_lib.sh
index d03aa817ac27..22ab39749ca2 100644
--- a/tools/testing/selftests/net/mptcp/mptcp_lib.sh
+++ b/tools/testing/selftests/net/mptcp/mptcp_lib.sh
@@ -106,23 +106,28 @@ mptcp_lib_pr_info() {
mptcp_lib_print_info "INFO: ${*}"
}
-# $1-2: listener/connector ns ; $3 port ; $4-5 listener/connector stat file
+mptcp_lib_pr_nstat() {
+ local ns="${1}"
+ local hist="/tmp/${ns}.out"
+
+ cat "${hist}"
+}
+
+# $1-2: listener/connector ns ; $3 port
mptcp_lib_pr_err_stats() {
local lns="${1}"
local cns="${2}"
local port="${3}"
- local lstat="${4}"
- local cstat="${5}"
echo -en "${MPTCP_LIB_COLOR_RED}"
{
printf "\nnetns %s (listener) socket stat for %d:\n" "${lns}" "${port}"
ip netns exec "${lns}" ss -Menitam -o "sport = :${port}"
- cat "${lstat}"
+ mptcp_lib_pr_nstat "${lns}"
printf "\nnetns %s (connector) socket stat for %d:\n" "${cns}" "${port}"
ip netns exec "${cns}" ss -Menitam -o "dport = :${port}"
- [ "${lstat}" != "${cstat}" ] && cat "${cstat}"
+ [ "${lns}" != "${cns}" ] && mptcp_lib_pr_nstat "${cns}"
} 1>&2
echo -en "${MPTCP_LIB_COLOR_RESET}"
}
diff --git a/tools/testing/selftests/net/mptcp/mptcp_sockopt.sh b/tools/testing/selftests/net/mptcp/mptcp_sockopt.sh
index 343615908558..42d533b95ec7 100755
--- a/tools/testing/selftests/net/mptcp/mptcp_sockopt.sh
+++ b/tools/testing/selftests/net/mptcp/mptcp_sockopt.sh
@@ -198,8 +198,7 @@ do_transfer()
print_title "Transfer ${ip:2}"
if [ ${rets} -ne 0 ] || [ ${retc} -ne 0 ]; then
mptcp_lib_pr_fail "client exit code $retc, server $rets"
- mptcp_lib_pr_err_stats "${listener_ns}" "${connector_ns}" "${port}" \
- "/tmp/${listener_ns}.out" "/tmp/${connector_ns}.out"
+ mptcp_lib_pr_err_stats "${listener_ns}" "${connector_ns}" "${port}"
mptcp_lib_result_fail "transfer ${ip}"
diff --git a/tools/testing/selftests/net/mptcp/simult_flows.sh b/tools/testing/selftests/net/mptcp/simult_flows.sh
index fbd1685d1adc..503cb59571a4 100755
--- a/tools/testing/selftests/net/mptcp/simult_flows.sh
+++ b/tools/testing/selftests/net/mptcp/simult_flows.sh
@@ -200,8 +200,7 @@ do_transfer()
fi
mptcp_lib_pr_fail "client exit code $retc, server $rets"
- mptcp_lib_pr_err_stats "${ns3}" "${ns1}" "${port}" \
- "/tmp/${ns3}.out" "/tmp/${ns1}.out"
+ mptcp_lib_pr_err_stats "${ns3}" "${ns1}" "${port}"
ls -l $sin $cout
ls -l $cin $sout
--
2.51.0
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH mptcp-next 3/5] selftests: mptcp: lib: stats: remove nstat rate columns
2025-11-03 19:19 [PATCH mptcp-next 0/5] selftests: mptcp: get counters from nstat history Matthieu Baerts (NGI0)
2025-11-03 19:19 ` [PATCH mptcp-next 1/5] selftests: mptcp: lib: introduce 'nstat_{init,get}' Matthieu Baerts (NGI0)
2025-11-03 19:19 ` [PATCH mptcp-next 2/5] selftests: mptcp: lib: remove stats files args Matthieu Baerts (NGI0)
@ 2025-11-03 19:19 ` Matthieu Baerts (NGI0)
2025-11-03 19:19 ` [PATCH mptcp-next 4/5] selftests: mptcp: join: dump stats from history Matthieu Baerts (NGI0)
` (2 subsequent siblings)
5 siblings, 0 replies; 9+ messages in thread
From: Matthieu Baerts (NGI0) @ 2025-11-03 19:19 UTC (permalink / raw)
To: MPTCP Upstream; +Cc: Matthieu Baerts (NGI0)
With the MPTCP selftests, the nstat daemon is not used. It means that
the last column (the rate) is always 0.0, and that's not something
interesting to display.
Then, this last column can be filtered out.
Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
---
tools/testing/selftests/net/mptcp/mptcp_lib.sh | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/tools/testing/selftests/net/mptcp/mptcp_lib.sh b/tools/testing/selftests/net/mptcp/mptcp_lib.sh
index 22ab39749ca2..f59268b25707 100644
--- a/tools/testing/selftests/net/mptcp/mptcp_lib.sh
+++ b/tools/testing/selftests/net/mptcp/mptcp_lib.sh
@@ -369,9 +369,9 @@ mptcp_lib_nstat_init() {
mptcp_lib_nstat_get() {
local ns="${1}"
- # filter out non-*TCP stats
+ # filter out non-*TCP stats, and the rate (last column)
NSTAT_HISTORY="/tmp/${ns}.nstat" ip netns exec "${ns}" nstat |
- grep Tcp > "/tmp/${ns}.out"
+ grep -o ".*Tcp\S\+\s\+[0-9]\+" > "/tmp/${ns}.out"
}
# $1: ns, $2: MIB counter
--
2.51.0
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH mptcp-next 4/5] selftests: mptcp: join: dump stats from history
2025-11-03 19:19 [PATCH mptcp-next 0/5] selftests: mptcp: get counters from nstat history Matthieu Baerts (NGI0)
` (2 preceding siblings ...)
2025-11-03 19:19 ` [PATCH mptcp-next 3/5] selftests: mptcp: lib: stats: remove nstat rate columns Matthieu Baerts (NGI0)
@ 2025-11-03 19:19 ` Matthieu Baerts (NGI0)
2025-11-03 19:19 ` [PATCH mptcp-next 5/5] selftests: mptcp: lib: get counters from nstat history Matthieu Baerts (NGI0)
2025-11-03 20:58 ` [PATCH mptcp-next 0/5] selftests: mptcp: " MPTCP CI
5 siblings, 0 replies; 9+ messages in thread
From: Matthieu Baerts (NGI0) @ 2025-11-03 19:19 UTC (permalink / raw)
To: MPTCP Upstream; +Cc: Matthieu Baerts (NGI0)
In case of errors, dump the stats from history instead of using nstat.
There are multiple advantages to that:
- The same filters from pr_err_stats are used, e.g. the unused 'rate'
column is not displayed.
- The counters are closer to the ones from when the test stopped.
- While at it, the errors can be better presented: error colours, a
small indentation to distinguish the different parts, extra new lines.
Even if it should only happen in rare cases -- internal errors, or netns
issues -- if no history is available, 'nstat' is used like before, just
in case.
Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
---
tools/testing/selftests/net/mptcp/mptcp_join.sh | 16 ++++++++++++----
tools/testing/selftests/net/mptcp/mptcp_lib.sh | 6 +++++-
2 files changed, 17 insertions(+), 5 deletions(-)
diff --git a/tools/testing/selftests/net/mptcp/mptcp_join.sh b/tools/testing/selftests/net/mptcp/mptcp_join.sh
index ad0981e0b377..6afcf6ad2788 100755
--- a/tools/testing/selftests/net/mptcp/mptcp_join.sh
+++ b/tools/testing/selftests/net/mptcp/mptcp_join.sh
@@ -1163,12 +1163,20 @@ run_tests()
do_transfer ${listener_ns} ${connector_ns} MPTCP MPTCP ${connect_addr}
}
+_dump_stats()
+{
+ local ns="${1}"
+ local side="${2}"
+
+ mptcp_lib_print_err "${side} ns stats (${ns2})"
+ mptcp_lib_pr_nstat "${ns}"
+ echo
+}
+
dump_stats()
{
- echo Server ns stats
- ip netns exec $ns1 nstat -as | grep Tcp
- echo Client ns stats
- ip netns exec $ns2 nstat -as | grep Tcp
+ _dump_stats "${ns1}" "Server"
+ _dump_stats "${ns2}" "Client"
}
chk_csum_nr()
diff --git a/tools/testing/selftests/net/mptcp/mptcp_lib.sh b/tools/testing/selftests/net/mptcp/mptcp_lib.sh
index f59268b25707..603f33885f8e 100644
--- a/tools/testing/selftests/net/mptcp/mptcp_lib.sh
+++ b/tools/testing/selftests/net/mptcp/mptcp_lib.sh
@@ -110,7 +110,11 @@ mptcp_lib_pr_nstat() {
local ns="${1}"
local hist="/tmp/${ns}.out"
- cat "${hist}"
+ if [ -f "${hist}" ]; then
+ awk '{ print " "$0 }' "${hist}"
+ else
+ ip netns exec "${ns}" nstat -as | grep Tcp
+ fi
}
# $1-2: listener/connector ns ; $3 port
--
2.51.0
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH mptcp-next 5/5] selftests: mptcp: lib: get counters from nstat history
2025-11-03 19:19 [PATCH mptcp-next 0/5] selftests: mptcp: get counters from nstat history Matthieu Baerts (NGI0)
` (3 preceding siblings ...)
2025-11-03 19:19 ` [PATCH mptcp-next 4/5] selftests: mptcp: join: dump stats from history Matthieu Baerts (NGI0)
@ 2025-11-03 19:19 ` Matthieu Baerts (NGI0)
2025-11-03 20:58 ` [PATCH mptcp-next 0/5] selftests: mptcp: " MPTCP CI
5 siblings, 0 replies; 9+ messages in thread
From: Matthieu Baerts (NGI0) @ 2025-11-03 19:19 UTC (permalink / raw)
To: MPTCP Upstream; +Cc: Matthieu Baerts (NGI0)
Before, 'nstat' was used to retrieve each individual counter: this means
querying 4 different sources from /proc/net and iterating over 100+
counters each time. Instead, the stats could be retrieved once, and the
output file could be parsed for each counter. Even better, such file is
already present: the nstat history file.
To be able to get this working, the nstat history file also needs to
contains zero counters too, so it is still possible to know if a counter
is missing or set to 0.
This also simplifies mptcp_connect.sh: instead of checking multiple
counters before and after a test to compute the difference, the stats
history files can be reset before each test, and nstat can display only
the difference.
mptcp_lib_get_counter() continues to work when no history file is
available: by fetching nstat directly, like before. This is the case in
diag.sh and userspace_pm.sh where there is no need to save the history
file. This is also the case in mptcp_join.sh, when 'run_tests' is
executed in the background: easier to continue fetching counters than
updating the history each time it is needed.
Note: 'nstat' is called with '-s' in mptcp_lib_nstat_get(), so this
helper can be called multiple times during the test if needed.
Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
---
tools/testing/selftests/net/mptcp/mptcp_connect.sh | 85 +++++++++-------------
tools/testing/selftests/net/mptcp/mptcp_lib.sh | 16 +++-
2 files changed, 46 insertions(+), 55 deletions(-)
diff --git a/tools/testing/selftests/net/mptcp/mptcp_connect.sh b/tools/testing/selftests/net/mptcp/mptcp_connect.sh
index 4ff2d02429d3..3a804abebd2c 100755
--- a/tools/testing/selftests/net/mptcp/mptcp_connect.sh
+++ b/tools/testing/selftests/net/mptcp/mptcp_connect.sh
@@ -389,21 +389,6 @@ do_transfer()
mptcp_lib_nstat_init "${connector_ns}"
fi
- local stat_synrx_last_l
- local stat_ackrx_last_l
- local stat_cookietx_last
- local stat_cookierx_last
- local stat_csum_err_s
- local stat_csum_err_c
- local stat_tcpfb_last_l
- stat_synrx_last_l=$(mptcp_lib_get_counter "${listener_ns}" "MPTcpExtMPCapableSYNRX")
- stat_ackrx_last_l=$(mptcp_lib_get_counter "${listener_ns}" "MPTcpExtMPCapableACKRX")
- stat_cookietx_last=$(mptcp_lib_get_counter "${listener_ns}" "TcpExtSyncookiesSent")
- stat_cookierx_last=$(mptcp_lib_get_counter "${listener_ns}" "TcpExtSyncookiesRecv")
- stat_csum_err_s=$(mptcp_lib_get_counter "${listener_ns}" "MPTcpExtDataCsumErr")
- stat_csum_err_c=$(mptcp_lib_get_counter "${connector_ns}" "MPTcpExtDataCsumErr")
- stat_tcpfb_last_l=$(mptcp_lib_get_counter "${listener_ns}" "MPTcpExtMPCapableFallbackACK")
-
timeout ${timeout_test} \
ip netns exec ${listener_ns} \
./mptcp_connect -t ${timeout_poll} -l -p $port -s ${srv_proto} \
@@ -458,38 +443,38 @@ do_transfer()
rets=$?
local extra=""
- local stat_synrx_now_l
- local stat_ackrx_now_l
- local stat_cookietx_now
- local stat_cookierx_now
- local stat_ooo_now
- local stat_tcpfb_now_l
- stat_synrx_now_l=$(mptcp_lib_get_counter "${listener_ns}" "MPTcpExtMPCapableSYNRX")
- stat_ackrx_now_l=$(mptcp_lib_get_counter "${listener_ns}" "MPTcpExtMPCapableACKRX")
- stat_cookietx_now=$(mptcp_lib_get_counter "${listener_ns}" "TcpExtSyncookiesSent")
- stat_cookierx_now=$(mptcp_lib_get_counter "${listener_ns}" "TcpExtSyncookiesRecv")
- stat_ooo_now=$(mptcp_lib_get_counter "${listener_ns}" "TcpExtTCPOFOQueue")
- stat_tcpfb_now_l=$(mptcp_lib_get_counter "${listener_ns}" "MPTcpExtMPCapableFallbackACK")
+ local stat_synrx
+ local stat_ackrx
+ local stat_cookietx
+ local stat_cookierx
+ local stat_ooo
+ local stat_tcpfb
+ stat_synrx=$(mptcp_lib_get_counter "${listener_ns}" "MPTcpExtMPCapableSYNRX")
+ stat_ackrx=$(mptcp_lib_get_counter "${listener_ns}" "MPTcpExtMPCapableACKRX")
+ stat_cookietx=$(mptcp_lib_get_counter "${listener_ns}" "TcpExtSyncookiesSent")
+ stat_cookierx=$(mptcp_lib_get_counter "${listener_ns}" "TcpExtSyncookiesRecv")
+ stat_ooo=$(mptcp_lib_get_counter "${listener_ns}" "TcpExtTCPOFOQueue")
+ stat_tcpfb=$(mptcp_lib_get_counter "${listener_ns}" "MPTcpExtMPCapableFallbackACK")
- expect_synrx=$((stat_synrx_last_l))
- expect_ackrx=$((stat_ackrx_last_l))
+ expect_synrx=0
+ expect_ackrx=0
cookies=$(ip netns exec ${listener_ns} sysctl net.ipv4.tcp_syncookies)
cookies=${cookies##*=}
if [ ${cl_proto} = "MPTCP" ] && [ ${srv_proto} = "MPTCP" ]; then
- expect_synrx=$((stat_synrx_last_l+connect_per_transfer))
- expect_ackrx=$((stat_ackrx_last_l+connect_per_transfer))
+ expect_synrx=${connect_per_transfer}
+ expect_ackrx=${connect_per_transfer}
fi
- if [ ${stat_synrx_now_l} -lt ${expect_synrx} ]; then
- mptcp_lib_pr_fail "lower MPC SYN rx (${stat_synrx_now_l})" \
+ if [ ${stat_synrx} -lt ${expect_synrx} ]; then
+ mptcp_lib_pr_fail "lower MPC SYN rx (${stat_synrx})" \
"than expected (${expect_synrx})"
retc=1
fi
- if [ ${stat_ackrx_now_l} -lt ${expect_ackrx} ]; then
- if [ ${stat_ooo_now} -eq 0 ]; then
- mptcp_lib_pr_fail "lower MPC ACK rx (${stat_ackrx_now_l})" \
+ if [ ${stat_ackrx} -lt ${expect_ackrx} ]; then
+ if [ ${stat_ooo} -eq 0 ]; then
+ mptcp_lib_pr_fail "lower MPC ACK rx (${stat_ackrx})" \
"than expected (${expect_ackrx})"
rets=1
else
@@ -503,47 +488,45 @@ do_transfer()
csum_err_s=$(mptcp_lib_get_counter "${listener_ns}" "MPTcpExtDataCsumErr")
csum_err_c=$(mptcp_lib_get_counter "${connector_ns}" "MPTcpExtDataCsumErr")
- local csum_err_s_nr=$((csum_err_s - stat_csum_err_s))
- if [ $csum_err_s_nr -gt 0 ]; then
- mptcp_lib_pr_fail "server got ${csum_err_s_nr} data checksum error[s]"
+ if [ $csum_err_s -gt 0 ]; then
+ mptcp_lib_pr_fail "server got ${csum_err_s} data checksum error[s]"
rets=1
fi
- local csum_err_c_nr=$((csum_err_c - stat_csum_err_c))
- if [ $csum_err_c_nr -gt 0 ]; then
- mptcp_lib_pr_fail "client got ${csum_err_c_nr} data checksum error[s]"
+ if [ $csum_err_c -gt 0 ]; then
+ mptcp_lib_pr_fail "client got ${csum_err_c} data checksum error[s]"
retc=1
fi
fi
- if [ ${stat_ooo_now} -eq 0 ] && [ ${stat_tcpfb_last_l} -ne ${stat_tcpfb_now_l} ]; then
+ if [ ${stat_ooo} -eq 0 ] && [ ${stat_tcpfb} -gt 0 ]; then
mptcp_lib_pr_fail "unexpected fallback to TCP"
rets=1
fi
if [ $cookies -eq 2 ];then
- if [ $stat_cookietx_last -ge $stat_cookietx_now ] ;then
+ if [ $stat_cookietx -eq 0 ] ;then
extra+=" WARN: CookieSent: did not advance"
fi
- if [ $stat_cookierx_last -ge $stat_cookierx_now ] ;then
+ if [ $stat_cookierx -eq 0 ] ;then
extra+=" WARN: CookieRecv: did not advance"
fi
else
- if [ $stat_cookietx_last -ne $stat_cookietx_now ] ;then
+ if [ $stat_cookietx -gt 0 ] ;then
extra+=" WARN: CookieSent: changed"
fi
- if [ $stat_cookierx_last -ne $stat_cookierx_now ] ;then
+ if [ $stat_cookierx -gt 0 ] ;then
extra+=" WARN: CookieRecv: changed"
fi
fi
- if [ ${stat_synrx_now_l} -gt ${expect_synrx} ]; then
+ if [ ${stat_synrx} -gt ${expect_synrx} ]; then
extra+=" WARN: SYNRX: expect ${expect_synrx},"
- extra+=" got ${stat_synrx_now_l} (probably retransmissions)"
+ extra+=" got ${stat_synrx} (probably retransmissions)"
fi
- if [ ${stat_ackrx_now_l} -gt ${expect_ackrx} ]; then
+ if [ ${stat_ackrx} -gt ${expect_ackrx} ]; then
extra+=" WARN: ACKRX: expect ${expect_ackrx},"
- extra+=" got ${stat_ackrx_now_l} (probably retransmissions)"
+ extra+=" got ${stat_ackrx} (probably retransmissions)"
fi
if [ $retc -eq 0 ] && [ $rets -eq 0 ]; then
diff --git a/tools/testing/selftests/net/mptcp/mptcp_lib.sh b/tools/testing/selftests/net/mptcp/mptcp_lib.sh
index 603f33885f8e..ce6c92826be7 100644
--- a/tools/testing/selftests/net/mptcp/mptcp_lib.sh
+++ b/tools/testing/selftests/net/mptcp/mptcp_lib.sh
@@ -111,7 +111,7 @@ mptcp_lib_pr_nstat() {
local hist="/tmp/${ns}.out"
if [ -f "${hist}" ]; then
- awk '{ print " "$0 }' "${hist}"
+ awk '$2 != 0 { print " "$0 }' "${hist}"
else
ip netns exec "${ns}" nstat -as | grep Tcp
fi
@@ -367,6 +367,7 @@ mptcp_lib_is_v6() {
mptcp_lib_nstat_init() {
local ns="${1}"
+ rm -f "/tmp/${ns}."{nstat,out}
NSTAT_HISTORY="/tmp/${ns}.nstat" ip netns exec "${ns}" nstat -n
}
@@ -374,18 +375,25 @@ mptcp_lib_nstat_get() {
local ns="${1}"
# filter out non-*TCP stats, and the rate (last column)
- NSTAT_HISTORY="/tmp/${ns}.nstat" ip netns exec "${ns}" nstat |
+ NSTAT_HISTORY="/tmp/${ns}.nstat" ip netns exec "${ns}" nstat -sz |
grep -o ".*Tcp\S\+\s\+[0-9]\+" > "/tmp/${ns}.out"
}
# $1: ns, $2: MIB counter
+# Get the counter from the history (mptcp_lib_nstat_{init,get}()) if available.
+# If not, get the counter from nstat ignoring any history.
mptcp_lib_get_counter() {
local ns="${1}"
local counter="${2}"
+ local hist="/tmp/${ns}.out"
local count
- count=$(ip netns exec "${ns}" nstat -asz "${counter}" |
- awk 'NR==1 {next} {print $2}')
+ if [[ -s "${hist}" && "${counter}" == *"Tcp"* ]]; then
+ count=$(awk "/^${counter} / {print \$2; exit}" "${hist}")
+ else
+ count=$(ip netns exec "${ns}" nstat -asz "${counter}" |
+ awk 'NR==1 {next} {print $2}')
+ fi
if [ -z "${count}" ]; then
mptcp_lib_fail_if_expected_feature "${counter} counter"
return 1
--
2.51.0
^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [PATCH mptcp-next 0/5] selftests: mptcp: get counters from nstat history
2025-11-03 19:19 [PATCH mptcp-next 0/5] selftests: mptcp: get counters from nstat history Matthieu Baerts (NGI0)
` (4 preceding siblings ...)
2025-11-03 19:19 ` [PATCH mptcp-next 5/5] selftests: mptcp: lib: get counters from nstat history Matthieu Baerts (NGI0)
@ 2025-11-03 20:58 ` MPTCP CI
2025-11-04 21:13 ` Paolo Abeni
5 siblings, 1 reply; 9+ messages in thread
From: MPTCP CI @ 2025-11-03 20:58 UTC (permalink / raw)
To: Matthieu Baerts; +Cc: mptcp
Hi Matthieu,
Thank you for your modifications, that's great!
Our CI did some validations and here is its report:
- KVM Validation: normal (except selftest_mptcp_join): Unstable: 2 failed test(s): packetdrill_fastclose selftest_mptcp_connect_mmap 🔴
- KVM Validation: normal (only selftest_mptcp_join): Success! ✅
- KVM Validation: debug (except selftest_mptcp_join): Unstable: 1 failed test(s): packetdrill_regressions 🔴
- KVM Validation: debug (only selftest_mptcp_join): Success! ✅
- KVM Validation: btf-normal (only bpftest_all): Success! ✅
- KVM Validation: btf-debug (only bpftest_all): Success! ✅
- Task: https://github.com/multipath-tcp/mptcp_net-next/actions/runs/19047087376
Initiator: Patchew Applier
Commits: https://github.com/multipath-tcp/mptcp_net-next/commits/9e66ab4bc31b
Patchwork: https://patchwork.kernel.org/project/mptcp/list/?series=1019082
If there are some issues, you can reproduce them using the same environment as
the one used by the CI thanks to a docker image, e.g.:
$ cd [kernel source code]
$ docker run -v "${PWD}:${PWD}:rw" -w "${PWD}" --privileged --rm -it \
--pull always mptcp/mptcp-upstream-virtme-docker:latest \
auto-normal
For more details:
https://github.com/multipath-tcp/mptcp-upstream-virtme-docker
Please note that despite all the efforts that have been already done to have a
stable tests suite when executed on a public CI like here, it is possible some
reported issues are not due to your modifications. Still, do not hesitate to
help us improve that ;-)
Cheers,
MPTCP GH Action bot
Bot operated by Matthieu Baerts (NGI0 Core)
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH mptcp-next 0/5] selftests: mptcp: get counters from nstat history
2025-11-03 20:58 ` [PATCH mptcp-next 0/5] selftests: mptcp: " MPTCP CI
@ 2025-11-04 21:13 ` Paolo Abeni
2025-11-05 10:58 ` Matthieu Baerts
0 siblings, 1 reply; 9+ messages in thread
From: Paolo Abeni @ 2025-11-04 21:13 UTC (permalink / raw)
To: mptcp, Matthieu Baerts
Hi Mat,
The series LGTM! actually that ugly old syntax I introduced bothered me
since a while, thanks for fixing it!
/P
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH mptcp-next 0/5] selftests: mptcp: get counters from nstat history
2025-11-04 21:13 ` Paolo Abeni
@ 2025-11-05 10:58 ` Matthieu Baerts
0 siblings, 0 replies; 9+ messages in thread
From: Matthieu Baerts @ 2025-11-05 10:58 UTC (permalink / raw)
To: Paolo Abeni; +Cc: mptcp
Hi Paolo,
On 04/11/2025 22:13, Paolo Abeni wrote:
> The series LGTM! actually that ugly old syntax I introduced bothered me
> since a while, thanks for fixing it!
Thank you for the review!
Now in our tree:
New patches for t/upstream:
- 5fc66ff0c21d: selftests: mptcp: lib: introduce 'nstat_{init,get}'
- 85c2658ab280: selftests: mptcp: lib: remove stats files args
- c03f469e66cd: selftests: mptcp: lib: stats: remove nstat rate columns
- 7c215cadfe13: selftests: mptcp: join: dump stats from history
- 1e8ac2ba9238: selftests: mptcp: lib: get counters from nstat history
- Results: 47634a71c01a..fdaf439eed61 (export)
Tests are now in progress:
- export:
https://github.com/multipath-tcp/mptcp_net-next/commit/4cf71a5e2203016f33c5584d5a926eca7a9529ff/checks
Cheers,
Matt
--
Sponsored by the NGI0 Core fund.
^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2025-11-05 10:58 UTC | newest]
Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-11-03 19:19 [PATCH mptcp-next 0/5] selftests: mptcp: get counters from nstat history Matthieu Baerts (NGI0)
2025-11-03 19:19 ` [PATCH mptcp-next 1/5] selftests: mptcp: lib: introduce 'nstat_{init,get}' Matthieu Baerts (NGI0)
2025-11-03 19:19 ` [PATCH mptcp-next 2/5] selftests: mptcp: lib: remove stats files args Matthieu Baerts (NGI0)
2025-11-03 19:19 ` [PATCH mptcp-next 3/5] selftests: mptcp: lib: stats: remove nstat rate columns Matthieu Baerts (NGI0)
2025-11-03 19:19 ` [PATCH mptcp-next 4/5] selftests: mptcp: join: dump stats from history Matthieu Baerts (NGI0)
2025-11-03 19:19 ` [PATCH mptcp-next 5/5] selftests: mptcp: lib: get counters from nstat history Matthieu Baerts (NGI0)
2025-11-03 20:58 ` [PATCH mptcp-next 0/5] selftests: mptcp: " MPTCP CI
2025-11-04 21:13 ` Paolo Abeni
2025-11-05 10:58 ` Matthieu Baerts
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox