brintos

brintos / linux-shallow public Read only

0
0
Text · 3.8 KiB · 05b6fbb Raw
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