Home / Alt manpages / tc-mqprio(8)

  • tc-mqprio(8)
  • Admin command
  • linux

Configure tc-mqprio Queues Without Losing the Rollback

tc-mqprio maps socket priorities onto hardware transmit queues, so latency-sensitive traffic can skip the queue behind a bulk transfer. You'll create the queuing discipline, map priorities to traffic classes and queue ranges, inspect the result, and remove it again. The examples use software coordination first, so they don't silently depend on a particular network card.

Allow 15 to 20 minutes. You need the iproute2 package, an interface with enough transmit queues for the example, and root privileges for changes. This guide was checked with tc from iproute2 6.1.0. The installed manual page is dated 24 September 2013, so hardware capabilities remain driver-specific even though the command syntax is stable here.

1. Record the interface before changing it

Choose the interface and inspect its current qdisc and queue information. Replace the placeholder with the real device name:

IFACE=eno1
tc qdisc show dev "$IFACE"
ip -details link show dev "$IFACE"
ethtool -l "$IFACE"

The first command records the current root qdisc. The other two tell you whether the device exposes at least eight transmit queues. The example below uses two traffic classes, each covering four queues, for a total range of queues 0 through 7. Do not copy that queue layout onto an interface with fewer queues.

Checkpoint

Save the output of tc qdisc show. If you need to undo the test, you should know what was there before it. Reading these details does not require sudo on most systems.

2. Understand the map before applying it

mqprio uses a priority-to-traffic-class map with entries for priorities 0 through 15, in that order. In this example, priorities 0 to 3 go to class 0, priorities 4 to 7 go to class 1, and the pattern repeats for priorities 8 to 15:

map 0 0 0 0 1 1 1 1 0 0 0 0 1 1 1 1

A class is not one queue: it's a group of contiguous queues. The matching queue declaration is queues 4@0 4@4: class 0 owns four queues starting at offset 0, while class 1 owns four starting at offset 4. Queue ranges must not overlap and must form a contiguous range.

The manual describes eight traffic classes and priorities 0 through 7 as the creation defaults, with priorities above 7 mapped to class 0. This example overrides those defaults with two classes and an explicit map, which is easier to review. It also uses hw 0, meaning the requested values are configured in software without hardware coordination.

3. Apply a software-only configuration

Run this as root once IFACE is set correctly. The command replaces the interface root qdisc, so existing root-qdisc behaviour changes immediately:

sudo tc qdisc replace dev "$IFACE" root handle 1: mqprio   num_tc 2   map 0 0 0 0 1 1 1 1 0 0 0 0 1 1 1 1   queues 4@0 4@4   hw 0

There's normally no success message. An error about an invalid queue count or range means the interface doesn't match the example; stop and correct the queue layout rather than guessing offsets.

Checkpoint

Inspect the live configuration:

$ sudo tc -s qdisc show dev "$IFACE"
qdisc mqprio 1: root ...

Exact statistics and formatting vary. Look for an mqprio root qdisc and the two traffic classes or their queue ranges. This shows configuration and counters; it does not prove an application is setting the priorities you expect.

4. Connect priorities to real traffic

MQPRIO classifies the packet priority already attached to each socket or packet. A process with sufficient privileges can set a socket priority with SO_PRIORITY. Firewall rules can set priority for matching flows, and the net_prio cgroup can assign priority to sockets belonging to an application.

Do not infer traffic-class use from the qdisc's mere existence. Check the application or classification rule that supplies the priority, then watch the per-qdisc counters while generating a controlled test flow:

sudo tc -s qdisc show dev "$IFACE"
sudo tc -s class show dev "$IFACE" parent 1:

If the class command reports no matching classes, use the qdisc output as the source of truth for the handle and inspect the device's supported output. Avoid changing firewall or cgroup policy as part of an initial qdisc test: that introduces a second source of failure.

5. Request hardware offload only when the driver supports it

hw 1 asks for hardware offload. In channel mode, the full MQPRIO configuration, queue layout and quality-of-service attributes are sent to the hardware. That request can fail when the driver or device cannot represent one of the values, and a failure is not evidence the software configuration was applied.

Once the software test is understood, a device-specific trial might look like this:

sudo tc qdisc replace dev "$IFACE" root handle 1: mqprio   num_tc 2   map 0 0 0 0 1 1 1 1 0 0 0 0 1 1 1 1   queues 4@0 4@4   hw 1 mode channel

This is a service-affecting change with no universal success output, and tc cannot make an unsupported adapter accept the request. The dcb mode is a narrower hardware-offload choice that lets the hardware use its own quality-of-service defaults. Both modes need hardware support plus hw 1.

Bandwidth limits use the hardware shaper syntax, for example shaper bw_rlimit min_rate 1Gbit 100Mbit max_rate 10Gbit 1Gbit. Check the driver's rate units and limits before using this. A rate-limited class deliberately changes throughput, so do not add it to a production interface as a harmless verification step.

6. Remove the test configuration

Warning

Deleting the root qdisc is disruptive and may restore a device default rather than the exact qdisc you recorded. Stop any controlled traffic first, then remove the MQPRIO qdisc:

sudo tc qdisc del dev "$IFACE" root
tc qdisc show dev "$IFACE"

If you need the previous configuration, reapply the exact command from your change record instead of assuming deletion recreates it. If the interface is managed by NetworkManager, systemd-networkd or another network service, its next reload may also replace a manually applied qdisc. Keep the rollback command and service configuration under the same change record.

Common traps

  • Too few queues: queues 4@0 4@4 needs eight queues. Inspect the device first.
  • Overlapping ranges: each class needs its own contiguous range. Offsets are not traffic-class numbers.
  • Wrong map length: map describes priorities 0 through 15, not just the priorities you currently use.
  • Assuming offload: hw 1 requests coordination with hardware; it does not guarantee the driver can implement the request.
  • Checking the wrong state: tc -s reports qdisc statistics, not the source of an application's socket priority.

Done means

  • Baseline recorded. The interface and its existing root qdisc were recorded.
  • Map is valid. It has 16 entries and the queue ranges are contiguous, non-overlapping and supported by the device.
  • Configuration confirmed. tc -s qdisc show confirms the intended MQPRIO configuration.
  • Hardware mode earned, not assumed. It was attempted only after software behaviour was understood and driver support was checked.
  • Rollback ready. The original configuration or a tested rollback command is available before production use.