lwip协议栈优化_干货分享 | KNI性能优化实践
友情提示:全文5000多文字,預計閱讀時間15分鐘
文章源自現網實踐對支撐及用戶態/內核態網絡報文交換場景的認識,歡迎有Linux/FreeBSD內核、網絡協議棧、DPDK優化實踐經驗的同學留言探討~
DPDK簡介
Intel DPDK全稱為Intel Date Plane Development Kit, Intel處理器架構下用戶空間高效的數據包處理提供了庫函數和驅動的支持,它不同于 Linux/FreeBSD等操作系統以通用性設計為目的,而是專注于網絡應用中網絡報文的高性能處理。操作系統與DPDK應用程序網絡處理如下圖所示:
Flow Bifurcation on Intel Ethernet Controller X710/XL710 --Jingjing Wu; Anjali
左側slowpath
在Linux/FreeBSD等操作系統,網卡通過硬件中斷方式通知內核驅動有網絡報文到達,內核響應硬件中斷處理,進一步移交由網卡驅動硬件中斷處理喚醒網卡驅動收包例程(中斷上半部),內核調度網卡驅動收包例程執行網絡報文接收處理(中斷下半部)。在經由一系列的內核網絡協議處理流程后,最終由位于用戶態的應用程序處理網絡報文內容,完成網絡報文接收過程
在整個網絡報文接收過程涉及一系列的軟硬件中斷搶占處理、內存拷貝/缺頁異常處理、系統調用(用戶態/內核上下文切換)、應用程序進程切換等CPU處理資源開銷,直接影響操作系統網絡報文的處理能力,進而影響網絡性能。
右側fastpath
DPDK采用Kernel Bypass方式實現, 在用戶空間實現了一套數據平面進行網絡報文的收發與處理。DPDK應用程序基于大頁內存、核綁定、用戶態輪詢機制的驅動實現,通過重載網卡驅動進行網絡報文收發,直接交由上層應用程序處理。從而避免操作系統內核/用戶態的網絡報文拷貝、線程調度、系統調用、中斷等CPU處理資源損耗,以達到DPDK應用程序網絡處理高性能目的。對于操作系統而言,DPDK應用程序只是一個普通的用戶態進程,與普通應用程序并無差別。
用戶態/內核態交換網絡報文交換
在非SRIOV或虛擬機場景網卡被用戶態DPDK應用程序接管,該網卡所有網絡報文將由用戶態的DPDK應用程序接收處理。對于部分控制面、轉發面分離的高性能DPDK應用實現中,存在采用fastpath、slowpath相結合進行網絡報文收發處理場景,如DPDK+Nginx+Keepalive高可用場景, 如下圖所示:
DPDK+Nginx+Keepalive流量
基于DPDK用戶態TCP/IP協議棧與Nginx相結合,通過fastpath提供高性能HTTP應用服務。Keepalive應用程序沿用操作系統slowpath協議棧進行網絡報文收發處理邏輯,通過VRRP協議提供DPDK+Nginx 高可用場景下的VIP主備切換控制。在用戶態/內核態交換網絡報文交換場景,KNI是DPDK引入的實現方式之一。
KNI
KNI(Kernel NIC Interface)是DPDK用于用戶態與內核態協議棧網絡報文交換的一種機制。其實現原理通過共享內存方式實現用戶態DPDK應用程序與內核態網絡協議棧網絡報文傳遞, 采用注冊KNI虛擬網絡設備接口方式實現網絡報文收發以達到利用內核協議棧,最終將網絡報文轉發至上層應用程序的目的。如下圖所示:
Components of a DPDK KNI Application
KNI注冊的虛擬網絡設備接口兼容支持Linux網絡工具如ethtool、ifconfig 、tcpdump對網絡接口的配置管理。對內核網絡協議棧而言,KNI虛擬網絡設備接口與普通網卡網絡設備接口進行網絡報文收發處理類似。
KNI 實現用戶態/內核態交換網絡報文交換由兩部分組成: 內核態RTE_KNI模塊、用戶態KNI網絡報文收發接口, 如下圖所示:
Packet Flow via mbufs in the DPDK KNI
左側內核態RTE_KNI模塊?
內核態RTE_KNI模塊負責創建初始化KNI虛擬網絡設備操作接口與注冊網絡報文接收內核線程實現網絡報文收發。
KNI網絡報文接收內核線程負責從rx_q網絡報文接收隊列讀取網絡報文,移交內核網絡協議棧入口netif_rx進一步處理。
KNI虛擬網絡設備kni_net_tx接口負責處理來自內核網絡協議棧的網絡報文發送請求,最終將網絡報文移交至tx_q,后續由用戶態DPDK應用程序網絡報文發送線程處理,完成網絡報文發送。
KNI網絡報文接收內核線程存在單線程、多線程兩種模式選擇,可在加載內核模塊時指定。在未指定情況下默認單線程模式,加載KNI內核模塊設置線程模式如下:
insmod kmod/rte_kni.ko? kthread_mode=single或kthread_mode=multiple
單線程、多線程兩種模式主要區別在于:
單線程模式:KNI內核模塊所有KNI虛擬網絡接口創建共享一個內核線程進行網絡報文接收處理。
多線程模式:KNI內核模塊為每個KNI虛擬網絡接口創建單獨一個內核線程進行網絡報文接收處理。在多個KNI虛擬網絡接口場景建議采用多線程模式,以提高單個KNI虛擬網絡設備網絡接收性能。
右側用戶態KNI網絡報文收發接口
用戶態KNI網絡報文收發主要涉及兩個接口:
rte_kni_tx_burst接口:在用戶態DPDK應用程序網絡報文接收處理線程通過rte_eth_rx_burst接口從網卡完成網絡報文讀取后,負責將需移交至內核態的網絡報文添加至rx_q網絡報文接收隊列,后續由內核態KNI網絡報文接收線程處理。
rte_kni_rx_burst接口:在用戶態DPDK應用程序網絡報文發送處理線程負責讀取tx_q網絡報文發送隊列中待發送網絡報文,通過rte_eth_tx_burst網卡發送接口將網絡報文發送。
遇到的問題
現網環境虛擬化計算節點復用一對業務萬兆光口來承載兩種流量:1)overlay虛擬機流量 2)underlay塊存儲流量。DPDK-OVS接管業務萬兆光口后,通過DPDK KNI注冊虛擬化計算節點存儲虛擬網絡接口,實現虛擬化計算節點通過存儲虛擬網絡接口訪問塊存儲。在虛擬機內部讀寫塊設備,虛擬化計算節點KNI虛擬網絡設備存儲網絡接口統計計數出現大量TX dropped。
KNI虛擬網絡設備內核態網絡報文發送接口kni_net_tx處理過程簡述如下:
檢查網絡報文長度及alloc_q/tx_q無可用共享內存緩存,否則釋放內核態網絡報文skb即跳轉至drop丟包處理,并更新KNI虛擬網絡設備TX dropped統計信息。
從alloc_q隊列獲取用戶態 mbuf網絡報文緩存,通過內存物理地址/虛擬地址轉換后完成skb至 mbuf 網絡報文內容復制,最終將mbuf添加至tx_q,移交由用戶態DPDK應用網絡報文發送線程處理,并釋放內核態網絡報文skb。
初步分析與alloc_q/tx_q無可用共享內存緩存有關。具體源碼實現請查閱:dpdk/kernel/linux/kni/kni_net.c ?KNI虛擬網絡設備網絡報文發送kni_net_tx接口。
問題模擬復現
通過DPDK examples/kni例子,模擬現網KNI網絡報文轉發處理過程。簡述如下:
在完成大頁內存設置/核隔離/網卡綁定等DPDK初始化環境后,啟動DPDK KNI
/root/dpdk-19.08/examples/kni/x86_64-native-linuxapp-gcc/kni -l 0-2 -- -P -p 0x1 --config="(0,1,2,0)"
參數說明:
-l? 指定DPDK EAL lcore參數即邏輯CPU ID或掩碼
-p 指定DPDK port
--config 指定參數(port,lcore_rx,lcore_tx,lcore_kthread)涉及port、KNI網絡報文接收線程CPU ID、KNI網絡報文發送線程CPU ID、內核KNI網絡報文接收線程綁定CPU ID
詳細請參見: DPDK Sample Applications User Guides Release 19.08 ?Kernel NIC Interface Sample Application小節
配置KNI虛擬網絡設備地址:
ifconfig vEth0_0 ?*.*.*.*??netmask *.*.*.*? up
查看用戶態KNI網絡報文收發統計計數:
kill -SIGUSR1 8072
客戶端通過KNI虛擬網絡設備網口運行iperf模擬內核態/用戶態轉發流量:
iperf3 -c *.*.*.*? -t 10
服務端運行iperf接收
iperf3 –s
查看用戶態KNI網絡報文收發統計計數,無丟包統計
查看內核態KNI網絡設備統計計數出現TX dropped
Iperf服務端接收速率在33.4Mb/s, 因KNI虛擬網絡設備丟包導致網絡性能較差。
改進思路
1)DPDK KNI alloc_q mbuf緩存參數調整
通過對問題模擬復現基本確定內核態的RTE_KNI模塊kni_net_tx 在發送網絡報文時因kni_fifo_count(kni->alloc_q) == 0觸發丟包處理邏輯,導致TCP報文重傳間接影響網絡性能。
DPDK KNI用戶態在對alloc_q 填充在初始化階段由rte_kni_alloc調用kni_allocate_mbufs進行初始化填充。運行時由用戶態DPDK應用程序網絡報文發送處理線程調用rte_kni_rx_burst從tx_q獲取待發送網絡報文后回調kni_allocate_mbufs進行alloc_q 回填操作,以確保內核態kni_net_tx在網絡報文發送時存在可用的mbuf進行網絡報文內容復制傳遞至用戶態處理。在kni_allocate_mbufs在極端情況下以申請MAX_MBUF_BURST_NUM數量mbuf回填alloc_q。
在調整MAX_MBUF_BURST_NUM后重新編譯DPDK KNI驗證,如下:
客戶端通過KNI虛擬網絡設備網口運行iperf模擬內核態/用戶態轉發流量:
iperf3 -c *.*.*.*?-t 10
服務端運行iperf接收
iperf3 –s
查看用戶態KNI網絡報文收發統計計數:
kill -SIGUSR1 8072
查看內核態KNI網絡設備統計計數無TX dropped
Iperf服務端接收速率在652Mb/s相對未調整前的33.4Mb/s, iperf吞吐接近20倍的差距。
2) KNI虛擬網絡設備內核網絡報文接收線程、KNI用戶態進程、iperf進程核分離
KNI虛擬網絡設備內核網絡報文接收線程、KNI用戶態進程、iperf進程核分離主要是驗證上述KNI內核態/用戶態網絡報文交換吞吐是否存在改善空間及進程切換對網絡吞吐性能的影響。
通過【pidstate –t –p 進程ID 1】采樣,查看KNI虛擬網絡設備內核網絡報文接收線程、KNI用戶態進程、iperf進程CPU運行狀態及占用率:
KNI虛擬網絡設備內核網絡報文接收線程、KNI用戶態進程、iperf進程均在爭取CPU0處理器資源【注:模擬環境虛擬機CPU0~CPU3,其中CPU1,CPU2己進行核隔離用于用戶態DPDK/KNI收發線程】。
taskset –pc 3 52722將用戶態DPDK/KNI master lcore調整至CPU3,避免其與KNI虛擬網絡設備內核網絡報文接收線程、iperf進程爭取CPU0處理器資源。
客戶端通過KNI虛擬網絡設備網口運行iperf模擬內核態/用戶態轉發流量:
iperf3 -c *.*.*.*? -t 10
服務端運行iperf接收
iperf3 –s
Iperf服務端接收速率在1.23Gb/s。從未調整前的33.4Mb/s至1.23Gb/s或許仍有進一步改進的空間,有待嘗試驗證。
后續
后續改進涉及底層處理邏輯修改及相關功能實現優化,改進思路簡述如下:
1)DPDK KNI虛擬網絡設備引入多隊列多收包線程
DPDK KNI虛擬網絡設備用戶態與內核態網絡報文傳遞采用單FIFO共享隊列實現,針對不同場景可考慮多FIFO共享隊列與多收包線程方式,充分利用多核CPU資源以達到優化改善網絡吞吐性能的目的。
2)DPDK網卡特性透穿至KNI虛擬網絡設備
現網采用DPDK-OVS VHOST-USER與Qemu協商實現網卡特性透傳至虛擬機網卡涉及如:TSO、UFO、GSO、CheckSum Offload等。利用網卡特性釋放虛擬機在處理網絡報文時的CPU處理資源消耗,達到提高虛擬機網絡吞吐性能的目的,并進一步優化DPDK-OVS KNI處理轉發效率。對于DPDK KNI虛擬網絡設備可借鑒該實現原理,提高KNI內核態與用戶態網絡報文交換網絡轉發性能。
3)其它改進措施待研究,歡迎提供參考建議
上述均在虛擬機環境進行模擬驗證,涉及環境變更可能存在偏差,改進思路僅供參考。
參考說明
DPDK之PMD原理
https://cloud.tencent.com/developer/article/1411982
絕對干貨!初學者也能看懂的DPDK解析
https://www.cnblogs.com/qcloud1001/p/9585724.html
DPDK之KNI原理
https://cloud.tencent.com/developer/article/1418603
DPDK內核模塊KNI
http://www.freesion.com/article/148821991/
《DPDK Programmer's Guide Release 19.08》
《DPDK Sample Applications User Guides Release 19.08》
《Flow Bifurcation on Intel Ethernet Controller X710/XL710 --Jingjing Wu; Anjali Singhai》
-End:)
往期精選
1、干貨分享 | 基于RocketMQ構建MQTT集群系列(1)—從MQTT協議和MQTT集群架構說起
2、干貨分享 | 虛擬化性能提升之本地熱遷移
3、干貨分享 | 時序數據庫Graphite在BC-DeepWatch中的設計與使用
總結
以上是生活随笔為你收集整理的lwip协议栈优化_干货分享 | KNI性能优化实践的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: vue进行判断使用class_vue如何
- 下一篇: 里计算两个数的总和_2个公式,在Exce