Skip to content

QoS: service levels, virtual lanes, SL2VL and VL arbitration

S2·E4The printed QoS policy and the storage team that starves anyway · Co-op data hall, a glass-walled room off the hot aisle, two days before acceptance

S2·E4Analyze~30 minsources checked todaylab mutates hardwareverified against QoS_management_in_OpenSM.txt (linux-rdma master) re-fetched 2026-09-07 (hard-coded qos_ca_* and qos_swe_* defaults, qos-setup parsed and ignored, 64-byte credits, high_limit semantics); UFM Subnet Manager Default Properties 6.24.1 re-fetched 2026-09-07 (qos TRUE, max_op_vls 2 with the fabric-flap note)

Builds on: Bringing up OpenSM

Before you read: what do you already know?

3 quick questions. Wrong answers are fine and expected; trying first makes the lesson stick.

After this lesson you can

  • Trace a service level through SL2VL and the VL arbitration tables and compute the bytes it gets per arbitration round.
  • Analyse an eight-class QoS design against max_op_vls and predict which classes collapse onto the same lane.
  • Distinguish what the QoS policy file configures from what only the opensm options file configures.
  • Verify a programmed QoS design with smpquery ibdiagnet and per-SL counters rather than from the policy file.

Episode 4 — The printed QoS policy and the storage team that starves anyway

The situation · Co-op data hall, a glass-walled room off the hot aisle, two days before acceptance

The storage group says their reads collapse every time the training job ramps. The network lead says QoS is configured and slides the printed policy file across the table to prove it; the expansion PO is in the same folder, and procurement has stopped pretending not to look at it. Then she says the thing she says once a quarter: show me the counter, not the printout.

Service levels exist because one physical link has to carry classes that must not starve each other. InfiniBand marks a packet with a service level and separates flows into virtual lanes with their own buffers and credits - up to 16 VLs, 16 SLs, and VL15 reserved exclusively for subnet management datagrams.[4] The subnet manager programs which SL lands on which lane, and the arbitration tables decide how many bytes each lane gets per round. Without that separation, a class gets whatever is left over.

You read their file in the order that finds the fault rather than the order it was written. Their SL2VL design sits in the qos-setup section of the policy file - the one place a mapping can be written where it is never applied, because SL2VL and VL arbitration belong in the OpenSM options file.[1] Two questions come before that even matters: is QoS enabled at all, given upstream ships it disabled and UFM ships it on, and what is max_op_vls.[2][3]

A QoS design you cannot read back out of the fabric is a drawing, not a configuration.

Segment 1 follows one packet from service level to lane.

1From service level to lane to bandwidth

The mechanism is three steps and each one is a table someone has to program. “Each port has its own set of buffers. The buffering is channeled through virtual lanes (VL) where each VL has its own flow control. There may be up to 16 VLs.”[4] “The actual VL that a packet uses is configured by the SM in the switch/channel adapter tables and is determined based on the Service Level (SL) specified in every packet. There are 16 possible SLs.”[4] And one lane is spoken for: “All ports must support VL15 which is reserved exclusively for subnet management datagrams.”[4]

That reservation has a consequence inside the configuration language. In OpenSM’s SL2VL template, “Note that VL15 used here means drop this SL.”[1] So the value 15 in a mapping table is not lane 15 — it is a discard, and it produces exactly the symptom customers describe as “the fabric is up and this one class of traffic disappears”.

Bandwidth comes from the two VL arbitration tables. Entries are VL and weight pairs, where a weight is “a VL number (values from 0-14), and a weighting value (values 0-255), indicating the number of 64 byte units (credits) which may be transmitted from that VL when its turn in the arbitration occurs”, with weight 0 skipping the entry.[1] The unit conversion is the part to memorise: “for 4KB MTU a single packet will require 64 credits, so … the weighting values for each VL should be multiples of 64.”[1] A weight of 4 is 256 bytes — a fraction of one packet.

The high and low tables are separated by a limit. “the number of bytes that can be sent is high_limit times 4K bytes. A high_limit value of 255 indicates that the byte limit is unbounded. Note: if the 255 value is used, the low priority VLs may be starved. A value of 0 indicates that only a single packet from the high-priority table may be sent before an opportunity is given to the low-priority table.”[1] The two IBA anchors the documentation itself gives are SL2VL mapping at IBA 7.6.6 and VL arbitration at IBA 7.6.9 — useful when a customer’s own spec extract needs matching to what OpenSM writes.[1][2]

