lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [day] [month] [year] [list]
Message-ID: <20251025160905.3857885-383-sashal@kernel.org>
Date: Sat, 25 Oct 2025 12:00:14 -0400
From: Sasha Levin <sashal@...nel.org>
To: patches@...ts.linux.dev,
	stable@...r.kernel.org
Cc: Jakub Kicinski <kuba@...nel.org>,
	Sasha Levin <sashal@...nel.org>,
	andrew+netdev@...n.ch,
	davem@...emloft.net,
	edumazet@...gle.com,
	pabeni@...hat.com,
	ast@...nel.org,
	daniel@...earbox.net,
	hawk@...nel.org,
	john.fastabend@...il.com,
	netdev@...r.kernel.org,
	bpf@...r.kernel.org
Subject: [PATCH AUTOSEL 6.17] selftests: drv-net: hds: restore hds settings

From: Jakub Kicinski <kuba@...nel.org>

[ Upstream commit ee3ae27721fb994ac0b4705b5806ce68a5a74c73 ]

The test currently modifies the HDS settings and doesn't restore them.
This may cause subsequent tests to fail (or pass when they should not).
Add defer()ed reset handling.

Link: https://patch.msgid.link/20250825175939.2249165-1-kuba@kernel.org
Signed-off-by: Jakub Kicinski <kuba@...nel.org>
Signed-off-by: Sasha Levin <sashal@...nel.org>
---

LLM Generated explanations, may be completely bogus:

YES

- Fixes a real bug in the selftest: The test was mutating device HDS
  settings and not restoring them, which can make subsequent tests fail
  or pass incorrectly. The commit adds a robust, deferred cleanup to
  restore both HDS mode and threshold to their original values, directly
  addressing the issue described in the commit message.

- Adds targeted, low-risk cleanup helpers:
  - Introduces `_hds_reset()` to restore original settings captured
    before modification. It first tries resetting `tcp-data-split` to
    `"unknown"` (auto) and, if that doesn’t match the prior value, falls
    back to the exact original value; it also restores `hds-thresh` if
    it changed. See `tools/testing/selftests/drivers/net/hds.py:63`–81.
  - Adds `_defer_reset_hds()` which captures the current ring settings
    (if supported) and schedules `_hds_reset()` using the existing
    deferred cleanup mechanism. See
    `tools/testing/selftests/drivers/net/hds.py:84`–90.
  - This follows existing patterns used elsewhere in the selftests
    (e.g., explicit defers in iou-zcrx), increasing consistency across
    tests (cf. `tools/testing/selftests/drivers/net/hw/iou-
    zcrx.py:50`–54, 81–85, 112–116).

- Ensures cleanup runs even on failures: The selftest framework flushes
  the global defer queue after each subtest, so scheduled resets will
  execute regardless of exceptions or skips. See
  `tools/testing/selftests/net/lib/py/ksft.py:271`.

- Minimal, contained changes: Only test code is touched (no kernel or
  driver changes). The changes are small and localized to
  `tools/testing/selftests/drivers/net/hds.py`.

- Defensive behavior and broad compatibility:
  - `_defer_reset_hds()` only schedules a reset if the device reports
    `hds-thresh` or `tcp-data-split` support and quietly ignores
    `NlError` exceptions (graceful on older kernels/drivers that don’t
    support these attributes), see
    `tools/testing/selftests/drivers/net/hds.py:84`–90.
  - Individual setters still check capabilities and skip when features
    aren’t supported (e.g., `get_hds`, `get_hds_thresh`), maintaining
    current skip behavior.

- Systematic application at mutation points: The new
  `_defer_reset_hds()` is invoked at the start of each function that
  modifies HDS-related state:
  - `set_hds_enable()` at
    `tools/testing/selftests/drivers/net/hds.py:93`–99.
  - `set_hds_disable()` at
    `tools/testing/selftests/drivers/net/hds.py:111`–119.
  - `set_hds_thresh_zero()` at
    `tools/testing/selftests/drivers/net/hds.py:129`–137.
  - `set_hds_thresh_random()` at
    `tools/testing/selftests/drivers/net/hds.py:147`–156`.
  - `set_hds_thresh_max()` at
    `tools/testing/selftests/drivers/net/hds.py:178`–186`.
  - `set_hds_thresh_gt()` at
    `tools/testing/selftests/drivers/net/hds.py:196`–205`.
  - `set_xdp()` when it changes `tcp-data-split` from `'enabled'` to
    `'unknown'` at
    `tools/testing/selftests/drivers/net/hds.py:217`–223`.
  - Existing explicit defer in `enabled_set_xdp()` remains (restores
    `'unknown'`), see
    `tools/testing/selftests/drivers/net/hds.py:235`–239.

- No architectural or behavioral risk to the kernel: The change affects
  only Python selftests, improving test isolation and reliability. It
  does not introduce new features or alter kernel behavior.

Given it is a clear test fix that prevents cross-test contamination, is
self-contained, low-risk, and improves the reliability of the selftest
suite, it meets stable backport criteria.

 tools/testing/selftests/drivers/net/hds.py | 39 ++++++++++++++++++++++
 1 file changed, 39 insertions(+)

