MQPRIO(8)
๐ NAME ๐
okay so MQPRIO is the Multiqueue Priority Qdisc (Offloaded Hardware QOS) and it's giving main character energy ๐
โจ SYNOPSIS โจ
tc qdisc ... dev dev ( parent classid | root) [ handle major: ] mqprio
[ num_tc tcs ] [ map P0 P1 P2... ] [ queues count1@offset1
count2@offset2 ... ]
[ hw 1|0 ] [ mode dcb|channel ] [ shaper dcb|bw_rlimit ]
[ min_rate min_rate1 min_rate2 ... ] [ max_rate max_rate1
max_rate2 ... ]
[ fp FP0 FP1 FP2 ... ]
๐ฆ DESCRIPTION ๐ฆ
bestie, the MQPRIO qdisc is a simple queuing discipline, and I'm obsessed. It lets you map traffic flows onto hardware queue ranges using priorities, plus a configurable priority-to-traffic-class map ๐ง. A traffic class here is a set of contiguous qdisc classes that map 1:1 onto a set of hardware exposed queues.
By default the qdisc gives you a pfifo qdisc (a packet limited first in, first out queue) for every TX queue the lower layer device exposes. You can add other queuing disciplines later if you want. Packets get enqueued using the map parameter and get hashed across the queues described by the offset and count. Honestly the driver usually configures all of this for you so it matches the hardware QOS structures ๐
.
Channel mode is the full-send option ๐ฅ. It offloads the mqprio options, the traffic classes, the queue configurations and the QOS attributes to the hardware. Hardware that supports it can steer traffic flows into the traffic classes this qdisc provides. Hardware based QOS gets configured with the shaper parameter, and bw_rlimit lets you set minimum and maximum bandwidth rates for each traffic class. You can also add more qdiscs to the classes of MQPRIO if you want something extra complex ๐.
๐ธ ALGORITHM ๐ธ
When you create it with tc qdisc add, eight traffic classes get made automatically. Priorities 0..7 map to traffic classes 0..7, and any priority greater than 7 goes to traffic class 0. This needs base driver support, so the creation will fail on devices that don't support hardware QOS schemes ๐.
You can override these defaults with the qdisc parameters. If you pass the hw 0 flag, software runs without hardware coordination ๐ซถ.
If hardware coordination is in use and you hand it arguments the hardware can't support, you'll get an error. For most people the hardware defaults work reasonably well, so don't stress ๐.
Here's a specific example: loads of Ethernet cards support the 802.1Q link strict priority transmission selection algorithm (TSA). MQPRIO-enabled hardware, paired with the classification methods below, can give you hardware offloaded support for this TSA โจ.
๐ง CLASSIFICATION ๐ง
There are multiple ways to set the SKB priority, and MQPRIO uses that priority to pick which traffic class the packet gets enqueued into. iykyk ๐.
๐ From user space
A process with sufficient privileges can encode the destination class directly with SO_PRIORITY. Check out socket(7) for the details ๐.
๐ฅ With iptables/nftables
You can make an iptables/nftables rule that matches traffic flows and sets the priority. iptables(8) ๐
๐ With net_prio cgroups
The net_prio cgroup can set the priority of all sockets belonging to an application. See the kernel and cgroup documentation for the deets ๐ฆ.
๐ QDISC PARAMETERS ๐
num_tcโ how many traffic classes you want. You can have up to 16 classes. You cannot have more classes than queues ๐ซงmapโ the priority to traffic class map. It maps priorities 0..15 to whichever traffic class you pick ๐บ๏ธqueuesโ the count and offset of the queue range for each traffic class, written ascount@offset. Queue ranges for different traffic classes cannot overlap, and each one has to be a contiguous range of queues ๐ซhwโ set to1to support hardware offload, or0to configure your user specified values in software only. The default is1๐ฅmodeโ set tochannelfor the full set of mqprio options. Usedcbif you only want to offload the TC values and use the hardware QOS defaults. This is only supported withhwset to1โจshaperโ usebw_rlimitto set bandwidth rate limits for a traffic class. Usedcbfor the hardware QOS defaults. Supported withhwset to1only ๐min_rateโ the minimum bandwidth rate limit for a traffic class. Only supported whenshaperis set tobw_rlimit๐ธmax_rateโ the maximum bandwidth rate limit for a traffic class. Only supported whenshaperis set tobw_rlimit๐ธfpโ picks whether each traffic class is express (delivers packets via the eMAC) or preemptible (delivers packets via the pMAC). This follows IEEE 802.1Q-2018 clause 6.7.2 Frame preemption ๐ฆ. It's an array with one element per traffic class, and each value isE(express) orP(preemptible).
Multiple priorities that map to the same traffic class, and multiple TXQs that map to the same traffic class, must have the same FP attributes. To read FP as a per-priority attribute, use the map argument for translation. To read FP as a per-TXQ attribute, use the queues argument for translation ๐ง .
Traffic classes are express by default. This argument is only supported with hw set to 1. Preemptible traffic classes are only accepted if the device has a MAC Merge layer that you can configure through ethtool(8) ๐ซถ.
๐ SEE ALSO ๐
๐ EXAMPLE ๐
This first one attaches priorities to 4 traffic classes (num_tc 4), then pairs those traffic classes with 4 hardware queues using mqprio, with hardware coordination (hw 1, or you can leave it out since 1 is the default value). Traffic class 0 (tc0) maps to hardware queue 0 (q0), tc1 maps to q1, tc2 maps to q2, and tc3 maps to q3 ๐.
# tc qdisc add dev eth0 root mqprio num_tc 4 map 0 0 0 0 1 1 1 1 2 2 2 2 3 3 3 3 queues 1@0 1@1 1@2 1@3 hw 1
The next one attaches priorities to 3 traffic classes (num_tc 3) and pairs them with 4 queues without hardware coordination (hw 0). Traffic class 0 (tc0) maps to hardware queue 0 (q0), tc1 maps to q1, and tc2 maps to both q2 and q3, where the queue selection between those two is kinda random ๐ฒ.
# tc qdisc add dev eth0 root mqprio num_tc 3 map 0 0 0 0 1 1 1 1 2 2 2 2 2 2 2 2 queues 1@0 1@1 2@2 hw 0
In both examples, priority values 0 to 3 (prio0-3) map to tc0, prio4-7 map to tc1, and prio8-11 map to tc2 (that's the map attribute doing its thing โจ). The last four priority values (prio12-15) get mapped differently in each example. In the first one they go to tc3, and in the second one they go to tc2 ๐. Here's how the two examples compare:
โโโโโโฌโโโโโฌโโโโโโโโ โโโโโโฌโโโโโฌโโโโโโโโโ
โPrioโ tc โ queue โ โPrioโ tc โ queue โ
โโโโโโผโโโโโผโโโโโโโโค โโโโโโผโโโโโผโโโโโโโโโค
โ 0 โ 0 โ 0 โ โ 0 โ 0 โ 0 โ
โ 1 โ 0 โ 0 โ โ 1 โ 0 โ 0 โ
โ 2 โ 0 โ 0 โ โ 2 โ 0 โ 0 โ
โ 3 โ 0 โ 0 โ โ 3 โ 0 โ 0 โ
โ 4 โ 1 โ 1 โ โ 4 โ 1 โ 1 โ
โ 5 โ 1 โ 1 โ โ 5 โ 1 โ 1 โ
โ 6 โ 1 โ 1 โ โ 6 โ 1 โ 1 โ
โ 7 โ 1 โ 1 โ โ 7 โ 1 โ 1 โ
โ 8 โ 2 โ 2 โ โ 8 โ 2 โ 2 or 3 โ
โ 9 โ 2 โ 2 โ โ 9 โ 2 โ 2 or 3 โ
โ 10 โ 2 โ 2 โ โ 10 โ 2 โ 2 or 3 โ
โ 11 โ 2 โ 2 โ โ 11 โ 2 โ 2 or 3 โ
โ 12 โ 3 โ 3 โ โ 12 โ 2 โ 2 or 3 โ
โ 13 โ 3 โ 3 โ โ 13 โ 2 โ 2 or 3 โ
โ 14 โ 3 โ 3 โ โ 14 โ 2 โ 2 or 3 โ
โ 15 โ 3 โ 3 โ โ 15 โ 2 โ 2 or 3 โ
โโโโโโดโโโโโดโโโโโโโโ โโโโโโดโโโโโดโโโโโโโโโ
example1 example2
Here's another queue mapping for you. This one has 5 traffic classes and 8 hardware queues ๐ซง.
# tc qdisc add dev eth0 root mqprio num_tc 5 map 0 0 0 1 1 1 1 2 2 3 3 4 4 4 4 4 queues 1@0 2@1 1@3 1@4 3@5
And here's how the values map out for that one:
โโโโโโโโโ
tc0โโโโโคQueue 0โโโโโโ1@0
โโโโโโโโโค
โโโคQueue 1โโโโโโ2@1
tc1โโโค โโโโโโโโโค
โโโคQueue 2โ
โโโโโโโโโค
tc2โโโโโคQueue 3โโโโโโ1@3
โโโโโโโโโค
tc3โโโโโคQueue 4โโโโโโ1@4
โโโโโโโโโค
โโโคQueue 5โโโโโโ3@5
โ โโโโโโโโโค
tc4โโโผโโคQueue 6โ
โ โโโโโโโโโค
โโโคQueue 7โ
โโโโโโโโโ
๐ AUTHORS ๐
John Fastabend, <john.r.fastabend@intel.com>
that's a wrap, bestie ๐ซถ๐ this MQPRIO(8) page came from iproute2, dated 24 Sept 2013, and I'm literally obsessed with it ๐ฆโจ
๐ฆ where this page comes from
- alpine 3.22: iproute2-doc 6.15.0-r0 ยท GPL-2.0-or-later
- 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
- debian trixie: iproute2 6.15.0-1 ยท GPL-2.0-only
- fedora 43: iproute-tc 6.14.0-2.fc43 ยท 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
- opensuse-leap 16.0: iproute2 6.12-160000.4.1 ยท GPL-2.0-only
- opensuse-leap 16.0: iproute2 6.12-160000.4.1 ยท GPL-2.0-only
- opensuse-leap 16.0: iproute2 6.12-160000.4.1 ยท GPL-2.0-only
- opensuse-leap 16.0: iproute2 6.12-160000.4.1 ยท GPL-2.0-only
- ubuntu questing: iproute2 6.16.0-1ubuntu2
- ubuntu questing: iproute2 6.16.0-1ubuntu2.1 ยท GPL-2.0-only
- ubuntu questing: iproute2 6.16.0-1ubuntu2.2
- 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 anthropic/claude-haiku-5.5 on : a language model's rewrite of the original, under its terms