2Where the tables live, and the section that is thrown away

QoS is off by default upstream: -Q/--qos — “This option enables QoS setup. It is disabled by default.”[2] UFM ships qos = TRUE, enabled by “setting the qos flag to TRUE in the /opt/ufm/files/conf/opensm/opensm.conf file”.[3][10] So the very first question about any customer’s QoS is not what they configured, it is whether QoS is on at all and who decided.

The tables are configured in the SM’s options file through four parameter sets: qos_ca_* for channel adapters, qos_swe_* for switch external ports, qos_sw0_* for switch port 0 and qos_rtr_* for routers.[1] The shipped defaults, verbatim:[1]

qos_ca_max_vls 15
qos_ca_high_limit 0
qos_ca_vlarb_high 0:4,1:0,2:0,3:0,4:0,5:0,6:0,7:0,8:0,9:0,10:0,11:0,12:0,13:0,14:0
qos_ca_vlarb_low  0:0,1:4,2:4,3:4,4:4,5:4,6:4,7:4,8:4,9:4,10:4,11:4,12:4,13:4,14:4
qos_ca_sl2vl      0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,7
qos_swe_max_vls 15
qos_swe_high_limit 0
qos_swe_vlarb_high 0:4,1:0,2:0,3:0,4:0,5:0,6:0,7:0,8:0,9:0,10:0,11:0,12:0,13:0,14:0
qos_swe_vlarb_low  0:0,1:4,2:4,3:4,4:4,5:4,6:4,7:4,8:4,9:4,10:4,11:4,12:4,13:4,14:4
qos_swe_sl2vl      0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,7

Read the SL2VL line: identity for SL0 through SL14, and SL15 mapped to VL7 rather than 15 — because 15 would mean drop.[1] Read the weights: 4 credits is 256 bytes, well under one 4 K packet, so the shipped arbitration is a placeholder rather than a design.[1]

Now the trap that wastes whole engagements. The QoS policy file has four sections — port-groups, qos-setup, qos-levels, qos-match-rules — and the second one does nothing: “This section describes how to set up SL2VL and VL Arbitration tables on various nodes in the fabric. However, this is not supported in OpenSM currently - the section is parsed and ignored. SL2VL and VLArb tables should be configured in the OpenSM options file”.[1] A customer whose SL2VL design lives in qos-policy.conf has a design that has never once been applied, and nothing in the logs says so.

What the policy file does do is assign SLs to traffic. A QoS level carries an SL plus optional mtu-limit, rate-limit, pkey and packet-life, and “One QoS level that is mandatory to define is a DEFAULT QoS level.”[1] The shortest legal file is therefore:[1]

qos-levels
    qos-level
        name: DEFAULT
        sl: 0
    end-qos-level
end-qos-levels

Match rules are ordered — “Rules are scanned in order of appearance in the QoS policy file such as the first match takes precedence” — matching on source port group, destination port group, PKey, QoS class or Service ID, and the policy is re-parsed “during fabric initialization and at every heavy sweep”.[1] The ordering gotcha worth writing on the change ticket: put the SRP or target-port-GUID rule last, because any ULP query may carry a target port GUID and would otherwise be misclassified as SRP.[1]

max_op_vls = 15
SL (packet)qos_ca_sl2vlVL lane (own buffers + flow control)SL 00SL 11SL 22SL 33SL 44SL 55SL 66SL 77SL 88SL 99SL 1010SL 1111SL 1212SL 1313SL 1414SL 157VL0SL 0 · hi 4 / lo 0VL1SL 1 · hi 0 / lo 4VL2SL 2 · hi 0 / lo 4VL3SL 3 · hi 0 / lo 4VL4SL 4 · hi 0 / lo 4VL5SL 5 · hi 0 / lo 4VL6SL 6 · hi 0 / lo 4VL7SL 7,15 · hi 0 / lo 4VL8SL 8 · hi 0 / lo 4VL9SL 9 · hi 0 / lo 4VL10SL 10 · hi 0 / lo 4VL11SL 11 · hi 0 / lo 4VL12SL 12 · hi 0 / lo 4VL13SL 13 · hi 0 / lo 4VL14SL 14 · hi 0 / lo 4VL15SMPs only — mapping here = drop
Set the target VL for SL 3:
SL2VL · IBA 7.6.6

