Page MenuHomeFreeBSD

iflib: implement drbr for simple_tx.
Needs ReviewPublic

Authored by gallatin on Mon, Aug 17, 11:02 PM.
Tags
None
Referenced Files
F168335343: D58901.id.diff
Thu, Aug 27, 4:22 PM
Unknown Object (File)
Wed, Aug 26, 12:54 AM
Unknown Object (File)
Mon, Aug 24, 12:39 PM
Unknown Object (File)
Sun, Aug 23, 8:44 PM
Unknown Object (File)
Sat, Aug 22, 11:36 PM
Unknown Object (File)
Sat, Aug 22, 8:57 PM
Unknown Object (File)
Sat, Aug 22, 6:10 AM
Unknown Object (File)
Thu, Aug 20, 6:19 AM
Subscribers

Details

Summary

{F166942590}Port buf_ring/drbr deferred transmit from mxge(4) to iflib. This
makes simple_tx outperform mp_ring by a wide margin (1.9x to 9x) at
all concurrency (fan-in) levels in my testing. This also adds ALTQ
support to simple_tx and gets us one step closer to removing mp_ring.
The drbr support has 2 improvements from mxge(4):

  1. Limit the number of producers attempting to defer traffic and block on ift_mtx rather than having many producers spinning on br_prod_tail. Producers are bounded via net.iflib.simple_max_producers, which defaults to 1 & which measured best by a fairly wide margin in testing using a home-grown packet generator sending traffic from N threads to a single output queue on a 96c/192t AMD Turin. Traditional unlimited deferrals can be achieved by setting it larger than ncpu, and setting it to 0 falls back to the current behavior of always grabbing a mutex.
  1. Block rather than drop when the buf ring fills. This limits useless work done by producers and again limits producers spinning on br_prod_tail when simple_max_producers is large.

The drbr buf_ring helper functions have been modified to support
blocking by removing the mbuf free in drbr_enqueue to
add a drbr_enqueue_nodrop() variant.

Drain from the tx task is bounded by net.iflib.simple_drain_quota
(default 8) so it cannot starve rx on a shared taskqueue or ithread.
The tx task is also modified to use a trylock and not block
waiting for another thread draining the buf ring.

We force queue 0 when ALTQ is enabled, as the mp_ring path does.

Performance data below from a 96c Turin, using a 400g bnxt interface, with my pkgen
sending 1342B UDP packets with separate headers (so as to be realistic and
give encap work to do). A single txq is selected by forcing the flowid in
the pkt generator., Gb/s at 1/2/4/8/16/32/64 threads per
queue. Data for this change is taken as the worst of three runs:

mp_ring      20 44 48 35 14  7  4
simple_tx    44 44 44 43 40 36 32
+this change 44 90 90 86 57 50 35

The only remaining feature to support is ice(4)'s special tx queue
selection. After that, I plan to make simple_tx the default
and then remove mp_ring after a month or two and rename all
the simple_tx* to iflib*

Diff Detail

Repository
rG FreeBSD src repository
Lint
Lint Skipped
Unit
Tests Skipped

Event Timeline

This comment was removed by gallatin.
sys/net/iflib.c
149

I think this may need #ifdef ALTQ or some other handling to avoid build breakage where that is undefined

4210

This wont be reachable with the same check right above taking the goto, rebase issue?

7883

for ALTQ this may need (void)iflib_completed_tx_reclaim(txq, NULL); before iflib_simple_drbr_drain because it gives up silently under lock contention

Some preliminary testing on a pedestrian setup: DUT is network limited, 1Gbps and 10Gbps interfaces both tested with 1 MSI-X q. iperf3 off q0 cpu on both sides. Each phase used three 10second repetitions at 1, 2, 4, and 8 parallel senders. Traffic was 1342-byte UDP with an unlimited offered rate, a 2 MiB socket window, fixed source ports, and fixed client affinity on CPUs 1,3,5,7. The tables contain medians. "Goodput" is receiver bytes normalized to the sender interval. This avoids counting iperf's post send socket drain interval. "Drops" means full software TX-ring enqueue failures: r_drops for A1/A2 and drbr_drops for B.

The one stream ice result seems like the best thing to chase first, any thoughts on that? The context switches to on ice 1 stream and I need to figure out what the 82754 awkwardness is for parallel streams.

ice(4) / E810

Reproducibility disclosure, D58910 is also applied

StreamsGoodput A1 / B / A2 (Gb/s)System CPU A1 / B / A2Context switches/s A1 / B / A2TX enqueue drops/run A1 / B / A2
19.526 / 9.531 / 9.51710.4 / 20.5 / 10.2%0.3k / 217k / 0.3k0 / 0.144m / 0
29.531 / 9.533 / 9.53425.0 / 30.7 / 24.7%843k / 506k / 923k6.36m / 1.79m / 6.52m
49.512 / 9.527 / 9.51347.5 / 54.8 / 47.1%1.11m / 661k / 1.13m28.55m / 2.99m / 28.49m
89.524 / 9.533 / 9.50747.2 / 54.9 / 47.1%1.04m / 619k / 1.08m27.92m / 2.27m / 27.83m

At P2-P8, simple_tx:

  • preserves line-rate throughput
  • reduces context switches by approximately 40-43%
  • reduces full-ring enqueue failures by approximately 72-92%
  • lowers peer CPU consumption and peer socket loss
  • costs approximately 6-8 additional sender system CPU%

em(4) / 82574L

StreamsGoodput A1 / B / A2 (Gb/s)System CPU A1 / B / A2Context switches/s A1 / B / A2TX enqueue drops/run A1 / B / A2
10.956 / 0.955 / 0.95613.2 / 21.6 / 13.7%225k / 38.9k / 231k2.40m / 12.88m / 2.16m
20.956 / 0.955 / 0.95632.8 / 31.7 / 32.7%54.9k / 81.5k / 49.7k17.02m / 22.68m / 17.34m
40.956 / 0.955 / 0.95653.3 / 54.4 / 53.7%11.6k / 104k / 11.1k36.97m / 26.61m / 36.85m
80.956 / 0.955 / 0.95653.4 / 55.2 / 53.6%13.0k / 104k / 10.4k37.32m / 26.23m / 36.59m

At P4/P8 it reduces full-ring enqueue failures by approximately 28%, but increases context switches by roughly 8-10x. At P1 it adds about 8 system CPU% and increases enqueue failures by more than 5x.