Page MenuHomeFreeBSD

aq(4): interrupt model and queue-count correctness
ClosedPublic

Authored by nick_spun.io on Thu, Jun 4, 11:20 AM.
Referenced Files
Unknown Object (File)
Sat, Jun 20, 2:48 AM
Unknown Object (File)
Wed, Jun 17, 3:37 AM
Unknown Object (File)
Wed, Jun 17, 1:49 AM
Unknown Object (File)
Sat, Jun 13, 1:02 AM
Unknown Object (File)
Fri, Jun 12, 10:54 PM
Unknown Object (File)
Fri, Jun 12, 5:19 PM
Unknown Object (File)
Wed, Jun 10, 6:15 AM
Unknown Object (File)
Wed, Jun 10, 1:20 AM
Subscribers

Details

Summary

Rework the MSI-X and queue-count handling to use the standard iflib
interrupt model and to keep every ring serviced.

  • Cap isc_n{tx,rx}qsets_max at the RSS indirection-table size (HW_ATL_RSS_INDIRECTION_QUEUES_MAX, 8) instead of HW_ATL_B0_RINGS_MAX. RSS only steers RX traffic to eight rings, so on hosts with more CPUs the surplus TX rings never make progress: iflib flowid-steers TCP flows across every TX ring, and a flow landing on a surplus ring has its segments queued but never transmitted, hanging the connection.
  • Add a TX-specific ifdi_tx_queue_intr_enable that reads tx_rings[txqid]->msix. It was wired to the RX handler, which indexes rx_rings[] with the qid; safe only while tx_rings_count == rx_rings_count, otherwise the lookup walks past rx_rings[] and feeds a garbage msix value into the IRQ mask register.
  • Fix three MSI-X / admin-IRQ bugs: the TX softirq was attached to rx_rings[i]->irq (overwriting the RX handle and leaving the TX handle uninitialized); the admin-IRQ failure path dereferenced rx_rings[rx_rings_count], one past the end; and aq_linkstat_isr cleared the admin interrupt by writing the raw vector number instead of BIT(vector).
  • Allocate one IFLIB_INTR_RXTX vector per RX/TX queue pair like every other in-tree iflib driver (em/ix/igc, vmxnet3) instead of an IFLIB_INTR_RX vector per RX ring plus a hand-wrapped IFLIB_INTR_TX softirq per TX ring. iflib's iflib_fast_intr_rxtx() then services TX completions on the shared vector through isc_txd_credits_update().

Diff Detail

Repository
rG FreeBSD src repository
Lint
Lint Skipped
Unit
Tests Skipped

Event Timeline

Why'd the TX queues hang? like, were they never actually started?

So I actually misdiagnosed the tx issue originally but the fix still worked 😆

We're only using one TC which sets up buffers and whatnot for a maximum of 8 rings. Any rings beyond that still exist but when traffic gets steered to them it doesn't actually go anywhere because they're not being scheduled or anything

We could use more TCs and TX queues but this seems reasonable since we have a max of 8 RX queues anyways

I think its fine to get it up and going, but in theory being able to transmit on all of the rings shouldn't stall traffic. If it is then chances are your RX thread is keeping your TX queue moving forward.

Can we figure out if there's something wrong with the TX side and MSI/intr completions?

We can totally bring up all 32 TX queues without issue now that I realized the issue with queues >8 was just them not being scheduled

This revision is now accepted and ready to land.Fri, Jun 19, 2:17 AM
This revision now requires review to proceed.Fri, Jun 19, 2:29 AM
This revision is now accepted and ready to land.Fri, Jun 19, 4:00 AM
This revision now requires review to proceed.Sat, Jun 20, 5:01 AM
This revision is now accepted and ready to land.Sat, Jun 20, 4:10 PM