文章目錄
- 網卡
- 網卡的核心功能
- 網卡的關鍵技術
- 單隊列網卡
- 多隊列網卡
- 查看網卡信息
- ifconfig
- ethtool
- 查看網卡隊列
- Linux 查看中斷綁定
- 網卡中斷查詢
- 查看中斷綁定的 cpu
- 總結
- 1. 默認情況(單隊列網卡)
- 2. 多隊列網卡
- 3. 如何查看和配置綁定關系?
- 4. 性能優化建議
- 結論
網卡
網卡
(Network Interface Card,NIC),又稱 網絡適配器
(Network Adapter)或 網絡接口控制器(Network Interface Controller),是計算機或其他網絡設備用于連接網絡的硬件組件。
它負責在計算機和網絡(如以太網、Wi-Fi、光纖網絡等)之間傳輸數據。
網卡的核心功能
數據發送
(TX, Transmit):將計算機的數據包轉換為電信號或光信號,并通過物理介質(如網線、光纖、無線電波)發送到網絡。數據接收
(RX, Receive):從網絡接收數據信號,并轉換為計算機可處理的數字數據。MAC 地址管理
:每個網卡都有一個唯一的 MAC 地址(Media Access Control Address),用于在局域網(LAN)中標識設備。協議處理
:支持 TCP/IP、UDP、ARP 等網絡協議,確保數據正確封裝和傳輸。中斷處理(IRQ)
:當數據到達或發送完成時,網卡通過 硬件中斷(IRQ) 通知 CPU 處理
網卡的關鍵技術
- 多隊列(Multi-Queue)
RSS
(Receive Side Scaling):多個 RX 隊列
,讓不同 CPU 核心并行處理接收流量。XPS
(Transmit Packet Steering):多個 TX 隊列
,優化發送性能。
適用場景:高吞吐量服務器(如 10G/25G 網卡)。
- 硬件卸載(Offload)
LRO/GRO
:大包合并,減少 CPU 負載。TSO
(TCP Segmentation Offload):由網卡拆分 TCP 大包
,降低 CPU 開銷。Checksum Offload
:由網卡計算校驗和,提高效率。
- 虛擬化支持
SR-IOV
(Single Root I/O Virtualization):一張物理網卡虛擬出多個虛擬網卡(VF),供虛擬機直通使用。VXLAN/NVGRE Offload
:硬件加速虛擬網絡。
單隊列網卡
如果網卡只有一個 RX 隊列(接收) 和一個 TX 隊列(發送)
,即為單隊列網卡
要注意的是,在網卡中,單獨的 RX(接收) 和 TX(發送) 通常被視為 兩個獨立的隊列,而不是一個隊列。 而稱之為單隊列網卡(1 RX + 1 TX
)是為了與多隊列網卡(n RX + m TX
)區別開來
關鍵點:
RX隊列
:專門負責接收數據包(從網絡到主機)。TX隊列
:專門負責發送數據包(從主機到網絡)。獨立性
:它們的功能和數據處理方向完全相反,硬件和驅動通常會分開管理這兩個隊列。
多隊列網卡
上面說到單隊列網卡 1個RX + 1個TX
= 2個隊列(1個接收隊列 + 1個發送隊列)。
那么如果是多隊列網卡,則可能是 N個RX隊列 + M個TX隊列
(例如 8RX+8TX
)。
查看網卡信息
ifconfig
通過 ifconfig
查看網卡,例如這里是 ens192
[root@ ~]# ifconfig
...
ens192: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
...RX packets 1447137979 bytes 421584628040 (392.6 GiB)RX errors 0 dropped 23 overruns 0 frame 0TX packets 1683429823 bytes 314926856868 (293.2 GiB)TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
ethtool
通過 ethtool
查看網卡相關信息
[root@ ~]# ethtool -i ens192
driver: vmxnet3
version: 1.4.17.0-k-NAPI
firmware-version:
expansion-rom-version:
bus-info: 0000:0b:00.0
supports-statistics: yes
supports-test: no
supports-eeprom-access: no
supports-register-dump: yes
supports-priv-flags: no
查看網卡隊列
可以執行下面命令查看網卡隊列,可以看出有16個隊列,rx 與 tx 隊列各有8個
[root@ ~]# ls /sys/class/net/ens192/queues/
rx-0 rx-1 rx-2 rx-3 rx-4 rx-5 rx-6 rx-7
tx-0 tx-1 tx-2 tx-3 tx-4 tx-5 tx-6 tx-7
Linux 查看中斷綁定
先上結果圖展示:
網卡內部有多個隊列,每一組都有 1 RX + 1 TX
2個隊列,例如 rx-0 與 tx-0
,每一組隊列對應一個中斷,是機器啟動后注冊上去的,每個中斷(硬中斷
)都對應著一個中斷函數。
后續網絡數據的收發 --> 硬中斷 --> 找到中斷函數 --> 用綁定的cpu來處理,網卡所發出的中斷是硬中斷。
網卡中斷查詢
通過 /proc/interrupts
過濾查詢對應網卡的中斷
[root@ ~]# (head -n 1 /proc/interrupts && grep ens192 /proc/interrupts)CPU0 CPU1 CPU2 CPU3 CPU4 CPU5 CPU6 CPU7 57: 54323955 50498186 58073762 26180655 117508750 61323815 13512600 5579109 PCI-MSI-edge ens192-rxtx-058: 36057837 61587828 64925105 16531986 53159081 18216138 14781056 25738649 PCI-MSI-edge ens192-rxtx-159: 21230949 35197430 29174376 15012576 21111201 19745533 193447095 4072969 PCI-MSI-edge ens192-rxtx-260: 18630617 37195730 38652962 23898573 10714277 13863697 22873438 206191900 PCI-MSI-edge ens192-rxtx-361: 20170505 20338217 24230031 27035431 11011878 198439738 60856797 2458748 PCI-MSI-edge ens192-rxtx-462: 71691281 87398091 79354652 46557471 40000772 13542848 4368702 4344379 PCI-MSI-edge ens192-rxtx-563: 58123626 26376999 40864211 157759424 34608174 12835300 31843092 10343885 PCI-MSI-edge ens192-rxtx-664: 109253297 71849659 37388197 55968603 56479525 20341714 5638153 2536989 PCI-MSI-edge ens192-rxtx-765: 0 0 0 0 0 0 0 0 PCI-MSI-edge ens192-event-8
/proc/interrupts
行中 CPU 核心編號列(如 CPU0 CPU1 CPU2…),顯示的是各中斷在這些 CPU 上的觸發次數。
上面舉例說明:
# 65號中斷:
#65: 0 0 0 0 0 0 0 0 PCI-MSI-edge ens192-event-8
65:表示邏輯中斷號,是系統為該中斷分配的唯一標識符。
0 0 0 0 0 0 0 0:這部分表示該中斷在各個 CPU 核心上發生的次數。這里顯示的都是 0,說明到目前為止,這個中斷還沒有在任何 CPU 核心上被觸發過。
PCI-MSI-edge:PCI-MSI 表示中斷類型為 PCI 消息信號中斷(PCI Message Signaled Interrupts),edge 表示中斷觸發方式為邊沿觸發,即當信號的電壓從低電平轉換到高電平時,會產生一個中斷信號,且該中斷信號只被發送一次。
ens192-event-8:這是與該中斷相關聯的設備名稱,表明這個中斷是由網絡接口ens192產生的,event-8可能是ens192網卡的某個特定事件或隊列對應的中斷。另外57號中斷:
#57: 54323955 50498186 58073762 26180655 117508750 61323815 13512600 5579109 PCI-MSI-edge ens192-rxtx-0...(前面幾個略去解釋)
ens192-rxtx-0:
ens192:網絡接口名稱,通常由系統自動分配。
rxtx-0:rxtx:表示該隊列是 接收(RX)和發送(TX)合并隊列(Combined 模式),同時處理數據收發。部分網卡支持將 RX 和 TX 隊列合并為一個隊列以簡化管理。0:隊列編號,表明這是網卡的 第 0 個合并隊列。現代多隊列網卡(如支持 RSS/XPS 的網卡)通常會創建多個隊列(如 rxtx-0、rxtx-1 等),每個隊列獨立處理流量以實現多核并行。
查看中斷綁定的 cpu
中斷與cpu 綁定
,對應的中斷則由相應的cpu來處理,通過 /proc/irq/<IRQ_NUM>/smp_affinity
查詢相關中斷綁定的cpu情況
[root@ ~]# for irq in {57..65}; do echo -n "IRQ $irq: " && cat /proc/irq/$irq/smp_affinity; done
IRQ 57: 01 # 0000 0001, 綁定的是 cpu0
IRQ 58: 40 # 0100 0000, 綁定的是 cpu6
IRQ 59: 02 # 0000 0010, 綁定的是 cpu1
IRQ 60: 08 # 0000 1000, 綁定的是 cpu3
IRQ 61: 20 # 0010 0000, 綁定的是 cpu5
IRQ 62: 10 # 0001 0000, 綁定的是 cpu4
IRQ 63: 02 # 0000 0010, 綁定的是 cpu1
IRQ 64: 04 # 0000 0100, 綁定的是 cpu2IRQ 65: 10 # 0001 0000, 綁定的是 cpu0
可以看出,網卡發送接收相關的中斷(57-64
) 對應網卡8個合并隊列 ens192-rxtx-0~7
,對應著 cpu 0-6
, 服務器是8核的虛擬機,雖然 cpu7 沒用在這個網卡中斷上,有可能其他中斷有占用,cpu1
在 59 與 63 號中斷共用,也可以自己指派 cpu,使其負載均衡,修改的文件是上面的 /proc/irq/$irq/smp_affinity
這里要注意的是每個合并隊列
實際上有兩個獨立的隊列,只是為了省寫方便
,例如 ens192-rxtx-0 指代 rx-0,tx-0
中斷號 | rxtx合并隊列 | cpu |
---|---|---|
57 | ens192-rxtx-0 | cpu0 |
58 | ens192-rxtx-1 | cpu6 |
59 | ens192-rxtx-2 | cpu1 |
60 | ens192-rxtx-3 | cpu3 |
61 | ens192-rxtx-4 | cpu5 |
62 | ens192-rxtx-5 | cpu4 |
63 | ens192-rxtx-6 | cpu1 |
64 | ens192-rxtx-7 | cpu2 |
總結
網卡的 RX(接收)隊列 和 TX(發送)隊列 可以由 同一個 CPU 核心處理,也可以由不同的 CPU 核心處理,具體取決于以下因素:
1. 默認情況(單隊列網卡)
- 如果網卡只有
1個 RX 隊列 和1個 TX 隊列
(即單隊列網卡),通常:- 同一個 CPU 核心 負責處理 RX 和 TX(通過中斷或輪詢方式)。
- 例如,Linux 默認情況下,
eth0
的接收和發送中斷可能綁定到 CPU 0。
2. 多隊列網卡
- 現代高性能網卡(如 Intel I350、X710、Mellanox ConnectX)支持:
多 RX 隊列
(RSS, Receive Side Scaling):不同 RX 隊列可以由不同 CPU 核心處理(負載均衡)。多 TX 隊列
(XPS, Transmit Packet Steering):不同 TX 隊列也可以綁定到不同 CPU 核心。
- RX 和 TX 可以獨立綁定到不同 CPU:
- 例如:
- RX 隊列 0 → CPU 0
- TX 隊列 0 → CPU 1
- RX 隊列 1 → CPU 2
- TX 隊列 1 → CPU 3
- 例如:
3. 如何查看和配置綁定關系?
- Linux 查看中斷綁定:
cat /proc/interrupts | grep ens192 # 查看網卡中斷分配
- 手動調整綁定(如將 RX 隊列 0 綁定到 CPU 2):
echo 4 > /proc/irq/<IRQ_NUM>/smp_affinity # 4 = CPU 2 (二進制掩碼)
- XPS(TX 隊列綁定):
echo 1 > /sys/class/net/ens192/queues/tx-0/xps_cpus # TX 隊列 0 綁定到 CPU 0
4. 性能優化建議
RX 和 TX 分離
:避免同一個 CPU 同時處理接收和發送,減少競爭。NUMA 架構優化
:確保網卡隊列綁定的 CPU 和網卡位于同一個 NUMA 節點,減少跨節點訪問延遲。
結論
單隊列網卡
:RX 和 TX 通常由 同一個 CPU 處理。多隊列網卡
:RX 和 TX 可以 獨立綁定到不同 CPU(推薦配置,提高并行性)。
作為開篇先認識網卡的一些概念,下一篇就開始探索 Linux 網絡數據的收發過程了,會用到本篇網卡隊列的知識,敬請期待……