Files
linux/tools/testing/selftests/tc-testing/tc-tests/qdiscs/dualpi2.json
Xingquan Liu 54704b32b2 selftests/tc-testing: Add DualPI2 GSO backlog accounting test
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>
2026-06-21 15:16:03 -07:00

299 lines
9.0 KiB
JSON

[
{
"id": "a4c7",
"name": "Create DualPI2 with default setting",
"category": [
"qdisc",
"dualpi2"
],
"plugins": {
"requires": "nsPlugin"
},
"setup": [
],
"cmdUnderTest": "$TC qdisc add dev $DUMMY handle 1: root dualpi2",
"expExitCode": "0",
"verifyCmd": "$TC qdisc show dev $DUMMY",
"matchPattern": "qdisc dualpi2 1: root refcnt [0-9]+ limit 10000p.* step_thresh 1ms min_qlen_step 0p coupling_factor 2 drop_on_overload drop_dequeue classic_protection 10% l4s_ect split_gso",
"matchCount": "1",
"teardown": [
"$TC qdisc del dev $DUMMY handle 1: root"
]
},
{
"id": "1ea4",
"name": "Create DualPI2 with memlimit",
"category": [
"qdisc",
"dualpi2"
],
"plugins": {
"requires": "nsPlugin"
},
"setup": [
],
"cmdUnderTest": "$TC qdisc add dev $DUMMY handle 1: root dualpi2 memlimit 20000000",
"expExitCode": "0",
"verifyCmd": "$TC qdisc show dev $DUMMY",
"matchPattern": "qdisc dualpi2 1: root refcnt [0-9]+ limit 10000p.* memlimit 20000000B",
"matchCount": "1",
"teardown": [
"$TC qdisc del dev $DUMMY handle 1: root"
]
},
{
"id": "2130",
"name": "Create DualPI2 with typical_rtt and max_rtt",
"category": [
"qdisc",
"dualpi2"
],
"plugins": {
"requires": "nsPlugin"
},
"setup": [
],
"cmdUnderTest": "$TC qdisc add dev $DUMMY handle 1: root dualpi2 typical_rtt 20ms max_rtt 200ms",
"expExitCode": "0",
"verifyCmd": "$TC qdisc show dev $DUMMY",
"matchPattern": "qdisc dualpi2 1: root refcnt [0-9]+ limit 10000p.* target 20ms tupdate 20ms alpha 0.042969 beta 1.496094",
"matchCount": "1",
"teardown": [
"$TC qdisc del dev $DUMMY handle 1: root"
]
},
{
"id": "90c1",
"name": "Create DualPI2 with max_rtt",
"category": [
"qdisc",
"dualpi2"
],
"plugins": {
"requires": "nsPlugin"
},
"setup": [
],
"cmdUnderTest": "$TC qdisc add dev $DUMMY handle 1: root dualpi2 max_rtt 300ms",
"expExitCode": "0",
"verifyCmd": "$TC qdisc show dev $DUMMY",
"matchPattern": "qdisc dualpi2 1: root refcnt [0-9]+ limit 10000p.* target 50ms tupdate 50ms alpha 0.050781 beta 0.996094",
"matchCount": "1",
"teardown": [
"$TC qdisc del dev $DUMMY handle 1: root"
]
},
{
"id": "7b3c",
"name": "Create DualPI2 with any_ect option",
"category": [
"qdisc",
"dualpi2"
],
"plugins": {
"requires": "nsPlugin"
},
"setup": [
],
"cmdUnderTest": "$TC qdisc add dev $DUMMY handle 1: root dualpi2 any_ect",
"expExitCode": "0",
"verifyCmd": "$TC qdisc show dev $DUMMY",
"matchPattern": "qdisc dualpi2 1: root refcnt [0-9]+ limit 10000p .* any_ect",
"matchCount": "1",
"teardown": [
"$TC qdisc del dev $DUMMY handle 1: root"
]
},
{
"id": "49a3",
"name": "Create DualPI2 with overflow option",
"category": [
"qdisc",
"dualpi2"
],
"plugins": {
"requires": "nsPlugin"
},
"setup": [
],
"cmdUnderTest": "$TC qdisc add dev $DUMMY handle 1: root dualpi2 overflow",
"expExitCode": "0",
"verifyCmd": "$TC qdisc show dev $DUMMY",
"matchPattern": "qdisc dualpi2 1: root refcnt [0-9]+ limit 10000p.* overflow",
"matchCount": "1",
"teardown": [
"$TC qdisc del dev $DUMMY handle 1: root"
]
},
{
"id": "d0a1",
"name": "Create DualPI2 with drop_enqueue option",
"category": [
"qdisc",
"dualpi2"
],
"plugins": {
"requires": "nsPlugin"
},
"setup": [
],
"cmdUnderTest": "$TC qdisc add dev $DUMMY handle 1: root dualpi2 drop_enqueue",
"expExitCode": "0",
"verifyCmd": "$TC qdisc show dev $DUMMY",
"matchPattern": "qdisc dualpi2 1: root refcnt [0-9]+ limit 10000p .* drop_enqueue",
"matchCount": "1",
"teardown": [
"$TC qdisc del dev $DUMMY handle 1: root"
]
},
{
"id": "f051",
"name": "Create DualPI2 with no_split_gso option",
"category": [
"qdisc",
"dualpi2"
],
"plugins": {
"requires": "nsPlugin"
},
"setup": [
],
"cmdUnderTest": "$TC qdisc add dev $DUMMY handle 1: root dualpi2 no_split_gso",
"expExitCode": "0",
"verifyCmd": "$TC qdisc show dev $DUMMY",
"matchPattern": "qdisc dualpi2 1: root refcnt [0-9]+ limit 10000p .* no_split_gso",
"matchCount": "1",
"teardown": [
"$TC qdisc del dev $DUMMY handle 1: root"
]
},
{
"id": "456b",
"name": "Create DualPI2 with packet step_thresh",
"category": [
"qdisc",
"dualpi2"
],
"plugins": {
"requires": "nsPlugin"
},
"setup": [
],
"cmdUnderTest": "$TC qdisc add dev $DUMMY handle 1: root dualpi2 step_thresh 3p",
"expExitCode": "0",
"verifyCmd": "$TC qdisc show dev $DUMMY",
"matchPattern": "qdisc dualpi2 1: root refcnt [0-9]+ limit 10000p .* step_thresh 3p",
"matchCount": "1",
"teardown": [
"$TC qdisc del dev $DUMMY handle 1: root"
]
},
{
"id": "610c",
"name": "Create DualPI2 with packet min_qlen_step",
"category": [
"qdisc",
"dualpi2"
],
"plugins": {
"requires": "nsPlugin"
},
"setup": [
],
"cmdUnderTest": "$TC qdisc add dev $DUMMY handle 1: root dualpi2 min_qlen_step 1",
"expExitCode": "0",
"verifyCmd": "$TC qdisc show dev $DUMMY",
"matchPattern": "qdisc dualpi2 1: root refcnt [0-9]+ limit 10000p .* min_qlen_step 1p",
"matchCount": "1",
"teardown": [
"$TC qdisc del dev $DUMMY handle 1: root"
]
},
{
"id": "b4fa",
"name": "Create DualPI2 with packet coupling_factor",
"category": [
"qdisc",
"dualpi2"
],
"plugins": {
"requires": "nsPlugin"
},
"setup": [
],
"cmdUnderTest": "$TC qdisc add dev $DUMMY handle 1: root dualpi2 coupling_factor 1",
"expExitCode": "0",
"verifyCmd": "$TC qdisc show dev $DUMMY",
"matchPattern": "qdisc dualpi2 1: root refcnt [0-9]+ limit 10000p .* coupling_factor 1",
"matchCount": "1",
"teardown": [
"$TC qdisc del dev $DUMMY handle 1: root"
]
},
{
"id": "37f1",
"name": "Create DualPI2 with packet classic_protection",
"category": [
"qdisc",
"dualpi2"
],
"plugins": {
"requires": "nsPlugin"
},
"setup": [
],
"cmdUnderTest": "$TC qdisc add dev $DUMMY handle 1: root dualpi2 classic_protection 0",
"expExitCode": "0",
"verifyCmd": "$TC qdisc show dev $DUMMY",
"matchPattern": "qdisc dualpi2 1: root refcnt [0-9]+ limit 10000p .* classic_protection 0%",
"matchCount": "1",
"teardown": [
"$TC qdisc del dev $DUMMY handle 1: root"
]
},
{
"id": "891f",
"name": "Verify DualPI2 GSO backlog accounting with QFQ parent",
"category": [
"qdisc",
"dualpi2",
"qfq",
"gso"
],
"plugins": {
"requires": "nsPlugin"
},
"setup": [
"$IP link set dev $DUMMY up || true",
"$IP addr add 10.10.10.10/24 dev $DUMMY || true",
"$TC qdisc add dev $DUMMY root handle 1: qfq",
"$TC class add dev $DUMMY parent 1: classid 1:1 qfq weight 1 maxpkt 4096",
"$TC qdisc add dev $DUMMY parent 1:1 handle 2: dualpi2",
"$TC filter add dev $DUMMY parent 1: matchall classid 1:1"
],
"cmdUnderTest": "./tdc_gso.py 10.10.10.10 10.10.10.1 9000 1200 2400",
"expExitCode": "0",
"verifyCmd": "$TC -j -s qdisc ls dev $DUMMY",
"matchJSON": [
{
"kind": "qfq",
"handle": "1:",
"packets": 2,
"backlog": 0,
"qlen": 0
},
{
"kind": "dualpi2",
"handle": "2:",
"packets": 2,
"backlog": 0,
"qlen": 0
}
],
"teardown": [
"$TC qdisc del dev $DUMMY root",
"$IP addr del 10.10.10.10/24 dev $DUMMY || true"
]
}
]