mirror of
https://github.com/torvalds/linux.git
synced 2026-07-27 17:47:41 +02:00
Add a regression test for DualPI2 GSO backlog accounting when it is used as a child qdisc of QFQ. The test sends one UDP GSO datagram through a QFQ class with DualPI2 as the leaf qdisc. DualPI2 splits the skb into two segments. After the traffic drains, both QFQ and DualPI2 must report zero backlog and zero qlen. On kernels with the broken accounting, QFQ can keep a stale non-zero qlen after all real packets have been dequeued. Signed-off-by: Xingquan Liu <b1n@b1n.io> Acked-by: Jamal Hadi Salim <jhs@mojatatu.com> Reviewed-by: Victor Nogueira <victor@mojatatu.com> Link: https://patch.msgid.link/20260619151447.223640-2-b1n@b1n.io Signed-off-by: Jakub Kicinski <kuba@kernel.org>
44 lines
1.4 KiB
Python
Executable File
44 lines
1.4 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
# SPDX-License-Identifier: GPL-2.0
|
|
|
|
"""
|
|
tdc_gso.py - send a UDP GSO datagram
|
|
|
|
Copyright (C) 2026 Xingquan Liu <b1n@b1n.io>
|
|
"""
|
|
|
|
import argparse
|
|
import socket
|
|
import struct
|
|
import sys
|
|
|
|
UDP_MAX_SEGMENTS = 1 << 7
|
|
|
|
|
|
parser = argparse.ArgumentParser(description="UDP GSO datagram sender")
|
|
parser.add_argument("src", help="source IPv4 address")
|
|
parser.add_argument("dst", help="destination IPv4 address")
|
|
parser.add_argument("port", type=int, help="destination UDP port")
|
|
parser.add_argument("gso_size", type=int, help="UDP GSO segment payload size")
|
|
parser.add_argument("payload_len", type=int, help="total UDP payload length")
|
|
args = parser.parse_args()
|
|
|
|
if args.gso_size <= 0 or args.gso_size > 0xFFFF:
|
|
parser.error("gso_size must fit in an unsigned 16-bit integer")
|
|
if args.payload_len <= args.gso_size:
|
|
parser.error("payload_len must be larger than gso_size")
|
|
if args.payload_len > args.gso_size * UDP_MAX_SEGMENTS:
|
|
parser.error("payload_len exceeds UDP_MAX_SEGMENTS")
|
|
|
|
SOL_UDP = getattr(socket, "SOL_UDP", socket.IPPROTO_UDP)
|
|
UDP_SEGMENT = getattr(socket, "UDP_SEGMENT", 103)
|
|
|
|
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
|
sock.bind((args.src, 0))
|
|
|
|
payload = b"b" * args.payload_len
|
|
cmsg = [(SOL_UDP, UDP_SEGMENT, struct.pack("=H", args.gso_size))]
|
|
|
|
sent = sock.sendmsg([payload], cmsg, 0, (args.dst, args.port))
|
|
sys.exit(sent != len(payload))
|