Path: blob/master/tools/testing/selftests/drivers/net/ring_reconfig.py
38237 views
#!/usr/bin/env python31# SPDX-License-Identifier: GPL-2.023"""4Test channel and ring size configuration via ethtool (-L / -G).5"""67from lib.py import ksft_run, ksft_exit, ksft_pr8from lib.py import ksft_eq9from lib.py import NetDrvEpEnv, EthtoolFamily, GenerateTraffic10from lib.py import defer, NlError111213def channels(cfg) -> None:14"""15Twiddle channel counts in various combinations of parameters.16We're only looking for driver adhering to the requested config17if the config is accepted and crashes.18"""19ehdr = {'header':{'dev-index': cfg.ifindex}}20chans = cfg.eth.channels_get(ehdr)2122all_keys = ["rx", "tx", "combined"]23mixes = [{"combined"}, {"rx", "tx"}, {"rx", "combined"}, {"tx", "combined"},24{"rx", "tx", "combined"},]2526# Get the set of keys that device actually supports27restore = {}28supported = set()29for key in all_keys:30if key + "-max" in chans:31supported.add(key)32restore |= {key + "-count": chans[key + "-count"]}3334defer(cfg.eth.channels_set, ehdr | restore)3536def test_config(config):37try:38cfg.eth.channels_set(ehdr | config)39get = cfg.eth.channels_get(ehdr)40for k, v in config.items():41ksft_eq(get.get(k, 0), v)42except NlError as e:43failed.append(mix)44ksft_pr("Can't set", config, e)45else:46ksft_pr("Okay", config)4748failed = []49for mix in mixes:50if not mix.issubset(supported):51continue5253# Set all the values in the mix to 1, other supported to 054config = {}55for key in all_keys:56config[key + "-count"] = 1 if key in mix else 057test_config(config)5859for mix in mixes:60if not mix.issubset(supported):61continue62if mix in failed:63continue6465# Set all the values in the mix to max, other supported to 066config = {}67for key in all_keys:68config[key + "-count"] = chans[key + '-max'] if key in mix else 069test_config(config)707172def _configure_min_ring_cnt(cfg) -> None:73""" Try to configure a single Rx/Tx ring. """74ehdr = {'header':{'dev-index': cfg.ifindex}}75chans = cfg.eth.channels_get(ehdr)7677all_keys = ["rx-count", "tx-count", "combined-count"]78restore = {}79config = {}80for key in all_keys:81if key in chans:82restore[key] = chans[key]83config[key] = 08485if chans.get('combined-count', 0) > 1:86config['combined-count'] = 187elif chans.get('rx-count', 0) > 1 and chans.get('tx-count', 0) > 1:88config['tx-count'] = 189config['rx-count'] = 190else:91# looks like we're already on 1 channel92return9394cfg.eth.channels_set(ehdr | config)95defer(cfg.eth.channels_set, ehdr | restore)969798def ringparam(cfg) -> None:99"""100Tweak the ringparam configuration. Try to run some traffic over min101ring size to make sure it actually functions.102"""103ehdr = {'header':{'dev-index': cfg.ifindex}}104rings = cfg.eth.rings_get(ehdr)105106restore = {}107maxes = {}108params = set()109for key in rings.keys():110if 'max' in key:111param = key[:-4]112maxes[param] = rings[key]113params.add(param)114restore[param] = rings[param]115116defer(cfg.eth.rings_set, ehdr | restore)117118# Speed up the reconfig by configuring just one ring119_configure_min_ring_cnt(cfg)120121# Try to reach min on all settings122for param in params:123val = rings[param]124while True:125try:126cfg.eth.rings_set({'header':{'dev-index': cfg.ifindex},127param: val // 2})128if val == 0:129break130val //= 2131except NlError:132break133134get = cfg.eth.rings_get(ehdr)135ksft_eq(get[param], val)136137ksft_pr(f"Reached min for '{param}' at {val} (max {rings[param]})")138139GenerateTraffic(cfg).wait_pkts_and_stop(10000)140141# Try max across all params, if the driver supports large rings142# this may OOM so we ignore errors143try:144ksft_pr("Applying max settings")145config = {p: maxes[p] for p in params}146cfg.eth.rings_set(ehdr | config)147except NlError as e:148ksft_pr("Can't set max params", config, e)149else:150GenerateTraffic(cfg).wait_pkts_and_stop(10000)151152153def main() -> None:154""" Ksft boiler plate main """155156with NetDrvEpEnv(__file__) as cfg:157cfg.eth = EthtoolFamily()158159ksft_run([channels,160ringparam],161args=(cfg, ))162ksft_exit()163164165if __name__ == "__main__":166main()167168169