Linux - RPS (Receive Packet Steering)
之前 介紹過 RSS, 但這個需要 硬體 配合,
Google 在 2010 年時有提出 RPS (Receive Packet Steering) 的方式,
利用報文的 hash 值, 來決定選用的 cpu, 這個 hash 值可以由網卡 硬體計算,
也可以由 軟體來計算. 這樣可以充分利用多核 (software interrupt load balance),
使得相對原本 no RPS 的作法, 有比較好的效能
https://lwn.net/Articles/378617/
1. multiqueue
首先 network device driver 需要決定 rx queue 個數, 這邊介紹一篇
HowTo for multiqueue network device support
device driver 先透過 alloc_etherdev_mq() 告訴 kernel 有多少個 RX queues (TX queues)
這邊相對應可以在底下目錄看到
/sys/class/net/<device>/queues/rx-?
如果 count 為 1, 則只有一個 rx-0, tx-0
如果 count 為 4, 則會看到 rx-0, rx-1, rx-2, rx-3, tx-0, tx-1, tx-2, tx-3
2. 指定 cpu
Scaling in the Linux Networking Stack
SMP IQ affinity
/sys/class/net/(dev)/queues/rx-(n)/rps_cpus
例如假設有 8 核, 我們想設置第 0, 2, 4, 6 CPU 用這個 queue
# echo 55 > /sys/class/net/eth0/queues/rx-0/rps_cpus
3. RPS 處理
當網卡 driver 報 rx packet 給 kernel 時, 會透過底下 function :
- netif_rx() : 非 NAPI
- netif_receive_skb(): NAPI
(1) 透過 get_rps_cpu() 得知決定該封包由哪一個 cpu 處理
作法: 通過 skb 計算 hash, 然後通過 hash 從對應的 queue 的 rps_mapping 取得 對應的 cpu id
這 hash 值可以交給 hardware network device 計算, 或 software 計算.
但 software 計算可能造成 cpu cache miss 效能問題
(2) 將該 packet 放到該 cpu 的 softnet_data 中的 input_pkt_queue 中,
每個 CPU 都有一個 softnet 結構, 和各自的 input_pkt_queue
softnet_data struct 中有 backlog, 在 enqueue_to_backlog 中, 會將 backlog 加入 cpu 輪詢,
並觸發 software interrupt, 而在net_rx_action() 處理
( net_rx_action() 會呼叫到 napi_poll() 和 net_rps_poll() )
另外可以在 /proc/softirqs 看到各 CPU 處理 NET_RX 的個數
--
下回介紹 RFS (receive flow steering)
https://lwn.net/Articles/381955/
Google 在 2010 年時有提出 RPS (Receive Packet Steering) 的方式,
利用報文的 hash 值, 來決定選用的 cpu, 這個 hash 值可以由網卡 硬體計算,
也可以由 軟體來計算. 這樣可以充分利用多核 (software interrupt load balance),
使得相對原本 no RPS 的作法, 有比較好的效能
https://lwn.net/Articles/378617/
1. multiqueue
首先 network device driver 需要決定 rx queue 個數, 這邊介紹一篇
HowTo for multiqueue network device support
device driver 先透過 alloc_etherdev_mq() 告訴 kernel 有多少個 RX queues (TX queues)
( 這兩個數量是相同的), kernel 會進行配置.
#define alloc_etherdev_mq(sizeof_priv, count) alloc_etherdev_mqs(sizeof_priv, count, count)這邊相對應可以在底下目錄看到
/sys/class/net/<device>/queues/rx-?
如果 count 為 1, 則只有一個 rx-0, tx-0
如果 count 為 4, 則會看到 rx-0, rx-1, rx-2, rx-3, tx-0, tx-1, tx-2, tx-3
2. 指定 cpu
Scaling in the Linux Networking Stack
SMP IQ affinity
/sys/class/net/(dev)/queues/rx-(n)/rps_cpus
例如假設有 8 核, 我們想設置第 0, 2, 4, 6 CPU 用這個 queue
# echo 55 > /sys/class/net/eth0/queues/rx-0/rps_cpus
3. RPS 處理
當網卡 driver 報 rx packet 給 kernel 時, 會透過底下 function :
- netif_rx() : 非 NAPI
- netif_receive_skb(): NAPI
(1) 透過 get_rps_cpu() 得知決定該封包由哪一個 cpu 處理
作法: 通過 skb 計算 hash, 然後通過 hash 從對應的 queue 的 rps_mapping 取得 對應的 cpu id
這 hash 值可以交給 hardware network device 計算, 或 software 計算.
但 software 計算可能造成 cpu cache miss 效能問題
(2) 將該 packet 放到該 cpu 的 softnet_data 中的 input_pkt_queue 中,
每個 CPU 都有一個 softnet 結構, 和各自的 input_pkt_queue
softnet_data struct 中有 backlog, 在 enqueue_to_backlog 中, 會將 backlog 加入 cpu 輪詢,
並觸發 software interrupt, 而在net_rx_action() 處理
( net_rx_action() 會呼叫到 napi_poll() 和 net_rps_poll() )
另外可以在 /proc/softirqs 看到各 CPU 處理 NET_RX 的個數
--
下回介紹 RFS (receive flow steering)
https://lwn.net/Articles/381955/
留言
張貼留言