Some devices refresh the statistics exposed via ethtool only periodically, every stats-block-usecs (as reported by ethtool -c). ethtool_std_stats and ethtool_rmon sample the counters immediately after generating traffic, so on such devices they can read stale values and fail with a delta short of the packets just sent. Add a hw_stats_settle() helper which sleeps for 1.25x the configured stats-block-usecs (defaulting to 20ms when the device reports no, or a zero, period). Use it for ethtool std stats and RMON. The 1.25x/20msec heuristic matches what the Python tests do. Signed-off-by: Jakub Kicinski --- CC: andrew@lunn.ch CC: shuah@kernel.org CC: dsahern@kernel.org CC: idosch@nvidia.com CC: ioana.ciornei@nxp.com CC: petrm@nvidia.com CC: linux-kselftest@vger.kernel.org --- .../selftests/drivers/net/hw/ethtool_rmon.sh | 2 ++ .../selftests/drivers/net/hw/ethtool_std_stats.sh | 2 ++ tools/testing/selftests/net/forwarding/lib.sh | 15 +++++++++++++++ 3 files changed, 19 insertions(+) diff --git a/tools/testing/selftests/drivers/net/hw/ethtool_rmon.sh b/tools/testing/selftests/drivers/net/hw/ethtool_rmon.sh index 2ec19edddfaa..a074834cbe59 100755 --- a/tools/testing/selftests/drivers/net/hw/ethtool_rmon.sh +++ b/tools/testing/selftests/drivers/net/hw/ethtool_rmon.sh @@ -65,6 +65,8 @@ bucket_test() run_on "$iface" \ "$MZ" "$iface" -q -c "$num_tx" -p "$len" -a own -b bcast -d 10us + hw_stats_settle "$iface" + after=$(run_on "$iface" ethtool --json -S "$iface" --groups rmon | \ jq -r ".[0].rmon[\"${set}-pktsNtoM\"][$bucket].val") diff --git a/tools/testing/selftests/drivers/net/hw/ethtool_std_stats.sh b/tools/testing/selftests/drivers/net/hw/ethtool_std_stats.sh index 1b329b3f60c2..09f8128c51f3 100755 --- a/tools/testing/selftests/drivers/net/hw/ethtool_std_stats.sh +++ b/tools/testing/selftests/drivers/net/hw/ethtool_std_stats.sh @@ -48,6 +48,8 @@ traffic_test() # shellcheck disable=SC2086 # needs split options run_on "$neigh" "$MZ" "$neigh" -q -d 10usec -c "$num_rx" $pkt_format + hw_stats_settle "$int" + for i in "${!counters[@]}"; do read -r int grp cnt target exact_check xfail_message \ <<< "${counters[$i]}" diff --git a/tools/testing/selftests/net/forwarding/lib.sh b/tools/testing/selftests/net/forwarding/lib.sh index ac8358bcb22c..05acd4011456 100644 --- a/tools/testing/selftests/net/forwarding/lib.sh +++ b/tools/testing/selftests/net/forwarding/lib.sh @@ -406,6 +406,21 @@ get_ifname_by_ip() __run_on "$target" ip -j addr show to "$ip_addr" | jq -r '.[].ifname' } +# Wait for the device to refresh its HW statistics. Devices latch the stats +# reported via ethtool only every stats-block-usecs, so sample after that. +hw_stats_settle() +{ + local iface=$1; shift + local usecs + + # Match only a non-zero integer; 0 or "n/a" use default (20msec) + usecs=$(run_on "$iface" ethtool -c "$iface" 2>/dev/null | \ + sed -n 's/^stats-block-usecs:[[:space:]]*\([1-9][0-9]*\)$/\1/p') + usecs=${usecs:-20000} + + sleep "$(echo "$usecs * 1.25 / 1000 / 1000" | bc -l)" +} + # Whether the test is conforming to the requirements and usage described in # drivers/net/README.rst. : "${DRIVER_TEST_CONFORMANT:=no}" -- 2.55.0