131 lines · python
1#!/usr/bin/env python32# SPDX-License-Identifier: GPL-2.03 4import errno5import time6import os7from lib.py import ksft_run, ksft_exit, ksft_pr8from lib.py import KsftSkipEx, KsftFailEx9from lib.py import NetdevFamily, NlError10from lib.py import NetDrvEpEnv11from lib.py import cmd, tool, GenerateTraffic12 13 14def _write_fail_config(config):15 for key, value in config.items():16 with open("/sys/kernel/debug/fail_function/" + key, "w") as fp:17 fp.write(str(value) + "\n")18 19 20def _enable_pp_allocation_fail():21 if not os.path.exists("/sys/kernel/debug/fail_function"):22 raise KsftSkipEx("Kernel built without function error injection (or DebugFS)")23 24 if not os.path.exists("/sys/kernel/debug/fail_function/page_pool_alloc_pages"):25 with open("/sys/kernel/debug/fail_function/inject", "w") as fp:26 fp.write("page_pool_alloc_pages\n")27 28 _write_fail_config({29 "verbose": 0,30 "interval": 511,31 "probability": 100,32 "times": -1,33 })34 35 36def _disable_pp_allocation_fail():37 if not os.path.exists("/sys/kernel/debug/fail_function"):38 return39 40 if os.path.exists("/sys/kernel/debug/fail_function/page_pool_alloc_pages"):41 with open("/sys/kernel/debug/fail_function/inject", "w") as fp:42 fp.write("\n")43 44 _write_fail_config({45 "probability": 0,46 "times": 0,47 })48 49 50def test_pp_alloc(cfg, netdevnl):51 def get_stats():52 return netdevnl.qstats_get({"ifindex": cfg.ifindex}, dump=True)[0]53 54 def check_traffic_flowing():55 stat1 = get_stats()56 time.sleep(1)57 stat2 = get_stats()58 if stat2['rx-packets'] - stat1['rx-packets'] < 15000:59 raise KsftFailEx("Traffic seems low:", stat2['rx-packets'] - stat1['rx-packets'])60 61 62 try:63 stats = get_stats()64 except NlError as e:65 if e.nl_msg.error == -errno.EOPNOTSUPP:66 stats = {}67 else:68 raise69 if 'rx-alloc-fail' not in stats:70 raise KsftSkipEx("Driver does not report 'rx-alloc-fail' via qstats")71 72 set_g = False73 traffic = None74 try:75 traffic = GenerateTraffic(cfg)76 77 check_traffic_flowing()78 79 _enable_pp_allocation_fail()80 81 s1 = get_stats()82 time.sleep(3)83 s2 = get_stats()84 85 if s2['rx-alloc-fail'] - s1['rx-alloc-fail'] < 1:86 raise KsftSkipEx("Allocation failures not increasing")87 if s2['rx-alloc-fail'] - s1['rx-alloc-fail'] < 100:88 raise KsftSkipEx("Allocation increasing too slowly", s2['rx-alloc-fail'] - s1['rx-alloc-fail'],89 "packets:", s2['rx-packets'] - s1['rx-packets'])90 91 # Basic failures are fine, try to wobble some settings to catch extra failures92 check_traffic_flowing()93 g = tool("ethtool", "-g " + cfg.ifname, json=True)[0]94 if 'rx' in g and g["rx"] * 2 <= g["rx-max"]:95 new_g = g['rx'] * 296 elif 'rx' in g:97 new_g = g['rx'] // 298 else:99 new_g = None100 101 if new_g:102 set_g = cmd(f"ethtool -G {cfg.ifname} rx {new_g}", fail=False).ret == 0103 if set_g:104 ksft_pr("ethtool -G change retval: success")105 else:106 ksft_pr("ethtool -G change retval: did not succeed", new_g)107 else:108 ksft_pr("ethtool -G change retval: did not try")109 110 time.sleep(0.1)111 check_traffic_flowing()112 finally:113 _disable_pp_allocation_fail()114 if traffic:115 traffic.stop()116 time.sleep(0.1)117 if set_g:118 cmd(f"ethtool -G {cfg.ifname} rx {g['rx']}")119 120 121def main() -> None:122 netdevnl = NetdevFamily()123 with NetDrvEpEnv(__file__, nsim_test=False) as cfg:124 125 ksft_run([test_pp_alloc], args=(cfg, netdevnl, ))126 ksft_exit()127 128 129if __name__ == "__main__":130 main()131