[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <m2sejocfw2.fsf@gmail.com>
Date: Wed, 25 Jun 2025 10:46:53 +0100
From: Donald Hunter <donald.hunter@...il.com>
To: Jakub Kicinski <kuba@...nel.org>
Cc: davem@...emloft.net, netdev@...r.kernel.org, edumazet@...gle.com,
pabeni@...hat.com, andrew+netdev@...n.ch, horms@...nel.org,
maxime.chevallier@...tlin.com, sdf@...ichev.me, jdamato@...tly.com,
ecree.xilinx@...il.com
Subject: Re: [PATCH net-next v2 8/8] selftests: drv-net: test RSS Netlink
notifications
Jakub Kicinski <kuba@...nel.org> writes:
> Test that changing the RSS config generates Netlink notifications.
>
> # ./tools/testing/selftests/drivers/net/hw/rss_api.py
> TAP version 13
> 1..2
> ok 1 rss_api.test_rxfh_indir_ntf
> ok 2 rss_api.test_rxfh_indir_ctx_ntf
> # Totals: pass:2 fail:0 xfail:0 xpass:0 skip:0 error:0
>
> Signed-off-by: Jakub Kicinski <kuba@...nel.org>
> ---
> .../selftests/drivers/net/hw/rss_api.py | 89 +++++++++++++++++++
> 1 file changed, 89 insertions(+)
> create mode 100755 tools/testing/selftests/drivers/net/hw/rss_api.py
>
> diff --git a/tools/testing/selftests/drivers/net/hw/rss_api.py b/tools/testing/selftests/drivers/net/hw/rss_api.py
> new file mode 100755
> index 000000000000..db0f723a674b
> --- /dev/null
> +++ b/tools/testing/selftests/drivers/net/hw/rss_api.py
> @@ -0,0 +1,89 @@
> +#!/usr/bin/env python3
> +# SPDX-License-Identifier: GPL-2.0
> +
> +"""
> +API level tests for RSS (mostly Netlink vs IOCTL).
> +"""
> +
> +import glob
> +from lib.py import ksft_run, ksft_exit, ksft_eq, ksft_is, ksft_ne
> +from lib.py import KsftSkipEx, KsftFailEx
> +from lib.py import defer, ethtool
> +from lib.py import EthtoolFamily
> +from lib.py import NetDrvEnv
> +
> +
> +def _ethtool_create(cfg, act, opts):
> + output = ethtool(f"{act} {cfg.ifname} {opts}").stdout
> + # Output will be something like: "New RSS context is 1" or
> + # "Added rule with ID 7", we want the integer from the end
> + return int(output.split()[-1])
I think .split() is not required because you can access strings as
arrays.
Will this only ever need to handle single digit values?
> +def test_rxfh_indir_ntf(cfg):
> + """
> + Check that Netlink notifications are generated when RSS indirection
> + table was modified.
> + """
> +
> + qcnt = len(glob.glob(f"/sys/class/net/{cfg.ifname}/queues/rx-*"))
> + if qcnt < 2:
> + raise KsftSkipEx(f"Local has only {qcnt} queues")
> +
> + ethnl = EthtoolFamily()
> + ethnl.ntf_subscribe("monitor")
> +
> + ethtool(f"--disable-netlink -X {cfg.ifname} weight 0 1")
> + reset = defer(ethtool, f"-X {cfg.ifname} default")
> +
> + ntf = next(ethnl.poll_ntf(duration=0.2), None)
> + if ntf is None:
> + raise KsftFailEx("No notification received")
> + ksft_eq(ntf["name"], "rss-ntf")
> + ksft_eq(set(ntf["msg"]["indir"]), {1})
> +
> + reset.exec()
> + ntf = next(ethnl.poll_ntf(duration=0.2), None)
> + if ntf is None:
> + raise KsftFailEx("No notification received after reset")
> + ksft_eq(ntf["name"], "rss-ntf")
> + ksft_is(ntf["msg"].get("context"), None)
> + ksft_ne(set(ntf["msg"]["indir"]), {1})
> +
> +
> +def test_rxfh_indir_ctx_ntf(cfg):
> + """
> + Check that Netlink notifications are generated when RSS indirection
> + table was modified on an additional RSS context.
> + """
> +
> + qcnt = len(glob.glob(f"/sys/class/net/{cfg.ifname}/queues/rx-*"))
> + if qcnt < 2:
> + raise KsftSkipEx(f"Local has only {qcnt} queues")
> +
> + ctx_id = _ethtool_create(cfg, "-X", "context new")
> + defer(ethtool, f"-X {cfg.ifname} context {ctx_id} delete")
> +
> + ethnl = EthtoolFamily()
> + ethnl.ntf_subscribe("monitor")
> +
> + ethtool(f"--disable-netlink -X {cfg.ifname} context {ctx_id} weight 0 1")
> +
> + ntf = next(ethnl.poll_ntf(duration=0.2), None)
> + if ntf is None:
> + raise KsftFailEx("No notification received")
> + ksft_eq(ntf["name"], "rss-ntf")
> + ksft_eq(ntf["msg"].get("context"), ctx_id)
> + ksft_eq(set(ntf["msg"]["indir"]), {1})
> +
> +
> +def main() -> None:
> + """ Ksft boiler plate main """
> +
> + with NetDrvEnv(__file__, nsim_test=False) as cfg:
> + ksft_run(globs=globals(), case_pfx={"test_"}, args=(cfg, ))
> + ksft_exit()
> +
> +
> +if __name__ == "__main__":
> + main()
Powered by blists - more mailing lists