diff --git a/tools/testing/selftests/drivers/net/hds.py b/tools/testing/selftests/drivers/net/hds.py
index 7c90a040ce45a..a2011474e6255 100755
--- a/tools/testing/selftests/drivers/net/hds.py
+++ b/tools/testing/selftests/drivers/net/hds.py
@@ -3,6 +3,7 @@
 
 import errno
 import os
+from typing import Union
 from lib.py import ksft_run, ksft_exit, ksft_eq, ksft_raises, KsftSkipEx
 from lib.py import CmdExitFailure, EthtoolFamily, NlError
 from lib.py import NetDrvEnv
@@ -58,7 +59,39 @@ def get_hds_thresh(cfg, netnl) -> None:
     if 'hds-thresh' not in rings:
         raise KsftSkipEx('hds-thresh not supported by device')
 
+
+def _hds_reset(cfg, netnl, rings) -> None:
+    cur = netnl.rings_get({'header': {'dev-index': cfg.ifindex}})
+
+    arg = {'header': {'dev-index': cfg.ifindex}}
+    if cur.get('tcp-data-split') != rings.get('tcp-data-split'):
+        # Try to reset to "unknown" first, we don't know if the setting
+        # was the default or user chose it. Default seems more likely.
+        arg['tcp-data-split'] = "unknown"
+        netnl.rings_set(arg)
+        cur = netnl.rings_get({'header': {'dev-index': cfg.ifindex}})
+        if cur['tcp-data-split'] == rings['tcp-data-split']:
+            del arg['tcp-data-split']
+        else:
+            # Try the explicit setting
+            arg['tcp-data-split'] = rings['tcp-data-split']
+    if cur.get('hds-thresh') != rings.get('hds-thresh'):
+        arg['hds-thresh'] = rings['hds-thresh']
+    if len(arg) > 1:
+        netnl.rings_set(arg)
+
+
+def _defer_reset_hds(cfg, netnl) -> Union[dict, None]:
+    try:
+        rings = netnl.rings_get({'header': {'dev-index': cfg.ifindex}})
+        if 'hds-thresh' in rings or 'tcp-data-split' in rings:
+            defer(_hds_reset, cfg, netnl, rings)
+    except NlError as e:
+        pass
+
+
 def set_hds_enable(cfg, netnl) -> None:
+    _defer_reset_hds(cfg, netnl)
     try:
         netnl.rings_set({'header': {'dev-index': cfg.ifindex}, 'tcp-data-split': 'enabled'})
     except NlError as e:
@@ -76,6 +109,7 @@ def set_hds_enable(cfg, netnl) -> None:
     ksft_eq('enabled', rings['tcp-data-split'])
 
 def set_hds_disable(cfg, netnl) -> None:
+    _defer_reset_hds(cfg, netnl)
     try:
         netnl.rings_set({'header': {'dev-index': cfg.ifindex}, 'tcp-data-split': 'disabled'})
     except NlError as e:
@@ -93,6 +127,7 @@ def set_hds_disable(cfg, netnl) -> None:
     ksft_eq('disabled', rings['tcp-data-split'])
 
 def set_hds_thresh_zero(cfg, netnl) -> None:
+    _defer_reset_hds(cfg, netnl)
     try:
         netnl.rings_set({'header': {'dev-index': cfg.ifindex}, 'hds-thresh': 0})
     except NlError as e:
@@ -110,6 +145,7 @@ def set_hds_thresh_zero(cfg, netnl) -> None:
     ksft_eq(0, rings['hds-thresh'])
 
 def set_hds_thresh_random(cfg, netnl) -> None:
+    _defer_reset_hds(cfg, netnl)
     try:
         rings = netnl.rings_get({'header': {'dev-index': cfg.ifindex}})
     except NlError as e:
@@ -140,6 +176,7 @@ def set_hds_thresh_random(cfg, netnl) -> None:
     ksft_eq(hds_thresh, rings['hds-thresh'])
 
 def set_hds_thresh_max(cfg, netnl) -> None:
+    _defer_reset_hds(cfg, netnl)
     try:
         rings = netnl.rings_get({'header': {'dev-index': cfg.ifindex}})
     except NlError as e:
@@ -157,6 +194,7 @@ def set_hds_thresh_max(cfg, netnl) -> None:
     ksft_eq(rings['hds-thresh'], rings['hds-thresh-max'])
 
 def set_hds_thresh_gt(cfg, netnl) -> None:
+    _defer_reset_hds(cfg, netnl)
     try:
         rings = netnl.rings_get({'header': {'dev-index': cfg.ifindex}})
     except NlError as e:
@@ -178,6 +216,7 @@ def set_xdp(cfg, netnl) -> None:
     """
     mode = _get_hds_mode(cfg, netnl)
     if mode == 'enabled':
+        _defer_reset_hds(cfg, netnl)
         netnl.rings_set({'header': {'dev-index': cfg.ifindex},
                          'tcp-data-split': 'unknown'})
 
-- 
2.51.0


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