DUALPI2(8)
๐ DUALPI2 ๐
okay bestie, so this one is dualpi2 from section 8 of the Linux manual pages โ the big-kid sysadmin section โ and it's literally one of the coolest queue disciplines in the whole tc lineup. buckle up. ๐
โจ NAME โจ
DUALPI2 โ Dual Queue Proportional Integral Controller AQM โ Improved with a square ๐
๐ธ SYNOPSIS ๐ธ
tc qdisc ... dualpi2
[ limit PACKETS ]
[ memlimit BYTES ]
[ coupling_factor NUMBER ]
[ step_thresh TIME|PACKETS ]
[ min_qlen_step PACKETS ]
[ drop_on_overload | overflow ]
[ drop_enqueue | drop_dequeue ]
[ l4s_ect | any_ect ]
[ classic_protection PERCENTAGE ]
[ max_rtt TIME [ typical_rtt TIME ]]
[ target TIME ]
[ tupdate TIME ]
[ alpha float ]
[ beta float ]
[ split_gso | no_split_gso ]
๐ฆ DESCRIPTION ๐ฆ
So, DUALPI2 AQM is a combo meal: it's the DUALQ Coupled-AQM glued onto a PI2 base-AQM. And PI2 itself? It's both an extension and a simplification of the PIE AQM (iykyk). PI2 makes a whole bunch of PIE heuristics just... unnecessary, while still being able to control scalable congestion controls like TCP-Prague. And with PI2, both Reno/Cubic can run in parallel with Prague, maintaining window fairness. ๐ซถ
DUALQ is what gives you the latency separation between the low-latency Prague flows and the Reno/Cubic flows that need a bigger queue.
The main design goals, no cap:
- L4S โ Low Loss, Low Latency and Scalable congestion control support โจ
- DualQ option to separate the L4S traffic in a low latency queue (L-queue), without harming the remaining traffic scheduled in the classic queue (C-queue), thanks to congestion-coupling
- Configurable overload strategies
- Use of sojourn time to reliably estimate queue delay
- Simple implementation
- Guaranteed stability and fast responsiveness
The detailed PI2 parameters โ alpha, beta, and tupdate โ of DualPI2 are genuinely hard to get right, and they typically give bad results if you just try them or guess at them. ๐ญ These parameters need to be calculated into a coherent set with a typical objective in mind. DualPI2 ships with a set of default parameters usable for the general Internet, where the max RTT is around 100ms and the typical RTT is around 15ms.
It is highly recommended to use max_rtt and typical_rtt (or target) helper parameters if your deployment deviates from those objectives (e.g. in a data center). These helpers are used to provide the theoretically optimal PI2 parameters (alpha, beta, and tupdate) for those objectives, and they can be used as a basis for further finetuning, experimentation, and testing if desired. ๐
๐ ALGORITHM ๐
DUALPI2 is designed to provide low loss and low latency to L4S traffic, without harming classic traffic. Every update interval, a new internal base probability is calculated based on queue delay. The base probability gets updated with a delta based on the difference between the current queue delay and the target delay, plus the queue growth compared with the queuing delay during the previous tupdate interval.
The integral gain factor alpha is used to correct slowly enough any persistent standing queue error to the user-specified target delay, while the proportional gain factor beta is used to quickly compensate for queue changes (growth or shrink).
The updated base probability is used as input to decide to mark and drop packets. DUALPI2 scales the calculated probability for each of the two queues accordingly. For the L-queue, the probability is multiplied by a coupling_factor, while for the C-queue, it is squared to compensate the squareroot rate equation of Reno/Cubic. The ECT identifier (l4s_ect|any_ect) is what classifies traffic into the respective queues.
If DUALPI2 AQM has detected overload (when excessive non-responsive traffic is sent), it can signal congestion solely using drop, irrespective of the ECN field โ or alternatively limit the drop probability and let the queue grow and eventually overflow (like tail-drop). ๐
Additional details can be found in the RFC cited below.
๐ PARAMETERS ๐
limitPACKETS โ Limit the number of packets that can be enqueued. Incoming packets will be dropped once this limit is reached. This limit is common for the L-queue and C-queue. Defaults to10000packets. That's about125msdelay on a1Gbpslink, bestie. ๐memlimitBYTES โ Limit the total amount of memory that can be used. Incoming packets will be dropped once this memlimit is reached. This memlimit is common for the L-queue and C-queue. Defaults to10000* interface MTU bytes.coupling_factorNUMBER โ Set the coupling rate factor between Classic and L4S. Defaults to2.l4s_ect|any_ectโ Configures the ECT classifier. Packets whose ECT codepoint matches this are sent to the L-queue, where they receive a scalable marking. Defaults tol4s_ect, i.e. the L4S identifier ECT(1). Setting this toany_ectcauses all packets whose ECN field is not zero to be sent to the L-queue. This makes it backward compatible with, e.g., DCTCP.
โ ๏ธ Note: DCTCP should only be used for intra-DC traffic with very low RTTs and AQM delay targets bigger than those RTTs, separated from Internet traffic (also if Prague compliant CC), as it does not support all Prague requirements that make sure that a congestion control can work well with the range of RTTs on the Internet. ๐
step_threshTIME | PACKETS โ Set the step threshold for the L-queue. This will cause packets with a sojourn time exceeding the threshold to always be marked. This value can either be specified using time units (i.e.us,ms,s), or in packets (p,pkt,packet(s)). A value without units is assumed to be in time (us). If defining the step in packets, be sure to disable GRO on the ingress interfaces. Defaults to1ms. ๐min_qlen_stepPACKETS โ Incoming packets enqueued to the L-queue may apply the step threshold when the queue length of the L-queue exceeds this value. Default to0packets. This means that every enqueued packet to the L-queue with a sojourn time exceeding the step threshold will be marked. โจdrop_on_overload|overflowโ Control the overload strategy.drop_on_overloadpreserves the delay in the L-queue by dropping in both queues on overload.overflowsacrifices delay to avoid losses, eventually resulting in a taildrop behavior once the limit is reached. Defaults todrop_on_overload.drop_enqueue|drop_dequeueโ Decide when packets are PI-based dropped or marked. Thestep_threshbased L4S marking is always at dequeue. Defaults todrop_dequeue.classic_protectionPERCENTAGE โ Protects the C-queue from unresponsive traffic in the L-queue. This bounds the maximal scheduling delay in the C-queue to be(100 - PERCENTAGE)times greater than the one in the L-queue. Defaults to10. ๐ซถtypical_rttTIME andmax_rttTIME โ Specify the maximum round trip time (RTT) and/or the typical RTT of the traffic that will be controlled by DUALPI2. These values are specified using time units (i.e.us,ms,s). A value without units is assumed to be inus.
If either max_rtt or typical_rtt is not specified, the missing value will be computed from the following relationship:
max_rtt = typical_rtt * 6
If any of these parameters is given, it will be used to automatically compute suitable values for alpha, beta, target, and tupdate, according to the relationship from appendix A.1 in the IETF RFC cited below, to achieve a stable control. Consequently, those derived values will override their eventual user-provided ones. ๐ณ
The default range of operation for the qdisc uses max_rtt = 100ms and typical_rtt = 15ms, which is suited to controlling Internet traffic.
targetTIME โ Set the expected queue delay. Defaults to15 ms. A value without units is assumed to be inus.tupdateTIME โ Set the frequency at which the system drop probability is calculated. Defaults to16 ms. A value without units is assumed to be in microseconds. This should be less than one-third of the maximum RTT supported.alphafloat andbetafloat โ Setalphaandbeta, the integral and proportional gain factors in Hz for the PI controller. These can be calculated based on control theory. Defaults are0.16and3.2Hz, which provide stable control for RTT's up to100mswithtupdateof16ms. Be aware, unlike with PIE, these are the real unscaled gain factors. If not provided, they will be automatically derived fromtypical_rttandmax_rtt, if one of them or both are provided. ๐split_gso|no_split_gsoโ Decide how to handle aggregated packets. Either treat the aggregate as a single packet (thus all share fate with respect to marks and drops) withno_split_gso, trading some tail latency for CPU usage โ or treat each packet individually (i.e. split them) withsplit_gsoto enable fine-grained marking/dropping of packets to control queueing latencies. Defaults tosplit_gso. ๐
๐ EXAMPLES ๐
Setting DUALPI2 for the Internet with default parameters:
# sudo tc qdisc add dev eth0 root dualpi2
Setting DUALPI2 for datacenter with legacy DCTCP using ECT(0):
# sudo tc qdisc add dev eth0 root dualpi2 any_ect
๐ง FILTERS ๐ง
This qdisc can be used in conjunction with tc-filters. More precisely, it will honor filters "stealing packets", as well as accept other classification schemes. โจ
Packets whose priority/classid are set to
1will be enqueued in the L-queue, alongside L4S traffic, and thus subject to the increased marking probability (or drops if they are marked not-ECT).
Packets whose priority/classid are set to
2will also be enqueued in the L-queue, but will never be dropped if they are not-ECT (unless the qdisc is full and thus resorts to taildrop).
Finally, all the other classid/priority map to the C-queue. ๐
๐ SEE ALSO ๐
โญ SOURCES โญ
- IETF RFC9332: https://datatracker.ietf.org/doc/html/rfc9332
- CoNEXT '16 Proceedings of the 12th International on Conference on emerging Networking Experiments and Technologies: "PI2: A Linearized AQM for both Classic and Scalable TCP"
๐ AUTHORS ๐
DUALPI2 was implemented by Koen De Schepper, Olga Albisser, Henrik Steen, Olivier Tilmans, and Chia-Yu Chang โ who are also the authors of this man page. ๐ Please report bugs and corrections to the Linux networking development mailing list at <netdev@vger.kernel.org>.
and that's the whole thing, bestie ๐ฆ this page came out of the iproute2 crew, dated 29 Oct 2024, and honestly? iconic. go forth and configure your queues, you're doing amazing ๐ โจ
๐ฆ where this page comes from
- alpine 3.23: iproute2-doc 6.17.0-r0 ยท GPL-2.0-or-later
- alpine 3.24: iproute2-doc 7.0.0-r0 ยท GPL-2.0-or-later
- arch rolling: iproute2 7.2.0-1
- arch rolling: iproute2 7.3.0-1 ยท GPL-2.0-or-later
- centos-stream 10: iproute-tc 7.0.0-2.el10 ยท GPL-2.0-or-later
- centos-stream 9: iproute-tc 6.17.0-3.el9 ยท GPL-2.0-or-later
- fedora 44: iproute-tc 6.17.0-2.fc44 ยท GPL-2.0-or-later
- nixos 26.05: iproute2 7.0.0
- nixpkgs unstable: iproute2 7.2.0
- ubuntu resolute: iproute2 6.19.0-1ubuntu1 ยท GPL-2.0-only
- ubuntu resolute: iproute2 6.19.0-1ubuntu1.1 ยท GPL-2.0-only
- ubuntu stonking: iproute2 7.2.0-1ubuntu1 ยท GPL-2.0-only
- ๐ girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms