1#!/usr/bin/env python3 2# SPDX-License-Identifier: GPL-2.0 3 4""" 5API level tests for RSS (mostly Netlink vs IOCTL). 6""" 7 8import glob 9from lib.py import ksft_run, ksft_exit, ksft_eq, ksft_is, ksft_ne 10from lib.py import KsftSkipEx, KsftFailEx 11from lib.py import defer, ethtool 12from lib.py import EthtoolFamily 13from lib.py import NetDrvEnv 14 15 16def _ethtool_create(cfg, act, opts): 17 output = ethtool(f"{act} {cfg.ifname} {opts}").stdout 18 # Output will be something like: "New RSS context is 1" or 19 # "Added rule with ID 7", we want the integer from the end 20 return int(output.split()[-1]) 21 22 23def test_rxfh_indir_ntf(cfg): 24 """ 25 Check that Netlink notifications are generated when RSS indirection 26 table was modified. 27 """ 28 29 qcnt = len(glob.glob(f"/sys/class/net/{cfg.ifname}/queues/rx-*")) 30 if qcnt < 2: 31 raise KsftSkipEx(f"Local has only {qcnt} queues") 32 33 ethnl = EthtoolFamily() 34 ethnl.ntf_subscribe("monitor") 35 36 ethtool(f"--disable-netlink -X {cfg.ifname} weight 0 1") 37 reset = defer(ethtool, f"-X {cfg.ifname} default") 38 39 ntf = next(ethnl.poll_ntf(duration=0.2), None) 40 if ntf is None: 41 raise KsftFailEx("No notification received") 42 ksft_eq(ntf["name"], "rss-ntf") 43 ksft_eq(set(ntf["msg"]["indir"]), {1}) 44 45 reset.exec() 46 ntf = next(ethnl.poll_ntf(duration=0.2), None) 47 if ntf is None: 48 raise KsftFailEx("No notification received after reset") 49 ksft_eq(ntf["name"], "rss-ntf") 50 ksft_is(ntf["msg"].get("context"), None) 51 ksft_ne(set(ntf["msg"]["indir"]), {1}) 52 53 54def test_rxfh_indir_ctx_ntf(cfg): 55 """ 56 Check that Netlink notifications are generated when RSS indirection 57 table was modified on an additional RSS context. 58 """ 59 60 qcnt = len(glob.glob(f"/sys/class/net/{cfg.ifname}/queues/rx-*")) 61 if qcnt < 2: 62 raise KsftSkipEx(f"Local has only {qcnt} queues") 63 64 ctx_id = _ethtool_create(cfg, "-X", "context new") 65 defer(ethtool, f"-X {cfg.ifname} context {ctx_id} delete") 66 67 ethnl = EthtoolFamily() 68 ethnl.ntf_subscribe("monitor") 69 70 ethtool(f"--disable-netlink -X {cfg.ifname} context {ctx_id} weight 0 1") 71 72 ntf = next(ethnl.poll_ntf(duration=0.2), None) 73 if ntf is None: 74 raise KsftFailEx("No notification received") 75 ksft_eq(ntf["name"], "rss-ntf") 76 ksft_eq(ntf["msg"].get("context"), ctx_id) 77 ksft_eq(set(ntf["msg"]["indir"]), {1}) 78 79 80def main() -> None: 81 """ Ksft boiler plate main """ 82 83 with NetDrvEnv(__file__, nsim_test=False) as cfg: 84 ksft_run(globs=globals(), case_pfx={"test_"}, args=(cfg, )) 85 ksft_exit() 86 87 88if __name__ == "__main__": 89 main() 90