SL 3VL 3

own laneAR enabled for this SL

Arbitration on VL 3: high weight 0 (0 bytes ≈ 0.00 × 4 K packets), low weight 4 (256 bytes). This lane takes 7% of a full low-priority round.

A VLArb entry is a VL number (0-14) and a weight (0-255) "indicating the number of 64 byte units (credits) which may be transmitted from that VL"; weight 0 skips the entry. Credit sizing: "for 4KB MTU a single packet will require 64 credits, so … the weighting values for each VL should be multiples of 64".

Read it back on the box: smpquery SL2VL <lid> <port> and smpquery VLArb <lid> <port>; fabric-wide it is ibdiagnet2.slvl. Watch it move with perfquery -X <lid> 1 / -S under ib_write_bw -S 3.

Adaptive routing must use the same tables

16 of 16 SLs are in the AR mask (default 0xFFFF = all). ar_sl_mask default 0xFFFF — "16-bit bitmask indicating which SLs should be configured for AR".

pfrn_sl 4VL 4. pfrn_sl = 4 — "SL for pFRN communication between switches. Make sure pfrn_sl is properly mapped in sl2vl qos settings."

ar_mode default 3 = "Auto mode in which adaptive routing is determined by the routing engine." shield_mode default 3 (auto). The switch-embedded SM implements none of AR, SHIELD/FRN, congestion control or SHARP.

VL arbitration tables — IBA 7.6.9, weights in 64-byte credits
VLhighlowlow bytes/roundSLs here
VL00SL0
VL1256SL1
VL2256SL2
VL3256SL3
VL4256SL4
VL5256SL5
VL6256SL6
VL7256SL7 SL15
VL8256SL8
VL9256SL9
VL10256SL10
VL11256SL11
VL12256SL12
VL13256SL13
VL14256SL14

high_limit: "the number of bytes that can be sent is high_limit times 4K bytes. A high_limit value of 255 indicates that the byte limit is unbounded… A value of 0 indicates that only a single packet from the high-priority table may be sent before an opportunity is given to the low-priority table."

Your options file right now
qos_ca_high_limit 0
qos_ca_vlarb_high 0:4,1:0,2:0,3:0,4:0,5:0,6:0,7:0,8:0,9:0,10:0,11:0,12:0,13:0,14:0
qos_ca_vlarb_low  0:0,1:4,2:4,3:4,4:4,5:4,6:4,7:4,8:4,9:4,10:4,11:4,12:4,13:4,14:4
qos_ca_sl2vl      0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,7
max_op_vls        15
OpenSM defaults, verbatim
qos_ca_max_vls 15
qos_ca_high_limit 0
qos_ca_vlarb_high 0:4,1:0,2:0,3:0,4:0,5:0,6:0,7:0,8:0,9:0,10:0,11:0,12:0,13:0,14:0
qos_ca_vlarb_low  0:0,1:4,2:4,3:4,4:4,5:4,6:4,7:4,8:4,9:4,10:4,11:4,12:4,13:4,14:4
qos_ca_sl2vl      0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,7

Four parameter sets configure these tables: qos_ca_* (CAs), qos_rtr_* (routers), qos_sw0_* (switch port 0), qos_swe_* (switch external ports). -Q / --qos "enables QoS setup. It is disabled by default." UFM ships qos = TRUE.

The qos-setup section of the QoS policy file "is not supported in OpenSM currently - the section is parsed and ignored. SL2VL and VLArb tables should be configured in the OpenSM options file".

Prove it on the fabric
  • smpquery SL2VL <lid> <port> and smpquery VLArb <lid> <port> read the programmed tables straight from the SMA.
  • saquery exposes SL2VLTableRecord (SL2VL) and VLArbitrationTableRecord (VLAR).
  • ibdiagnet --r_opt check_sl validates "all SL2VL mappings don’t route to VL15".
  • ibdiagnet2.slvl holds the SL/VL tables of the fabric switches; ibdiagnet --qos "Displays qos config sl".
  • perfquery -X/--xmtsl and -S/--rcvsl read PortXmitDataSL / PortRcvDataSL per-SL counters.
  • UFM ships max_op_vls = 2 (RW). The UFM table warns "Note, SM will flap all fabric" when it changes.

