diff options
Diffstat (limited to 'tools/testing/selftests/drivers/net/hw/xsk_reconfig.py')
| -rwxr-xr-x | tools/testing/selftests/drivers/net/hw/xsk_reconfig.py | 60 | 
1 files changed, 60 insertions, 0 deletions
| diff --git a/tools/testing/selftests/drivers/net/hw/xsk_reconfig.py b/tools/testing/selftests/drivers/net/hw/xsk_reconfig.py new file mode 100755 index 000000000000..d19d1d518208 --- /dev/null +++ b/tools/testing/selftests/drivers/net/hw/xsk_reconfig.py @@ -0,0 +1,60 @@ +#!/usr/bin/env python3 +# SPDX-License-Identifier: GPL-2.0 + +# This is intended to be run on a virtio-net guest interface. +# The test binds the XDP socket to the interface without setting +# the fill ring to trigger delayed refill_work. This helps to +# make it easier to reproduce the deadlock when XDP program, +# XDP socket bind/unbind, rx ring resize race with refill_work on +# the buggy kernel. +# +# The Qemu command to setup virtio-net +# -netdev tap,id=hostnet1,vhost=on,script=no,downscript=no +# -device virtio-net-pci,netdev=hostnet1,iommu_platform=on,disable-legacy=on + +from lib.py import ksft_exit, ksft_run +from lib.py import KsftSkipEx, KsftFailEx +from lib.py import NetDrvEnv +from lib.py import bkg, ip, cmd, ethtool +import time + +def _get_rx_ring_entries(cfg): +    output = ethtool(f"-g {cfg.ifname}", json=True) +    return output[0]["rx"] + +def setup_xsk(cfg, xdp_queue_id = 0) -> bkg: +    # Probe for support +    xdp = cmd(f'{cfg.net_lib_dir / "xdp_helper"} - -', fail=False) +    if xdp.ret == 255: +        raise KsftSkipEx('AF_XDP unsupported') +    elif xdp.ret > 0: +        raise KsftFailEx('unable to create AF_XDP socket') + +    try: +        return bkg(f'{cfg.net_lib_dir / "xdp_helper"} {cfg.ifindex} ' \ +                   '{xdp_queue_id} -z', ksft_wait=3) +    except: +        raise KsftSkipEx('Failed to bind XDP socket in zerocopy.\n' \ +                         'Please consider adding iommu_platform=on ' \ +                         'when setting up virtio-net-pci') + +def check_xdp_bind(cfg): +    with setup_xsk(cfg): +        ip(f"link set dev %s xdp obj %s sec xdp" % +           (cfg.ifname, cfg.net_lib_dir / "xdp_dummy.bpf.o")) +        ip(f"link set dev %s xdp off" % cfg.ifname) + +def check_rx_resize(cfg): +    with setup_xsk(cfg): +        rx_ring = _get_rx_ring_entries(cfg) +        ethtool(f"-G %s rx %d" % (cfg.ifname, rx_ring // 2)) +        ethtool(f"-G %s rx %d" % (cfg.ifname, rx_ring)) + +def main(): +    with NetDrvEnv(__file__, nsim_test=False) as cfg: +        ksft_run([check_xdp_bind, check_rx_resize], +                 args=(cfg, )) +    ksft_exit() + +if __name__ == "__main__": +    main() | 
