iT邦幫忙

2026 iThome 鐵人賽

DAY 23
0
IT Operation

低延遲網路的維運工程:從 HFT 現場長出來的 30 天系列 第 23 篇

Day 23:ethtool RX 調校的延遲實測

  • 分享至 

  • xImage
  •  

Solarflare X4522 的 interrupt coalescing 只在封包很密的時候才會拖慢延遲,而且實際等的時間比設定值長得多。每 1 ms 一個請求時,rx-usecs 從 0 調到 100,延遲沒有變;請求改成每 20 µs 一個、關掉 busy poll,中位數從 4.35 µs 拉長到約 150 µs。同樣每 20 µs 一個、rx-usecs 100,開著 busy poll 時中位數反而是全篇最低的 2.91 µs,coalescing 影響不到它。ring buffer 縮小、GRO 關掉,延遲都沒變。

三個參數與量法

ExaNIC X25 的 port0 每隔固定時間送一個多播請求,X4522 上的回覆程式收到就回;交換器把請求和回覆都送到 X25 的 port1,由它打兩個硬體時戳相減。每一輪 10000 個請求,另外加了兩項控制:

  1. 回覆程式用 taskset 綁在 CPU 19,排除排程器中途換 CPU 對延遲的影響。
  2. 每改一個參數,先讀回設定確認生效,再開始量。
參數 指令 管什麼 這台原本
interrupt coalescing ethtool -C 延後發中斷,讓多個封包共用一次中斷 rx-usecs 0、adaptive off
ring buffer ethtool -G 網卡接收佇列能暫存的封包數 RX 4096
offload ethtool -K 把同一條連線的多個封包合併成一個大封包再往上交,GRO 在 kernel 做、LRO 在網卡端做 GRO on、LRO off

這台的 tuned 還開了 busy poll(net.core.busy_read 50)。程式在 recvmsg 等封包時,會先自己到網卡的佇列輪詢最多 50 µs,等不到才改等中斷。

interrupt coalescing 的作用條件

表中請求間隔 1 ms 的三輪,busy poll 照這台原本開著。它最多只輪詢 50 µs,下一個請求 1 ms 後才到,程式早就改等中斷,所以這三輪的封包一樣靠中斷收進來,中斷次數 10000 也對得上。間隔 20 µs 的四輪不一樣,下一個封包在輪詢結束前就到了,要先把 busy poll 關掉,讓每個封包都靠中斷收進來,才量得到 coalescing 的影響。

請求間隔 設定 中位數 p99.9 收請求的中斷 平均中斷間隔
1 ms rx-usecs 0 4.68 µs 5.09 µs 10000 1.05 ms
1 ms rx-usecs 100 4.64 µs 5.10 µs 10000 1.05 ms
1 ms adaptive(上限 50) 4.66 µs 5.12 µs 10000 1.05 ms
20 µs rx-usecs 0 4.35 µs 12.40 µs 10000 20 µs
20 µs rx-usecs 50 77.02 µs 141.98 µs 1455 137.5 µs
20 µs rx-usecs 100 149.64 µs 279.80 µs 728 274.7 µs
20 µs adaptive(上限 50) 76.86 µs 141.96 µs 1455 137.5 µs

間隔 1 ms 時,rx-usecs 100 跟 0 的中位數只差 40 ns,中斷一樣是一個封包一次,封包都沒有多等。kernel 對 rx-usecs 的定義是「收到封包後延遲幾 µs 再發中斷」,這張卡在封包稀疏時沒有照這個定義延遲。

間隔 20 µs 時差異才出現:rx-usecs 設得越大,中斷越少、延遲越長,等於用延遲換中斷次數。rx-usecs 50 跟 100 的平均中斷間隔都是設定值的 2.75 倍,p99.9 大約是一個間隔加上沒開時的 4.35 µs:

https://ithelp.ithome.com.tw/upload/images/20261006/20184063npF6mQZnol.png

adaptive 讓驅動依流量自動調整等待時間。間隔 1 ms 時它跟 rx-usecs 0 一樣,間隔 20 µs 時跟 rx-usecs 固定 50 幾乎相同,封包一密就把等待時間開到上限。

busy poll 下的 coalescing

把 busy poll 開回 50,同樣間隔 20 µs、rx-usecs 100,跟關著時比較:

間隔 20 µs rx-usecs 0、busy poll 關 rx-usecs 100、busy poll 關 rx-usecs 100、busy poll 開
中位數 4.35 µs 149.64 µs 2.91 µs
p99.9 12.40 µs 279.80 µs 3.93 µs
收請求的中斷 10000 728 729
kernel 收到封包到程式拿到(中位數) 1385 ns 9794 ns 492 ns

busy poll 開著時,程式一直在網卡的佇列上輪詢,封包一到就被拿走,不用等中斷,rx-usecs 100 也影響不到它。中斷照樣每 275 µs 左右來一次,只是那時封包已經被拿走了:

https://ithelp.ithome.com.tw/upload/images/20261006/20184063FKtFhpdIVA.png

kernel 的文件建議全域打開時設 50,也寫了會增加耗電,因為程式等封包時一直在輪詢。

ring buffer 與 offload

ring buffer 管的是 kernel 來不及收時,網卡能先暫存多少封包。除了每 1 ms 一個請求,也讓 X25 用線速送 20000 個 1518 bytes(每秒約 81 萬個),X4522 只加入群組、不開程式收:

ring RX 每 1 ms 一個請求的中位數 爆量時網卡收到 網卡丟掉 kernel 收到
512 4.58 µs 20000 0 20000
4096 4.61 µs 20000 0 20000

512 也沒掉封包,這個速率下 kernel 收得過來,ring 用不滿:

https://ithelp.ithome.com.tw/upload/images/20261006/20184063FfXzL5mgzX.png

GRO 關掉,中位數一樣是 4.58 µs,通常是因為每 1 ms 才來一個 UDP 請求,沒有可以合併的封包。關的時候 ethtool 印出了沒要求的變更:

https://ithelp.ithome.com.tw/upload/images/20261006/20184063IRml1572kN.png

LRO 從 off 變成 on。把 GRO 開回來,LRO 還是開著。這輪的中位數沒受影響,但這種沒要求的連動變更,只確認自己改的那一項就會漏掉;復原時要另外用 ethtool -K <介面> lro off 關回去。

調完 ethtool 的驗證與監控

  1. 改完讀回 ethtool -c、-g、-k,跟改之前整份比對,沒改的項目也要看。
  2. coalescing 要用比計時器密的流量驗,每 1 ms 一個封包量不出差別。行情爆量時封包間隔是微秒等級,那時才會被拖慢。
  3. 不要用 rx-usecs 推算封包會等多久。這張卡實際是設定值的 2.75 倍,換卡或換驅動都要重量。
  4. 這三份輸出存成基線,開機或更新驅動後跟基線不同就列為 P2;port_rx_nodesc_drops(ring 沒有空格、網卡只好丟掉的封包)增量大於 0,交易時段 P1 通報。

明天看網卡中斷和回覆程式各放在哪顆 CPU,延遲差多少。


上一篇
Day 22:kernel 網路堆疊的收發延遲實測
下一篇
Day 24:IRQ 與程式綁核的延遲實測
系列文
低延遲網路的維運工程:從 HFT 現場長出來的 30 天 共 25 篇
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言