FAE angle. Check in this order: max_op_vls, then qos_*_sl2vl, then the VLArb weights. Raising max_op_vls flaps the whole fabric — it is a maintenance-window change, not a live tune. Then prove it: ibdiagnet --qos, ibdiagnet -r --r_opt check_sl, ibdiagnet2.slvl.

QoS Management in OpenSM · UFM SM defaults · ibdiagnet routing validation · RFC 4392

Start on OpenSM's shipped `qos_ca_*` tables with SL3 selected and read its effective VL and credits per round. Then drag max_op_vls down to 2 and watch an eight-class design fold onto two lanes - and map one SL to VL15 to see the drop.

3max_op_vls, and the eight-class design that becomes two

Here is the second way a careful QoS design does nothing. UFM ships max_op_vls = 2, described as the “Limit of the maximum operational VLs”, with the table’s own warning: “Note, SM will flap all fabric links to deploy the configuration upon parameter change.”[3]

Two operational lanes means every SL in a sixteen-entry SL2VL table lands on VL0 or VL1 no matter what the table says. The classes still exist as labels; they no longer exist as separate buffers or separate flow control, which is the entire point of the exercise. So an eight-class design on a stock UFM fabric behaves as a two-class design, and it does so consistently enough that customers report “QoS makes no difference” rather than “QoS is broken”.

The order of checks that follows from this is short and worth internalising: qos enabled at all, then max_op_vls, then qos_*_sl2vl, then the VLArb weights.[3][1] Reversing it means auditing tables whose lanes do not exist.

The warning attached to the parameter is equally important commercially. Raising max_op_vls flaps all fabric links, so it is a maintenance-window change on a production training cluster, not a live tune.[3] Plan it with the customer’s job scheduler, not during a bridge call.

4Verifying a QoS design against the fabric

Four read-backs, from narrowest to widest.

Per port, straight from the SMA: smpquery SL2VL <lid> <port> and smpquery VLArb <lid> <port> return the programmed tables, using the operation aliases SL2VLTable (SL2VL) and VLArbitration (VLArb).[7] This is the ground truth for one port and needs no SA.

Fabric-wide, ibdiagnet --qos “Displays qos config sl” and the SL and VL tables of switches land in ibdiagnet2.slvl; routing validation additionally dumps ibdiagnet2.vl2vl.[9][6][5] The check that matters most is ibdiagnet -r --r_opt check_sl, which validates that “all SL2VL mappings don’t route to VL15” — the direct test for the silent-drop case.[5]

Under traffic, perfquery reads per-SL data counters with -X/--xmtsl (PortXmitDataSL) and -S/--rcvsl (PortRcvDataSL), plus optional per-VL counters --vloppackets, --vlopdata and --vlxmitcounters.[8] Remember the unit trap when you quote a number: “components that represent Data (e.g. PortXmitData and PortRcvData) indicate octets divided by 4 rather than just octets.”[8]

To generate that traffic on a chosen SL, perftest takes -S/--sl with a default of 0, and both sides must be given the same options — “The SAME OPTIONS must be passed to both server and client.”[11] That gives you the closed loop: set an SL, move bytes, and watch the counter for that SL rather than the aggregate.

Trace one SL end to end and prove the design

