File Index
Files and directories
Sign in
FILE

queues.py

File preview with syntax highlighting.

linux-6.19.14/tools/testing/selftests/drivers/net/queues.py PYTHON
  1#!/usr/bin/env python3
  2# SPDX-License-Identifier: GPL-2.0
  3
  4from lib.py import ksft_disruptive, ksft_exit, ksft_run
  5from lib.py import ksft_eq, ksft_not_in, ksft_raises, KsftSkipEx, KsftFailEx
  6from lib.py import EthtoolFamily, NetdevFamily, NlError
  7from lib.py import NetDrvEnv
  8from lib.py import bkg, cmd, defer, ip
  9import errno
 10import glob
 11import os
 12import socket
 13import struct
 14
 15def sys_get_queues(ifname, qtype='rx') -> int:
 16    folders = glob.glob(f'/sys/class/net/{ifname}/queues/{qtype}-*')
 17    return len(folders)
 18
 19
 20def nl_get_queues(cfg, nl, qtype='rx'):
 21    queues = nl.queue_get({'ifindex': cfg.ifindex}, dump=True)
 22    if queues:
 23        return len([q for q in queues if q['type'] == qtype])
 24    return None
 25
 26
 27def check_xsk(cfg, nl, xdp_queue_id=0) -> None:
 28    # Probe for support
 29    xdp = cmd(f'{cfg.net_lib_dir / "xdp_helper"} - -', fail=False)
 30    if xdp.ret == 255:
 31        raise KsftSkipEx('AF_XDP unsupported')
 32    elif xdp.ret > 0:
 33        raise KsftFailEx('unable to create AF_XDP socket')
 34
 35    with bkg(f'{cfg.net_lib_dir / "xdp_helper"} {cfg.ifindex} {xdp_queue_id}',
 36             ksft_wait=3):
 37
 38        rx = tx = False
 39
 40        queues = nl.queue_get({'ifindex': cfg.ifindex}, dump=True)
 41        if not queues:
 42            raise KsftSkipEx("Netlink reports no queues")
 43
 44        for q in queues:
 45            if q['id'] == 0:
 46                if q['type'] == 'rx':
 47                    rx = True
 48                if q['type'] == 'tx':
 49                    tx = True
 50
 51                ksft_eq(q.get('xsk', None), {},
 52                        comment="xsk attr on queue we configured")
 53            else:
 54                ksft_not_in('xsk', q,
 55                            comment="xsk attr on queue we didn't configure")
 56
 57        ksft_eq(rx, True)
 58        ksft_eq(tx, True)
 59
 60
 61def get_queues(cfg, nl) -> None:
 62    snl = NetdevFamily(recv_size=4096)
 63
 64    for qtype in ['rx', 'tx']:
 65        queues = nl_get_queues(cfg, snl, qtype)
 66        if not queues:
 67            raise KsftSkipEx('queue-get not supported by device')
 68
 69        expected = sys_get_queues(cfg.dev['ifname'], qtype)
 70        ksft_eq(queues, expected)
 71
 72
 73def addremove_queues(cfg, nl) -> None:
 74    queues = nl_get_queues(cfg, nl)
 75    if not queues:
 76        raise KsftSkipEx('queue-get not supported by device')
 77
 78    curr_queues = sys_get_queues(cfg.dev['ifname'])
 79    if curr_queues == 1:
 80        raise KsftSkipEx('cannot decrement queue: already at 1')
 81
 82    netnl = EthtoolFamily()
 83    channels = netnl.channels_get({'header': {'dev-index': cfg.ifindex}})
 84    rx_type = 'rx'
 85    if channels.get('combined-count', 0) > 0:
 86            rx_type = 'combined'
 87
 88    expected = curr_queues - 1
 89    cmd(f"ethtool -L {cfg.dev['ifname']} {rx_type} {expected}", timeout=10)
 90    queues = nl_get_queues(cfg, nl)
 91    ksft_eq(queues, expected)
 92
 93    expected = curr_queues
 94    cmd(f"ethtool -L {cfg.dev['ifname']} {rx_type} {expected}", timeout=10)
 95    queues = nl_get_queues(cfg, nl)
 96    ksft_eq(queues, expected)
 97
 98
 99@ksft_disruptive
100def check_down(cfg, nl) -> None:
101    # Check the NAPI IDs before interface goes down and hides them
102    napis = nl.napi_get({'ifindex': cfg.ifindex}, dump=True)
103
104    ip(f"link set dev {cfg.dev['ifname']} down")
105    defer(ip, f"link set dev {cfg.dev['ifname']} up")
106
107    with ksft_raises(NlError) as cm:
108        nl.queue_get({'ifindex': cfg.ifindex, 'id': 0, 'type': 'rx'})
109    ksft_eq(cm.exception.nl_msg.error, -errno.ENOENT)
110
111    if napis:
112        with ksft_raises(NlError) as cm:
113            nl.napi_get({'id': napis[0]['id']})
114        ksft_eq(cm.exception.nl_msg.error, -errno.ENOENT)
115
116
117def main() -> None:
118    with NetDrvEnv(__file__, queue_count=100) as cfg:
119        ksft_run([get_queues, addremove_queues, check_down, check_xsk],
120                 args=(cfg, NetdevFamily()))
121    ksft_exit()
122
123
124if __name__ == "__main__":
125    main()
~/ Read-only file preview.