1引言node
本文檔主要包含INTEL DPDK安裝和配置說明。目的是讓用戶快速的開發和運行程序。文檔描述瞭如何在不深刻細節的狀況下在linux應用開發環境上編譯和運行一個DPDK應用程序。python
1.1文檔總覽linux
如下是DPDK文檔列表,建議按照文檔順序閱讀:ios
注意:以上文檔均可以從DPDK源碼包的同一個位置上分別下載。c++
2系統必備條件shell
本章講的是編譯DPDK源碼包必須具備的環境。編程
注意:若是DPDK要用到intel的89XX系列的網卡平臺上,請先翻閱89xx網卡系列的入門手冊。ubuntu
2.1X86上BIOS先決條件緩存
對於主要的平臺,沒有什麼特別的BIOS設置才能用DPDK的基本功能。然而總有例外的,對於HPET高精度時鐘,能源管理功能,在40g網卡上高性能的小包收發,BIOS設置須要改一下。請看第5章(其它功能的開啓)來獲取須要作哪些更改的信息。網絡
2.2編譯DPDK
注意:測試是在Fedora18上,編譯安裝指令在其它系統上可能不同。在其它linux發行版本上的測試細節請參閱DPDKrelease note。
注意:x86_32應用程序接口只支持最新的debian發行版和13.10以上版本的unbuntu。惟一支持的gcc版本是4.8+。
注意:python須要2.6或者是2.7,在dpdk安裝包中有各類各樣的幫助腳本。
可選的工具:
2.3運行DPDK程序
要運行dpdk程序,在目標機器上須要一些本地化要求。
2.3.1系統軟件
要求:
當前在使用的內核版本能夠經過如下命令獲取:
uname -r
對於在更早的內核版本上使用DPDK須要的補丁細節,能夠看DPDK的Release Notes中的DPDK FAQ。也要注意redhat 6.2和6.3使用的2.6.32內核版本須要用到全部必須得補丁。
c庫版本能夠經過使用ldd -version命令獲取,一個命令使用結果例子以下:
# ldd --version
ldd (GNU libc) 2.14.90
Copyright (C) 2011 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
Written by Roland McGrath and Ulrich Drepper.
在fedora os和其它普通的linux發行版,例如ubuntu,或者是紅帽企業版linux,供應商提供的內核配置能夠跑大部分DPDK應用。
對於其它內核版本,要使用DPDK必須使一下選項能支持:
2.3.2在linux上使用大頁內存
對於要緩存報文的超大內存池的內存分配必須用hugepage,(HUGETLBFS選項在當前容許的內核上必須是支持的,入2.3所說的)使用大頁來分配內存,即便只使用少數頁面,性能也是可以獲得提高的。由於用到更少的頁表緩衝條目(TLBs,高速翻譯緩存),能夠減小翻譯虛擬地址到物理地址的時間,若是不用大頁,那麼用4k的頁較高的TLB丟失率會下降性能。實際上還有一個好處就是不會被交換到磁盤上去。
獲取DPDK使用的大頁內存
分配大頁內存最好是在系統啓動時或者是在啓動後儘早,以便於申請的內存減小碎片,即內存在物理上儘可能是連續的。在內核啓動時獲取大頁內存,須要將一個參數傳遞給內核。
對於2m的頁,僅僅只須要將大頁選項發送給內核。例如,申請1024個2m的頁:
hugepages=1024
對於其它尺寸的大頁內存,例如1g的頁,頁大小必須明確的指定,也能設置系統的默認大頁內存大小。例如申請4g大小的大內存經過4個1g內存頁的形式,須要將如下選項發給內核:
default_hugepagesz=1G hugepagesz=1G hugepages=4
注意:在intel的架構機器上cpu支持的大頁內存的尺寸取決於CPU標識(這些標示能夠經過查看/proc/cpuinfo獲取),若是pse存在,那麼2m頁支持,pdpe1gb存在,則1g頁支持。在IBM power架構的機器上,支持16M和16G的頁。
注意:64位機器,交付時若是平臺支持那天生就支持1g頁了。
對於2個socket的NUMA系統,申請的大頁內存數在系統啓動時通常是從兩個socket上平均分配(假定兩個socket上都有足夠的內存),如上,4g就是一個socket上分出2g內存。
能夠看內核源碼樹的Documentation/kernel-parameter.txt文件獲取更多的內核選項細節。
可選項:
2m的頁也能夠在系統啓動後申請,經過echo 內存頁數目到/sys/devices/目錄下的文件nr_hugepages中。對於單node的系統,使用一下命令獲取1024個2m內存頁:
echo 1024 > /sys/kernel/mm/hugepages/hugepages_2048kb/nr_huge
在numa的機器上,必須精確的在每一個node上指定分配的頁數:
echo 1024 > /sys/devices/system/node/node0/hugepages/hugepages-2048kB/nr_hugepages
echo 1024 > /sys/devices/system/node/node1/hugepages/hugepages-2048kB/nr_hugepages
注意:對於1g的大內存頁是不可能在系統啓動以後申請分配的。
2.3.3 linux環境下Xen Domain0支持
當前的內存管理基於linux內核的大內存頁機制,在Xen虛擬機監視器上,大頁支持無特權帳戶意味着DPDK程序是做爲一個普通用戶態程序運行。
然而,Domain0不支持大頁的,解決這個限制須要,內核模塊rte_dom0_mm加入,使得能夠經過IOCTL和MMAP來分配和映射內存。
在DPDK中打開Xen Dom0模式
默認狀況下,Xen Dom0在DPDK配置文件中是關閉的,要支持Xen Dom0就須要改變配置項CONFIG_RTE_LIBRTE_XEN_DOM0的值爲y,那這個功能在編譯時就是打開的。
此外,CONFIG_RTE_EAL_ALLOW_INV_SOCKET_ID選項也應該設爲y,避免萬一收到錯誤的socket id。
加載DPDK rte_dom0_mm模塊
在Xen Dom0上跑DPDK程序,rte_dom0_mm模塊必須帶着參數rsv_memsize選項加載入運行中的內核中。模塊能夠在DPDK目錄下的子目錄kmod中找到,加載時使用insmod命令,像下面同樣操做(假設咱們當前處於DPDK的根目錄下):
sudo insmod kmod/rte_dom0_mm.ko rsc_memsize=X
X的值能夠大於4096(MB)
配置DPDK使用的內存
在加載完rte_dom0_mm.ko內核模塊後,用戶必須配置DPDK使用的內存大小。經過echo 內存頁數目到/sys/devices/目錄下的內存大小配置文件中。使用以下命令(假設須要2048MB內存):
echo 2048 >/sys/kernel/mm/dom0_mm/memsize-mB/memsize
用戶也能夠檢查當前已經使用了多少內存:
cat /sys/kernel/mm/dom0-mm/memsize-mB/memsize_revd
Xen Domain0不支持NUMA配置,因此–socket-mem選項對它來講是沒用的。
注意:內存大小值不能大於rsv_memsize值
在Xen Domain0上跑DPDK程序
要在Xen Domain0上跑DPDK程序,必須帶上額外的選項–xen-dom0
3編譯DPDK源碼包
3.1安裝DPDK和查看源碼
首先,解壓壓縮包並進入DPDK目錄:
user@host:~$ unzip DPDK-<version>.zip
user@host:~$ cd DPDK-<version>
user@host:~/DPDK-<version>$ ls
app/ config/ drivers/ examples/ lib/ LICENSE.GPL LICENSE.LGPL Makefile mk/ sc
解壓的DPDK目錄下有幾個子目錄:
3.2在目標機器環境下安裝DPDK
安裝DPDK的結果格式以下(就是在當前目錄下回出現一個新目錄,目錄名格式):
ARCH-MACHINE-EXECENV-TOOLCHAIN
我在redhat上的是x86_64-native-linuxapp-gcc(intel的ICC編譯器沒用過...,聽說在intel的機器上,用icc性能高一些)
生成的文件取決於32/64位安裝包和機器上的編譯器。能實現的結果能夠在DPDK/config中看到。defconfig_ prefix不必用到。
注意:提供的配置文件是根據RTE_MACHINE優化的最優選項集,在配置文件中,RTE_MACHINE配置項
被設爲native,意味着編譯軟件會自動匹配編譯的平臺。要看更多關於設置和可能值的詳細星系,請看DPDK Programmers Guide
當使用intel的C++編譯器icc,須要針對64位和32位系統分別執行下面的命令。注意shell腳本更新了PATH環境變量,所以在同一個會話中不須要再執行了。另外,確認編譯的安裝目錄由於目錄可能不同:
source /opt/intel/bin/iccvars.sh intel64
source /opt/intel/bin/iccvars.sh ia32
安裝和編譯,在DPDK根目錄下執行make install T=<target>命令。
例如,用icc編譯64位系統,執行:
make install T=x86_64-native-linuxapp-icc
用gcc編譯32位系統,命令以下:
make install T=i686-native-linuxapp-gcc
用gcc編譯64位系統:
make install T=x86_64*gcc
同時使用gcc和icc編譯64位系統:
make install T=x86_64-*
注意:通配符*表示能夠同時生成多個結果。
準備編譯而不是編譯它,例如,配置被改變了須要在編譯前make一下,使用make config T=<target>命令:make config T=x86_64-native-linuxapp-gcc
提示:任意一個使用到的內核模塊,如igb_uio,rte,必須在目標機器上同一個運行的內核上編譯。若是你的DPDK不是要裝在本機,那麼編譯前須要將RTE_KERNELDIR指向須要安裝的機器的內核版本的一個拷貝。
暈:忘了保存了........,再來一遍
一旦環境配置好了,那麼進入配置的目錄修改代碼並編譯。用戶若是要修改編譯時的配置,那麼修改安裝目錄下的.config文件。它是安裝根目錄下的config目錄中的defconfig文件的一個拷貝。
cd x86_64-native-linuxapp-gcc
vi .config
make
此外,make clean命令能夠清除以前編譯產生的文件,以便從新編譯。
3.3查看安裝完成的DPDK環境目錄
一旦編譯完成,那麼這個DPDK環境目錄包含全部的庫文件,PMD,全部DPDK應用程序須要用到了DPDK頭文件。此外,測試程序和測試PMD程序在對應的build/app目錄下,能夠用來測試。當前的kmod目錄下須要被加載到內核中的木塊。
$ ls x86_64-native-linuxapp-gcc
app build hostapp include kmod lib Makefile
3.4加載內核模塊實現DPDK用戶態IO
跑dpdk程序,對應匹配的uio模塊須要加載到運行的內核中。不少狀況下,linux內核已經有的uio_pci_generic模塊能夠提供uio能力,能夠經過如下命令加載:
sudo modprobe uio_pci_generic
相對這個正式的方式,DPDK還提供kmod子目錄下的igb_uio模塊實現這個功能。加載以下:
sudo modprobe uio
sudoi insmod kmod/igb_uio.ko
注意:對於一些缺少對中斷支持的設備,例如虛擬設備(VF),igb_uio須要用來替換uio_pci_generic。
從DPDK1.7以上版本提供VFIO支持之後,對於使用VFIO的平臺來講,用不用uio就無所謂了。
3.5在家VFIO模塊
運行一個使用VFIO的程序,vfio-pci模塊必須加載:
sudo modprobe vfio-pci
固然要使用VFIO,內核也必須支持才行。自動3.6.0內核版本以來都包含有VFIO模塊且默認都是加載的,可是最好是看看對應使用的linux發行版本的說明文檔以防萬一。
哎,用VFIO,內核和BIOS都必須支持且被配置使用IO virtualization(例如 intel@VT-d(bios裏面的一個選項)
對於非root用戶在跑dpdk程序時,應該賦予相應的權限操做VFIO。能夠經過DPDK腳原本實現(在tools目錄下,名字是setup.sh)
3.6綁定和解綁網卡從內核模塊
自從dpdk1.4版本起,dpdk程序再也不須要自動的解綁全部支持dpdk且內核驅動正在用的網卡。取而代之的是,dpdk程序要用到的網卡必須在程序運行前綁定到uio_pci_generic, igb_uio或者vfio-pci模塊。在linux內核驅動控制下的網卡都會被dpdk的pmd忽略,也不會被程序使用。
提示:dpdk將,也是默認,再也不在啓動時自動從linux內核驅動解綁每一個網卡。任意一個要被dpdk用到的網卡必須在程序運行前先從linux控制下解綁而後綁定到對應的uio_pci_generic, igb_uio or vfio-pci。
綁定網卡到uio_pci_generic, igb_uio or vfio-pci供dpdk使用,以及將網卡返回給linux系統控制,tools子目錄下叫dpdk_nic_bind.py腳本能夠提供該功能。這個腳本能夠列出當前系統內全部網卡的狀態信息,也能夠從不一樣linux驅動綁定或者解綁網卡,包括uio和vfio模塊。下面是一些展現腳本如何使用的例子。對於腳本完整的功能和參數介紹能夠經過使用腳本帶上-help或者是-usage參數。要注意的是使用dpdk_nic_bind.py腳本前須要將uio或者是vfio加載到內核中。
提示:對於使用VFIO的設備會有一些限制。主要歸結於IOMMU分組如何工做。任何虛擬設備就其自己而言均可以使用VFIO,可是對於物理設備要求綁定到VFIO,或者是其中一些綁定到VFIO而另外的不綁定到任何東西上。
若是你的設備是在一個PCI-to-PCI網橋以後,網橋將做爲設備的IOMMU組的一部分。因此當設備在網橋以後工做於VFIO,網橋驅動也必須與網橋PCI設備解綁。
提示:任何用戶可使用腳本查看網卡狀態,解綁和綁定網卡,可是須要root權限。
上面這個xen啊,vfio啊,不是很懂,翻譯的不是很清楚,也可能翻譯錯了,想搞明白仍是看原文吧。
看系統內網卡的狀態:
root@host:DPDK# ./tools/dpdk_nic_bind.py --status
Network devices using DPDK-compatible driver
============================================
0000:82:00.0 '82599EB 10-Gigabit SFI/SFP+ Network Connection' drv=uio_pci_generic unused=ixgbe
0000:82:00.1 '82599EB 10-Gigabit SFI/SFP+ Network Connection' drv=uio_pci_generic unused=ixgbe
Network devices using kernel driver
===================================
0000:04:00.0 'I350 Gigabit Network Connection' if=em0 drv=igb unused=uio_pci_generic *Active*
0000:04:00.1 'I350 Gigabit Network Connection' if=eth1 drv=igb unused=uio_pci_generic
0000:04:00.2 'I350 Gigabit Network Connection' if=eth2 drv=igb unused=uio_pci_generic
0000:04:00.3 'I350 Gigabit Network Connection' if=eth3 drv=igb unused=uio_pci_generic
Other network devices
=====================
<none>
綁定網卡eth1,04:00.1(eth1的pci號),到uio_pci_generic驅動:
root@host:DPDK# ./tools/dpdk_nic_bind.py --bind=uio_pci_generic 04:00.1
或者是用這種方式:
root@host:DPDK# ./tools/dpdk_nic_bind.py --bind=uio_pci_generic eth1
恢復設備82:00.0,綁定到原有的內核驅動:
root@host:DPDK# ./tools/dpdk_nic_bind.py --bind=ixgbe 82:00.0
4編譯和運行範例程序
本章介紹瞭如何編譯和在DPDK環境下運行程序,也指示了範例程序存在哪裏。
注意:本章的部份內容能夠在第6章描述的使用安裝腳本後操做。
4.1編譯範例程序
一旦DPDK環境建立完成(例如x86_64-nativelinuxapp-gcc),包含開發程序須要的全部的DPDK庫和頭文件。
當在linux下編譯一個基於dpdk的程序,下面的兩個參數要被導出:
RTE_SDK:指向DPDK安裝目錄
RTE_TARGET:指向DPDK目的環境目錄,就是編譯dpdk產生的目錄,例如x86_64-nativelinuxapp-gcc
下面是建立helloworld程序的例子,這個是在dpdk linux環境在運行的。這個例子能夠在${RTE_SDK}/examples目錄下找到。
這個目錄包含一個main.c文件。這個文件和dpdk目錄下的庫結合,調用各類初始化dpdk環境的函數,而後加載每一個core的入口函數(分發程序)運行。(這個我本身明白可是翻譯的不清楚,實際就是在dpdk線程上運行一個入口函數,在函數內再根據所在的邏輯核配置跑對應的功能,入rx,tx,fp)。默認編譯產生的可執行二進制文件在build目錄下。
user@host:~/DPDK$ cd examples/helloworld/
user@host:~/DPDK/examples/helloworld$ export RTE_SDK=$HOME/DPDK
user@host:~/DPDK/examples/helloworld$ export RTE_TARGET=x86_64-native-linuxapp-gcc
user@host:~/DPDK/examples/helloworld$ make
CC main.o
LD helloworld
INSTALL-APP helloworld
INSTALL-MAP helloworld.map
user@host:~/DPDK/examples/helloworld$ ls build/app
helloworld helloworld.map
注意:在上面的例子中,helloworld是在dpdk目錄框架下。然而也有可能它再也不dpdk目錄下以保證dpdk的完整。在下面的例子中,helloworl程序就是從dpdk目錄下將helloworld拷貝到一個新的目錄下:
user@host:~$ export RTE_SDK=/home/user/DPDK
user@host:~$ cp -r $(RTE_SDK)/examples/helloworld my_rte_app
user@host:~$ cd my_rte_app/
user@host:~$ export RTE_TARGET=x86_64-native-linuxapp-gcc
user@host:~/my_rte_app$ make
CC main.o
LD helloworld
INSTALL-APP helloworld
INSTALL-MAP helloworld.map
4.2運行一個範例程序
提示:uio驅動和大頁內存必須在程序運行前設置。
提示:每一個程序使用的網卡必須綁定到內核對應的驅動,實際就是咱們家在到內核的dpdk內核模塊,如igb_uio等,如3.5所寫的,這個動做也要在程序運行前執行。
程序是和dpdk目標環境下的環境抽象層庫鏈接,後者提供了每一個dpdk程序通用的一些選項。
下面是須要提供給eal的參數列表:
./rte-app -c COREMASK -n NUM [-b <domain:bus:devid.func>] [--socket-mem=MB,...] [-m MB] [-r NUM]
EAL選項以下:
-n和-c是必須得,其它都是可選項
拷貝可執行程序到目的機器上,以下運行程序(假設每一個socket有4個內存通道,使用0-3核跑該程序):
user@target:~$ ./helloworld -c f -n 4
注意:選項-proc-type和-file-prefix EAL用於跑多個dpdk程序,能夠看《dpdk範例程序使用手冊》中的多進程範例程序一章和dpdk開發手冊獲取更多細節。
4.2.1程序使用的邏輯核
對於dpdk程序,參數coremask是必須有的。每一個bit的掩碼都對應linxu展現的邏輯覈編號。這些邏輯覈編號對應具體得NUMA上的物理核心,不一樣的平臺會不一樣,建議在不一樣的平臺上運行不一樣的例子要考慮選擇使用的core的分佈。
運行dpdk程序初始化EAL時,會將使用的邏輯核和對應的socket打印出來。這些信息也可用經過查看/proc/cpuinfo來獲取,例如,執行 cat /proc/cpuinfo,顯示的physical id代表了每一個核所屬的cpu插槽。這個在咱們弄明白邏輯核和socket的映射關係時頗有用。
注意:更多的邏輯核分佈的拓撲結構視圖能夠經過使用lstopo獲取。在Fedora上,該命令可能安裝了,像這樣運行:
sudo yum install hwloc
./lstopo
提示:在不一樣的主板上佈局不一樣,邏輯核的分佈也會不一樣,咱們須要在選取程序使用的邏輯核以前檢查一下
4.2.2程序使用的大頁內存
在程序運行時,使用分配的數量的大頁內存(就是你分配多少就用多少了,而不是按需去整),這是在沒有指定參數-m和-socket-mem時程序在啓動時自動執行的。
若是程序使用-m和-socket-mem指定具體的內存數超出時,程序就會掛掉。然而,程序要求使用的內存比分配保留的大頁內存數小,特別是用-m選項指定時,程序也可能會掛掉。原有以下:假設如今系統在socket0和socket1上各有1024個2M的大內存頁。若是用戶申請使用128M內存,那64個頁可能不知足如下限制:
-socket-mem選擇用於在特定的socket上申請指定數目的內存頁。使用-socket-mem帶上每一個socket申請的內存數實現。例如,使用-socket-mem=0,512,意味着只在socket1上分配512m內存。一樣的,在4個socket的機器上,從socket0和socket2上分配各1g內存,參數應該是-socket-mem=1024,0,1024.在其它沒有明確指定的cpusocket上不會分配內存,如socket3.若是dpdk在每一個socket上不能申請到足夠的內存,EAL就會初始化失敗。
4.3其它的範例程序
其它的例子程序在${RTE_SDK}/examples目錄下。這些程序的建立和運行與本手冊中其它章節描述的差很少。另外就是看《dpdk範例程序使用手冊》看具體每一個程序的描述信息,編譯和執行時的特殊指令,以及一些代碼的註釋說明。
4.4另外的測試程序
除此以外,有兩個程序在庫建立時也建立了。源文件在DPDK/app下,在測試和測試pmd時調用。能夠在庫建立完成後,在build/app下找到。
測試程序提供了DPDK各類功能的多種測試。
PMD測試程序提供了一些不一樣的包收發測試和像如何使用INTEL® 82599萬兆網卡的FLow Director這類特徵的例子。
5打開其它功能
5.1高精度時鐘功能HPET
5.1.1BIOS支持
要使用HPET那麼平臺的BIOS必須是支持的,不然使用默認的TSC。通常狀況下,開機時按F2能夠進入bios設置。用戶能夠選擇HPET選項。在intel的Crystal Forest平臺的BIOS上,路徑是Advanced -> PCH-IOConfiguration -> High Precision Timer -> (Change fromDisabled to Enabled if necessary).
在系統重啓後,用下面的指令確認是否打開HPET:
# grep hpet /proc/timer_list
若是沒啥返回,HPET在BIOS上確定打開了,每次在重啓後執行上述命令。
5.1.2linux內核支持
dpdk使用平臺的HPET經過映射時間戳計時器到用戶地址空間,諸如此類的,就須要內核的HPET_MMAP選項打開。
提示:在Fedora上,和其它的注入unbuntu發現版上,HPET的內核選項默認是關閉的。在將選項修改後在編譯內核,請經過查看發行版文檔來獲取確切的指令。
5.1.3在DPDK中打開HPET
默認狀況下,DPDK的配置文件中HPET支持選項是禁用的。要使用HPET,那麼CONFIG_RTE_LIBEAL_USE_HPET選項須要設置成y,會在編譯時使用HPET配置。
應用程序要使用rte_get_hpet_cycles() 和rte_get_hpet_hz()這兩個接口,使用HPET最爲rte_timer庫的默認時間源。API rte_eal_hpet_init()須要在程序初始化時調用。這個API的調用確認HPET是可使用,返回錯誤值則說明不能用。例如,若是內核的HPET_MMAP是關閉的。程序能夠決定採起什麼動做,若是HPET在運行時不能用。
注意:程序要使用時間API,可是明確HPET是不能用時,建議使用rte_get_timer_cycles() and rte_get_timer_hz()代替HPET相關的API。這兩個API使用的不是TSC就是HPET,取決於程序是否調用了rte_eal_hpet_init(),作了就看系統是否在運行時支持了。
5.2非root權限下運行dpdk程序
儘管基於dpdk的程序能直接使用到網卡和其它硬件資源,只須要一點小的權限調整便可跑起來而不是做爲root用戶使用。要實現這些,文件的全部者或者是權限要調整以便確保linux用戶帳號可以使用dpdk程序:
注意:在一些安裝的linux上,會默認建立一個大頁的掛載點/dev/hugepages
5.3電量管理和省電功能
要用到dpdk的電源管理功能就要求該平臺的bios支持加強型intel SpeedStep®技術,不然,sys文件/sys/devices/system/cpu/cpu0/cpufreq就不會存在且cpu平率調整的電源管理也不恩可以用。查閱相關的bIOS文檔看如何實現吧
舉例說明,在一些intel平臺上,Enhanced IntelSpeedStep® Technology在BIOS的路徑是:
Advanced->Processor Configuration->Enhanced Intel SpeedStep® Tech
此外,爲了電源管理C3和C6也須要打開。C3和C6路徑以下:Advanced->Processor Configuration->Processor C3 Advanced->ProcessorConfiguration-> Processor C6
5.4使用linux的cpu核心隔離來減小上下文切換的開銷
當DPDK程序線程固定在系統的摸一個核上運行時,linux調度器可能會將其它的任務調度到該核上運行。爲了防止其它負載調度到dpdk使用的核上,須要使用linux內核參數isolcpus來將這些核從linux調度器中隔離開。
例如,若是dpdk程序跑在邏輯核2,4,6上,下面的這個參數須要加到內核選項(就是那個grub文件)中:
isolcpus=2,4,6
5.5 加載kni模塊
要跑dpdk KNI例子程序,須要額外加載一個模塊kni。在dpdk編譯目錄下的kmod中,和加載igb_uio同樣,使用ismod加載:
#insmod kmod/rte_kni.ko
注意:請看DPDK範例使用手冊的KNI示例章節。
5.6經過intel的VT-d虛擬化技術實現IOMMU直接傳輸跑dpdk
要讓linux內核支持intel® VT-d,須要打開如下內核選項:
• IOMMU_SUPPORT
• IOMMU_API
• INTEL_IOMMU
此外,要跑使用intel VT-d技術的dpdk程序,在使用igb_uio驅動時必須帶上iommu=pt參數。這會讓直接內存訪問從新映射。若是內核參數NTEL_IOMMU_DEFAULT_ON沒有設置,那麼內核參數intel_iommu=on也必須使用。這是爲了確保intel IOMMU按照預期初始化。
請注意當強制在igb_uio,vfio-pci驅動上使用iommu=pt,確實能夠同時使用iommu=pt and iommu=on。
5.740g網卡上小包的高性能處理
最新版本的固件鏡像解決了性能加強的問題,固件更新能夠獲取更高的處理性能。跟本地的intel工程師聯繫固件更新。支持固件版本FVL3E的基本驅動將在下一個dpdk版本中整合到一塊兒,當前能用到的版本是4.2.6
5.7.1 打開Extended Tag和設置Max Read Request Size
PCI的extended_tag和max_read_request_size對40g網卡的小包處理性能有巨大的影響。打開extended_tag和設置max_read_request_size爲小尺寸例如128字節會對小包的處理性能提高有恆大的幫助。
CONFIG_RTE_PCI_CONFIG
CONFIG_RTE_PCI_EXTENDED_TAG
CONFIG_RTE_PCI_MAX_READ_REQUEST_SIZE
5.7.2 使用16字節大小的rx描述符
i40e的PMD支持16和32字節大小rx描述符,16個字節能夠在小包處理性能上提供幫助。要使用16字節的須要修改配置文件中的配置項CONFIG_RTE_LIBRTE_I40E_16BYTE_RX_DESC。
5.7.3高性能和包延遲權衡
因爲硬件設計的緣由,每一個包描述符的回寫是須要網卡內部的中斷型號來實現。最小時間間隔的中斷信號能夠經過配置文件的CONFIG_RTE_LIBRTE_I40E_ITR_INTERVAL配置,編譯生效。儘管有默認配置,用戶能夠考慮性能或者是包處理延遲來調整這個參數。
6快速啓動腳本
tools目錄下的setup.sh腳本能夠幫助用戶完成如下任務:
那些步驟完成後,用戶須要編譯本身的程序並鏈接建立的dpdk EAL庫。
6.1腳本的使用
setup.sh腳本能夠暗轉給必定的順序使用,每一步都給說明方便用戶完成想要的任務。下面是每一步驟的簡短說明:
step1:建立dpdk庫
最開始,用戶表虛選擇須要建立的dpdk目標類型和建立庫是用到的編譯選項。
用戶必須先有全部的連接庫,模塊,更新和編譯安裝,如前面章節中介紹的。
step2:安裝環境
用戶配置linux系統環境以支持運行dpdk程序。大頁能夠在numa或非numa系統中創建。任何存在的大頁都會被弄走。要用到的內核模塊也會在這是插入,dpdk用的網卡端口也會綁定到這個模塊。
step3:運行程序
一旦上述步驟完成,用戶可能要運行測試程序。測試程序容許用戶運行一系列的dpdk功能測試。testpmd測試程序則是測試收發包。
step4:檢查系統
這一步提供一些工具查看大頁的狀態信息
step:系統還原
最後一步是將系統還原到初始的狀態。
6.2用例
下面的步驟是展現如何使用setup.sh腳本。腳本的運行須要使用source命令,執行前腳本的一些選項提示用到的值。
提示:setup.sh腳本要運行在root權限下。
user@host:~/rte$ source tools/setup.sh
------------------------------------------------------------------------
RTE_SDK exported as /home/user/rte
------------------------------------------------------------------------
Step 1: Select the DPDK environment to build
------------------------------------------------------------------------
[1] i686-native-linuxapp-gcc
[2] i686-native-linuxapp-icc
[3] ppc_64-power8-linuxapp-gcc
[4] x86_64-ivshmem-linuxapp-gcc
[5] x86_64-ivshmem-linuxapp-icc
[6] x86_64-native-bsdapp-clang
[7] x86_64-native-bsdapp-gcc
[8] x86_64-native-linuxapp-clang
[9] x86_64-native-linuxapp-gcc
[10] x86_64-native-linuxapp-icc
------------------------------------------------------------------------
Step 2: Setup linuxapp environment
------------------------------------------------------------------------
[11] Insert IGB UIO module
[12] Insert VFIO module
[13] Insert KNI module
[14] Setup hugepage mappings for non-NUMA systems
[15] Setup hugepage mappings for NUMA systems
[16] Display current Ethernet device settings
[17] Bind Ethernet device to IGB UIO module
[18] Bind Ethernet device to VFIO module
[19] Setup VFIO permissions
------------------------------------------------------------------------
Step 3: Run test application for linuxapp environment
------------------------------------------------------------------------
[20] Run test application ($RTE_TARGET/app/test)
[21] Run testpmd application in interactive mode ($RTE_TARGET/app/testpmd)
------------------------------------------------------------------------
Step 4: Other tools
------------------------------------------------------------------------
[22] List hugepage info from /proc/meminfo
------------------------------------------------------------------------
Step 5: Uninstall and system cleanup
------------------------------------------------------------------------
[23] Uninstall all targets
[24] Unbind NICs from IGB UIO driver
[25] Remove IGB UIO module
[26] Remove VFIO module
[27] Remove KNI module
[28] Remove hugepage mappings
[29] Exit Script
Option:
下面是建立x86_64-native-linuxapp-gcc dpdk庫的命令使用示範:
Option: 9
================== Installing x86_64-native-linuxapp-gcc
Configuration done
== Build lib
...
Build complete
RTE_TARGET exported as x86_64-native -linuxapp-gcc
下面是加載dpdk uio驅動的示例:(感受不對,25應該按上面說的是卸載驅動啊,2.1沒用過,等後面翻譯開發手冊時再試試吧)
Option: 25
Unloading any existing DPDK UIO module
Loading DPDK UIO module
在numa系統中建立大頁的示範。在每一個node上分配1024個2m內存頁。結果就是程序應該在啓動時帶上-m 4096參數使用這些內存(實際上即便不提供-m選項,dpdk程序也會自動使用這些內存)
注意:若是顯示提示用戶刪除臨時文件,輸入y
Option: 15
Removing currently reserved hugepages
mounting /mnt/huge and removing directory
Input the number of 2MB pages for each node
Example: to have 128MB of hugepages available per node,
enter '64' to reserve 64 * 2MB pages on each node
Number of pages for node0: 1024
Number of pages for node1: 1024
Reserving hugepages
Creating /mnt/huge and mounting as hugetlbfs
下面是加載測試程序在一個核上跑的示例:
Option: 20
Enter hex bitmask of cores to execute test app on
Example: to execute app on cores 0 to 7, enter 0xff
bitmask: 0x01
Launching app
EAL: coremask set to 1
EAL: Detected lcore 0 on socket 0
...
EAL: Master core 0 is ready (tid=1b2ad720)
RTE>>
6.3應用程序
一旦用戶setup.sh腳本運行過,EAL建立了,大頁也搞好了。就能夠建立和運行本身的程序了或者是提供的例子程序。
下面是運行/exaples下的helloword程序示例,使用的是0-3核:
rte@rte-desktop:~/rte/examples$ cd helloworld/rte@rte-desktop:~/rte/examples/helloworld$ makeCC main.oLD helloworldINSTALL-APP helloworldINSTALL-MAP helloworld.maprte@rte-desktop:~/rte/examples/helloworld$ sudo ./build/app/helloworld -c 0xf -n 3[sudo] password for rte:EAL: coremask set to fEAL: Detected lcore 0 as core 0 on socket 0EAL: Detected lcore 1 as core 0 on socket 1EAL: Detected lcore 2 as core 1 on socket 0EAL: Detected lcore 3 as core 1 on socket 1EAL: Setting up hugepage memory...EAL: Ask a virtual area of 0x200000 bytesEAL: Virtual area found at 0x7f0add800000 (size = 0x200000)EAL: Ask a virtual area of 0x3d400000 bytesEAL: Virtual area found at 0x7f0aa0200000 (size = 0x3d400000)EAL: Ask a virtual area of 0x400000 bytesEAL: Virtual area found at 0x7f0a9fc00000 (size = 0x400000)EAL: Ask a virtual area of 0x400000 bytesEAL: Virtual area found at 0x7f0a9f600000 (size = 0x400000)EAL: Ask a virtual area of 0x400000 bytesEAL: Virtual area found at 0x7f0a9f000000 (size = 0x400000)EAL: Ask a virtual area of 0x800000 bytesEAL: Virtual area found at 0x7f0a9e600000 (size = 0x800000)EAL: Ask a virtual area of 0x800000 bytesEAL: Virtual area found at 0x7f0a9dc00000 (size = 0x800000)EAL: Ask a virtual area of 0x400000 bytesEAL: Virtual area found at 0x7f0a9d600000 (size = 0x400000)EAL: Ask a virtual area of 0x400000 bytesEAL: Virtual area found at 0x7f0a9d000000 (size = 0x400000)EAL: Ask a virtual area of 0x400000 bytesEAL: Virtual area found at 0x7f0a9ca00000 (size = 0x400000)EAL: Ask a virtual area of 0x200000 bytesEAL: Virtual area found at 0x7f0a9c600000 (size = 0x200000)EAL: Ask a virtual area of 0x200000 bytesEAL: Virtual area found at 0x7f0a9c200000 (size = 0x200000)EAL: Ask a virtual area of 0x3fc00000 bytesEAL: Virtual area found at 0x7f0a5c400000 (size = 0x3fc00000)EAL: Ask a virtual area of 0x200000 bytesEAL: Virtual area found at 0x7f0a5c000000 (size = 0x200000)EAL: Requesting 1024 pages of size 2MB from socket 0EAL: Requesting 1024 pages of size 2MB from socket 1EAL: Master core 0 is ready (tid=de25b700)EAL: Core 1 is ready (tid=5b7fe700)EAL: Core 3 is ready (tid=5a7fc700)EAL: Core 2 is ready (tid=5affd700)hello from core 1hello from core 2hello from core 3hello from core 0