Case: a customer wants storage traffic on its own lane so it stops competing with training collectives. They propose SL3 for storage and SL0 for everything else, and they run a UFM-managed fabric with a 4 K MTU.

  1. Establish the operating conditions before designing anything:
    grep -E '^(qos|max_op_vls|qos_ca_sl2vl|qos_ca_vlarb_high|qos_ca_vlarb_low|qos_ca_high_limit) ' /opt/ufm/files/conf/opensm/opensm.conf
    Expected on a stock UFM: qos TRUE and max_op_vls 2.[3] Stop here and tell the customer: with two operational VLs the proposal cannot separate SL3 from SL0 onto different lanes, and raising the cap flaps every link in the fabric.[3]
  2. Assume the maintenance window is agreed and max_op_vls will go to 8. Now design the SL2VL mapping. Keeping the identity mapping, SL3 lands on VL3, and SL15 must stay at 7 rather than 15 so it is not dropped:[1]
    qos_ca_sl2vl  0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,7
    qos_swe_sl2vl 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,7
  3. Size the arbitration in credits, not in adjectives. Storage should get roughly a quarter of the low-priority turns against collectives on VL0. With a 4 K MTU one packet is 64 credits, so use multiples of 64:[1]
    qos_ca_vlarb_low  0:192,3:64,1:0,2:0,4:0,5:0,6:0,7:0,8:0,9:0,10:0,11:0,12:0,13:0,14:0
    qos_swe_vlarb_low 0:192,3:64,1:0,2:0,4:0,5:0,6:0,7:0,8:0,9:0,10:0,11:0,12:0,13:0,14:0
    Read it back as bytes before agreeing to it: VL0 gets 192 credits = 12 KB = three 4 K packets per round, VL3 gets 64 credits = one packet, and the weight-0 entries are skipped entirely.[1]
  4. Decide the high-priority table deliberately. Leaving qos_ca_high_limit 0 means a single high-priority packet then a turn for the low table — a safe default that cannot starve storage.[1] Do not reach for 255: the documentation warns explicitly that it may starve the low-priority VLs.[1]
  5. Assign the SL to the traffic in the policy file, not the tables. A qos-level with sl: 3 matched by the storage target’s port group, with the DEFAULT level at sl: 0, and the target-GUID rule placed last so it does not capture other ULPs.[1]
  6. Apply during the window and verify in order:
    smpquery SL2VL <lid> 1
    smpquery VLArb <lid> 1
    ibdiagnet -r --r_opt check_sl
    Expected: SL3 to VL3 on the port; the low table showing 0:192 and 3:64; and no SL mapped to VL15 fabric-wide.[7][5]
  7. Prove it moves under real traffic:
    # server, then client with identical options
    ib_write_bw -d mlx5_0 -S 3 -D 30
    perfquery -X <lid> 1 ; perfquery -S <lid> 1
    Expected: PortXmitDataSL for SL3 climbing while other SLs stay flat.[11][8] Quote the numbers as octets divided by four or the customer’s arithmetic will not match yours.[8]
  8. Rollback plan, written before step 6 runs: restore the previous opensm.conf and policy file from backup and restart the SM. Note in the change record that restoring max_op_vls will flap all links a second time.[3]

Four classes, two lanes

How it ended

The running configuration answers both prior questions: QoS is on, and max_op_vls is 2 - so all four classes share two lanes and the paper on the table is decorative.[3] smpquery SL2VL and smpquery VLArb on a leaf port show what is actually programmed, and ibdiagnet -r --r_opt check_sl clears the fabric of any SL mapped to VL15.[7][5]

What you say to the network lead: “Your design has four classes and your fabric has two lanes. Raising max_op_vls flaps every link, so it belongs in a maintenance window, not on this call.”[3]

She writes the window down. Underneath it, the co-op’s security side has already added Friday’s change board: every InfiniBand key on before Monday.

Lab

Mutating steps ahead. Needs a maintenance window, out-of-band access (BMC/iDRAC/rshim console) and a rollback path. Record the pre-flight inventory before changing anything. Never on a production host.

