1. 網(wǎng)卡處理數(shù)據(jù)包流程
網(wǎng)卡處理網(wǎng)絡(luò)數(shù)據(jù)流程圖:
圖片來(lái)自參考鏈接1
上圖中虛線(xiàn)步驟的解釋?zhuān)?/p>
1 DMA 將 NIC 接收的數(shù)據(jù)包逐個(gè)寫(xiě)入 sk_buff ,一個(gè)數(shù)據(jù)包可能占用多個(gè) sk_buff , sk_buff 讀寫(xiě)順序遵循FIFO(先入先出)原則。
2 DMA 讀完數(shù)據(jù)之后,NIC 會(huì)通過(guò) NIC Interrupt Handler 觸發(fā) IRQ (中斷請(qǐng)求)。
3 NIC driver 注冊(cè) poll 函數(shù)。
4 poll 函數(shù)對(duì)數(shù)據(jù)進(jìn)行檢查,例如將幾個(gè) sk_buff 合并,因?yàn)榭赡芡粋€(gè)數(shù)據(jù)可能被分散放在多個(gè) sk_buff 中。
5 poll 函數(shù)將 sk_buff 交付上層網(wǎng)絡(luò)棧處理。
完整流程:
1 系統(tǒng)啟動(dòng)時(shí) NIC (network interface card) 進(jìn)行初始化,系統(tǒng)分配內(nèi)存空間給 Ring Buffer 。
2 初始狀態(tài)下,Ring Buffer 隊(duì)列每個(gè)槽中存放的 Packet Descriptor 指向 sk_buff ,狀態(tài)均為 ready。
3 DMA 將 NIC 接收的數(shù)據(jù)包逐個(gè)寫(xiě)入 sk_buff ,一個(gè)數(shù)據(jù)包可能占用多個(gè) sk_buff ,sk_buff 讀寫(xiě)順序遵循FIFO(先入先出)原則。4 被寫(xiě)入數(shù)據(jù)的 sk_buff 變?yōu)?used 狀態(tài)。
5 DMA 讀完數(shù)據(jù)之后,NIC 會(huì)通過(guò) NIC Interrupt Handler 觸發(fā) IRQ (中斷請(qǐng)求)。
6 NIC driver 注冊(cè) poll 函數(shù)。
7 poll 函數(shù)對(duì)數(shù)據(jù)進(jìn)行檢查,例如將幾個(gè) sk_buff 合并,因?yàn)榭赡芡粋€(gè)數(shù)據(jù)可能被分散放在多個(gè) sk_buff 中。8 poll 函數(shù)將 sk_buff 交付上層網(wǎng)絡(luò)棧處理。
9 poll 函數(shù)清理 sk_buff,清理 Ring Buffer 上的 Descriptor 將其指向新分配的 sk_buff 并將狀態(tài)設(shè)置為 ready。
2. 多 CPU 下的 Ring Buffer 處理
因?yàn)榉峙浣o Ring Buffer 的空間是有限的,當(dāng)收到的數(shù)據(jù)包速率大于單個(gè) CPU 處理速度的時(shí)候 Ring Buffer 可能被占滿(mǎn),占滿(mǎn)之后再來(lái)的新數(shù)據(jù)包會(huì)被自動(dòng)丟棄。
如果在多核 CPU 的服務(wù)器上,網(wǎng)卡內(nèi)部會(huì)有多個(gè) Ring Buffer,NIC 負(fù)責(zé)將傳進(jìn)來(lái)的數(shù)據(jù)分配給不同的 Ring Buffer,同時(shí)觸發(fā)的 IRQ 也可以分配到多個(gè) CPU 上,這樣存在多個(gè) Ring Buffer 的情況下 Ring Buffer 緩存的數(shù)據(jù)也同時(shí)被多個(gè) CPU 處理,就能提高數(shù)據(jù)的并行處理能力。
當(dāng)然,要實(shí)現(xiàn)“NIC 負(fù)責(zé)將傳進(jìn)來(lái)的數(shù)據(jù)分配給不同的 Ring Buffer”,NIC 網(wǎng)卡必須支持 Receive Side Scaling(RSS) 或者叫做 multiqueue 的功能。RSS 除了會(huì)影響到 NIC 將 IRQ 發(fā)到哪個(gè) CPU 之外,不會(huì)影響別的邏輯了。數(shù)據(jù)處理過(guò)程跟之前描述的是一樣的。
3. Ring Buffer 相關(guān)命令
在生產(chǎn)實(shí)踐中,因 Ring Buffer 寫(xiě)滿(mǎn)導(dǎo)致丟包的情況很多。當(dāng)環(huán)境中的業(yè)務(wù)流量過(guò)大且出現(xiàn)網(wǎng)卡丟包的時(shí)候,考慮到 Ring Buffer 寫(xiě)滿(mǎn)是一個(gè)很好的思路。
總結(jié)下 Ring Buffer 相關(guān)的命令:
3.1 網(wǎng)卡收到的數(shù)據(jù)包統(tǒng)計(jì)
[root@test]$ethtool-Sem1|more NICstatistics: rx_packets:35874336743 tx_packets:35163830212 rx_bytes:6337524253985 tx_bytes:3686383656436 rx_broadcast:15392577 tx_broadcast:873436 rx_multicast:45849160 tx_multicast:1784024
RX 就是收到數(shù)據(jù),TX 是發(fā)出數(shù)據(jù)。
3.2 帶有 drop 字樣的統(tǒng)計(jì)和 fifo_errors 的統(tǒng)計(jì)
[root@test]$ethtool-Sem1|grep-iE"error|drop" rx_crc_errors:0 rx_missed_errors:0 tx_aborted_errors:0 tx_carrier_errors:0 tx_window_errors:0 rx_long_length_errors:0 rx_short_length_errors:0 rx_align_errors:0 dropped_smbus:0 rx_errors:0 tx_errors:0 tx_dropped:0 rx_length_errors:0 rx_over_errors:0 rx_frame_errors:0 rx_fifo_errors:79270 tx_fifo_errors:0 tx_heartbeat_errors:0 rx_queue_0_drops:16669 rx_queue_1_drops:21522 rx_queue_2_drops:0 rx_queue_3_drops:5678 rx_queue_4_drops:5730 rx_queue_5_drops:14011 rx_queue_6_drops:15240 rx_queue_7_drops:420
發(fā)送隊(duì)列和接收隊(duì)列 drop 的數(shù)據(jù)包數(shù)量顯示在這里。并且所有 queue_drops 加起來(lái)等于 rx_fifo_errors。所以總體上能通過(guò) rx_fifo_errors 看到 Ring Buffer 上是否有丟包。如果有的話(huà)一方面是看是否需要調(diào)整一下每個(gè)隊(duì)列數(shù)據(jù)的分配,或者是否要加大 Ring Buffer 的大小。
3.3 查詢(xún) Ring Buffer 大小
[root@test]$ethtool-gem1 Ringparametersforem1: Pre-setmaximums: RX:4096 RXMini:0 RXJumbo:0 TX:4096 Currenthardwaresettings: RX:256 RXMini:0 RXJumbo:0 TX:256
RX 和 TX 最大是 4096,當(dāng)前值為 256 。隊(duì)列越大丟包的可能越小,但數(shù)據(jù)延遲會(huì)增加。
3.4 調(diào)整 Ring Buffer 隊(duì)列數(shù)量
[root@test]$ethtool-lem1 Channelparametersforem1: Pre-setmaximums: RX:0 TX:0 Other:1 Combined:8 Currenthardwaresettings: RX:0 TX:0 Other:1 Combined:8
Combined = 8,說(shuō)明當(dāng)前 NIC 網(wǎng)卡會(huì)使用 8 個(gè)進(jìn)程處理網(wǎng)絡(luò)數(shù)據(jù)。
更改 eth0 網(wǎng)卡 Combined 的值:
ethtool -L eth0 combined 8
需要注意的是,ethtool 的設(shè)置操作可能都要重啟一下才能生效。
3.4 調(diào)整 Ring Buffer 隊(duì)列大小查看當(dāng)前 Ring Buffer 大小:
[root@test]$ethtool-gem1 Ringparametersforem1: Pre-setmaximums: RX:4096 RXMini:0 RXJumbo:0 TX:4096 Currenthardwaresettings: RX:256 RXMini:0 RXJumbo:0 TX:256
看到 RX 和 TX 最大是 4096,當(dāng)前值為 256。隊(duì)列越大丟包的可能越小,但數(shù)據(jù)延遲會(huì)增加.
設(shè)置 RX 和 TX 隊(duì)列大小:
ethtool -G em1 rx 4096
ethtool -G em1 tx 4096
3.5 調(diào)整 Ring Buffer 隊(duì)列的權(quán)重
NIC 如果支持 mutiqueue 的話(huà) NIC 會(huì)根據(jù)一個(gè) Hash 函數(shù)對(duì)收到的數(shù)據(jù)包進(jìn)行分發(fā)。能調(diào)整不同隊(duì)列的權(quán)重,用于分配數(shù)據(jù)。
[root@test]$ethtool-xem1 RXflowhashindirectiontableforem1with8RXring(s): 0:00000000 8:00000000 16:11111111 24:11111111 32:22222222 40:22222222 48:33333333 56:33333333 64:44444444 72:44444444 80:55555555 88:55555555 96:66666666 104:66666666 112:77777777 120:77777777 RSShashkey: Operationnotsupported
我的 NIC 一共有 8 個(gè)隊(duì)列,一共有 128 個(gè)不同的 Hash 值,上面就是列出了每個(gè) Hash 值對(duì)應(yīng)的隊(duì)列是什么。最左側(cè) 0 8 16 是為了能讓你快速的找到某個(gè)具體的 Hash 值。比如 Hash 值是 76 的話(huà)我們能立即找到 72 那一行:"72: 4 4 4 4 4 4 4 4",從左到右第一個(gè)是 72 數(shù)第 5 個(gè)就是 76 這個(gè) Hash 值對(duì)應(yīng)的隊(duì)列是 4 。
設(shè)置 8 個(gè)隊(duì)列的權(quán)重。加起來(lái)不能超過(guò) 128 。128 是 indirection table 大小,每個(gè) NIC 可能不一樣。
3.6 更改 Ring Buffer Hash Field
分配數(shù)據(jù)包的時(shí)候是按照數(shù)據(jù)包內(nèi)的某個(gè)字段來(lái)進(jìn)行的,這個(gè)字段能進(jìn)行調(diào)整。
[root@test]$ethtool-nem1rx-flow-hashtcp4 TCPoverIPV4flowsusethesefieldsforcomputingHashflowkey: IPSA IPDA L4bytes0&1[TCP/UDPsrcport] L4bytes2&3[TCP/UDPdstport]
也可以設(shè)置 Hash 字段:查看 tcp4 的 Hash 字段。
ethtool -N em1 rx-flow-hash udp4 sdfn
sdfn 需要查看 ethtool 看其含義,還有很多別的配置值。
3.6 IRQ 統(tǒng)計(jì)
/proc/interrupts 能看到每個(gè) CPU 的 IRQ 統(tǒng)計(jì)。一般就是看看 NIC 有沒(méi)有支持 multiqueue 以及 NAPI 的 IRQ 合并機(jī)制是否生效。看看 IRQ 是不是增長(zhǎng)的很快。
-
網(wǎng)卡
+關(guān)注
關(guān)注
4文章
323瀏覽量
27846 -
buffer
+關(guān)注
關(guān)注
2文章
120瀏覽量
30492 -
函數(shù)
+關(guān)注
關(guān)注
3文章
4368瀏覽量
64185 -
dma
+關(guān)注
關(guān)注
3文章
572瀏覽量
102308 -
NIC
+關(guān)注
關(guān)注
0文章
23瀏覽量
12608
原文標(biāo)題:網(wǎng)卡的 Ring Buffer 詳解
文章出處:【微信號(hào):LinuxHub,微信公眾號(hào):Linux愛(ài)好者】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
網(wǎng)卡知識(shí)詳解
網(wǎng)卡芯片詳解
Ring Buffer 有什么特別?
什么是Resilient Packet Ring
粉紅圈(pink ring),粉紅圈(pink ring)是
Ring buffer介紹
BPF ring buffer解決的問(wèn)題及背后的設(shè)計(jì)
網(wǎng)卡的Ring Buffer詳解
簡(jiǎn)述linux系統(tǒng)UDP丟包問(wèn)題分析思路(上)

簡(jiǎn)述linux系統(tǒng)UDP丟包問(wèn)題分析思路(下)
多CPU下的Ring Buffer處理

MSPM0 UART通信中DMA和Ring Buffer環(huán)形緩沖的應(yīng)用

評(píng)論