Goal: program and read back a real QoS design on the Dell lab. Step 3 restarts the subnet manager with new tables and changes fabric behaviour; its rollback is named. Do not change max_op_vls on anything but a lab fabric — it flaps every link.

  1. Pre-flight, read-only:
    ibstat | grep -E "Base lid|State:"
    sudo cp /etc/opensm/opensm.conf /root/opensm.conf.bak 2>/dev/null || opensm -c /root/opensm.conf.bak
    smpquery SL2VL <lid> 1 | tee /tmp/sl2vl-before.txt
    smpquery VLArb <lid> 1 | tee /tmp/vlarb-before.txt
    Expected: active ports with LIDs, a saved baseline configuration, and the tables as programmed with QoS off — capture them even if they look empty, because the diff is the evidence.[7]
  2. Write the QoS parameters into a config file rather than the command line, so the change is reviewable:
    qos TRUE
    qos_ca_sl2vl  0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,7
    qos_ca_vlarb_low  0:192,3:64,1:0,2:0,4:0,5:0,6:0,7:0,8:0,9:0,10:0,11:0,12:0,13:0,14:0
    qos_swe_sl2vl 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,7
    qos_swe_vlarb_low 0:192,3:64,1:0,2:0,4:0,5:0,6:0,7:0,8:0,9:0,10:0,11:0,12:0,13:0,14:0
  3. Mutating — restart the SM with QoS enabled. Rollback: sudo kill $(cat /var/run/opensm.pid) then restart with the original command and no -Q.
    sudo kill $(cat /var/run/opensm.pid)
    sudo opensm -g <port_guid> -p 13 -Q -F /etc/opensm/opensm.conf -B -J /var/run/opensm.pid
    sleep 20
    grep -c "SUBNET UP" /var/log/opensm.log
    Expected: one further SUBNET UP.[2]
  4. Read back what was programmed, read-only:
    smpquery SL2VL <lid> 1 | tee /tmp/sl2vl-after.txt
    smpquery VLArb <lid> 1 | tee /tmp/vlarb-after.txt
    diff /tmp/sl2vl-before.txt /tmp/sl2vl-after.txt
    diff /tmp/vlarb-before.txt /tmp/vlarb-after.txt
    Expected: SL3 mapping to VL3 and the low table showing 0:192 and 3:64.[7] If nothing changed, QoS did not enable — check that the SM really loaded your config file before touching the tables again.
  5. Fabric-wide validation, read-only:
    ibdiagnet -r --r_opt check_sl
    ibdiagnet --qos
    Expected: no SL mapped to VL15, and the SL and VL tables written to ibdiagnet2.slvl in the directory the run prints.[5][6][9]
  6. Move traffic on one SL and watch its counter, read-only in effect. Server then client with identical options:
    ib_write_bw -d mlx5_0 -S 3 -D 20              # server
    ib_write_bw -d mlx5_0 -S 3 -D 20 <server_ip>  # client
    perfquery -X <lid> 1 ; perfquery -S <lid> 1
    Expected: the SL3 entries of PortXmitDataSL and PortRcvDataSL move while other SLs stay flat.[11][8] Remember the counters are octets divided by four before you compare them with the perftest result.[8]
  7. Reproduce the silent drop deliberately, mutating. Change the SL2VL entry for SL5 to 15, restart the SM, re-run ibdiagnet -r --r_opt check_sl, and try ib_write_bw -S 5.[1][5] Expected: the check flags the mapping and the SL5 transfer gets nowhere. Rollback: restore the entry to its identity value and restart.
  8. Restore: put back /root/opensm.conf.bak, restart the SM without -Q, and re-run the step 4 diffs until they are empty. Optional, customer lab only: compare the same tables against ibdiagnet2.slvl collected fabric-wide from a UFM-managed subnet, and note whether max_op_vls there is 2.[6][3]

Retrieval check

10 questions from memory. Answer before looking anything up; misses become flashcards.

Explain it to a Dell SE

A Dell customer wants storage traffic to stop starving their training jobs and asks for QoS on the InfiniBand fabric. Explain in five sentences what you would actually configure and what could make the whole design do nothing.

14 flashcards for this lesson — 0 in deck. Spaced review lives at /review.

Sources

Facts in this lesson were checked against QoS_management_in_OpenSM.txt (linux-rdma master) re-fetched 2026-09-07 (hard-coded qos_ca_* and qos_swe_* defaults, qos-setup parsed and ignored, 64-byte credits, high_limit semantics); UFM Subnet Manager Default Properties 6.24.1 re-fetched 2026-09-07 (qos TRUE, max_op_vls 2 with the fabric-flap note). Dates are when each page was fetched.

  1. QoS Management in OpenSM (linux-rdma/opensm master) · fetched 2026-09-07
  2. opensm(8) man page source (linux-rdma/opensm master) · fetched 2026-09-07
  3. UFM Enterprise 6.24.1: UFM Subnet Manager Default Properties · fetched 2026-09-07
  4. RFC 4392 - IP over InfiniBand (IPoIB) Architecture · fetched 2026-09-07
  5. Routing Validation - IBUtils2 2.26.0 · fetched 2026-09-07
  6. ibdiagnet Dump Files - IBUtils2 Utility Documentation · fetched 2026-09-07
  7. smpquery(8) man page (rdma-core master) · fetched 2026-09-07
  8. perfquery(8) man page (rdma-core master) · fetched 2026-09-07
  9. ibdiagnet Basic Commands - IBUtils2 Utility Documentation · fetched 2026-09-07
  10. SM Configurations - UFM Enterprise 6.20.1 · fetched 2026-09-07
  11. perftest README (linux-rdma/perftest master) · fetched 2026-09-07
  12. opensm/include/opensm/osm_base.h - built-in option defaults (linux-rdma/opensm master) · fetched 2026-09-07

The same idea elsewhere

Other lessons that cover this ground, sometimes from another course's angle.