#2 DPDK 17.02をCentOS 7.3で使う
使用マシン
今回使用するマシンとOSのスペックを下記に記載します。
CPU | Intel(R) Core(TM) i7-4790 CPU @ 3.60GHz |
Memory | DDR3-1600 8GB x4 |
DPDK用NIC | Intel Corporation Ethernet Controller 10-Gigabit X540-AT2 |
OS | CentOS 7.3 |
DPDK | 17.02 |
DKDKのビルド
ビルドに必要なパッケージをインストールしておきます。
$ sudo yum install make gcc kernel-devel
執筆での最新版である17.02をインストールします。適当な作業ディレクトリで次のコマンドを実行します。オプション-O3については、最適化のために使用することを推奨しますが、-g3はデバッグオプションですので、GDBを用いてデバッグする予定がなければ不要です。
$ curl http://fast.dpdk.org/rel/dpdk-17.02.tar.xz | tar xJvf -
(出力結果省略)
$ cd dpdk-17.02
$ sudo make install T=x86_64-native-linuxapp-gcc DESTDIR=/usr/local EXTRA_CFLAGS="-O3 -g3"
セットアップ
前回と同様にHuge Pagesの設定を行います。/etc/default/grubに次の設定を加えます。水色の部分が追加項目です。パラメータの意味は、前回の記事で解説した通りですが、今後、Open vSwitchやKVMなどでも利用を目論んでいるため、多めに1GiBページを確保しました。
GRUB_CMDLINE_LINUX="crashkernel=auto rhgb quiet default_hugepagesz=1G hugepagesz=1G hugepages=16"
その後、設定を有効にします。
# grub2-mkconfig -o /boot/grub2/grub.cfg
また、起動時にカーネルモジュールがロードされるように、/etc/sysconfig/modules/igb_uio.modulesというファイルを作成し、次の内容を記載します。
#!/bin/sh
modprobe uio
insmod /usr/local/lib/modules/3.10.0-514.6.1.el7.x86_64/extra/dpdk/igb_uio.ko
実行属性も付与し、再起動します。
# chmod +x /etc/sysconfig/modules/igb_uio.modules
再起動後、以下のようにロードされていることを確認します。
$ lsmod | grep uio
igb_uio 13224 0
uio 19259 1 igb_uio
また、Huge Pageが確保されていることも確認しておきます。
$ cat /proc/meminfo | grep ^Huge
HugePages_Total: 16
HugePages_Free: 16
HugePages_Rsvd: 0
HugePages_Surp: 0
Hugepagesize: 1048576 kB
対向実験
前回セットアップしたUbuntuベースのマシン1とし、今回セットアップしたマシンをマシン2として、以下の図のように接続にします。X540-AT2は、2つのポートを持っています。それぞれを対向するホストのポートに直結しました。
NICがDPDK用にバインドされていない場合(本ブログの手順通りに作業すると、再起動後はバインドされていない状態です)、それぞれのマシンで次のようにNICをDPDK用にバインドします。--statusコマンドで、NICのリストを表示して、先頭に表示されるPCIバスアドレス(水色で表示)を確認します。
# /usr/local/sbin/dpdk-devbind --status
Network devices using DPDK-compatible driver
============================================
<none>
Network devices using kernel driver
===================================
0000:01:00.0 'Ethernet Controller 10-Gigabit X540-AT2' if=enp1s0f0 drv=ixgbe unused=igb_uio
0000:01:00.1 'Ethernet Controller 10-Gigabit X540-AT2' if=enp1s0f1 drv=ixgbe unused=igb_uio
0000:03:00.0 'RTL8111/8168/8411 PCI Express Gigabit Ethernet Controller' if=enp3s0 drv=r8169 unused=igb_uio *Active*
(以下省略)
これらを次のコマンドでバインドします。引数の最後のアドレスには以下のように、複数のNICを列挙することができます。
# /usr/local/sbin/dpdk-devbind -b igb_uio 0000:01:00.0 0000:01:00.1
再度、バインド状態を確認すると、2つのNICがNetwork devices using DPDK-compatible driverに移動していることがわかります。
# /usr/local/sbin/dpdk-devbind --status
Network devices using DPDK-compatible driver
============================================
0000:01:00.0 'Ethernet Controller 10-Gigabit X540-AT2' drv=igb_uio unused=ixgbe
0000:01:00.1 'Ethernet Controller 10-Gigabit X540-AT2' drv=igb_uio unused=ixgbe
Network devices using kernel driver
===================================
0000:03:00.0 'RTL8111/8168/8411 PCI Express Gigabit Ethernet Controller' if=enp3s0 drv=r8169 unused=igb_uio *Active*
(以下省略)
パケット転送
パケットの転送は、最初にホスト1で、パケットを生成してホスト2に送ります。以降は、以下の図のように2つのホスト間で循環的に転送が継続されます。
まず、ホスト2で次のようにtestpmd(DPDK標準のパケット転送ツール)を起動し、startコマンドを実行します。startコマンドはパケット転送機能を有効にします。
# testpmd -- -i
(省略)
Port 0 Link Up - speed 10000 Mbps - full-duplex
Port 1 Link Up - speed 10000 Mbps - full-duplex
Done
testpmd> start
io packet forwarding - ports=2 - cores=1 - streams=2 - NUMA support disabled, MP over anonymous pages disabled
Logical Core 1 (socket 0) forwards packets on 2 streams:
RX P=0/Q=0 (socket 0) -> TX P=1/Q=0 (socket 0) peer=02:00:00:00:00:01
RX P=1/Q=0 (socket 0) -> TX P=0/Q=0 (socket 0) peer=02:00:00:00:00:00
(省略)
上記の表示されたメッセージでの着目すべきところを水色にしています。水色で表示したcore=1は転送を1つのCPUコア(PMDスレッド)で行うという意味です。RX P=0/Q=0 -> TX P=1/Q=0は、Port 0のQueue 0に到達したパケットをPoart 1のQueue 0に転送するという意味です。RX P=1/Q=0 -> TX P=0/Q=0も同様です。Queueは、パケット入出力用のバッファですが、1つのポートに対して複数Queueを作成して性能を向上することができます。まずは、デフォルトのNICのポート1つにQueue 1つの構成で進めます。したがって、1つのPMDスレッドが2つのQueueをポーリングしていることになります。
続いて、ホスト1でもtestpmdを起動します。start tx_firstと入力します。tx_firstは、最初にパケット生成して送信するためのオプションです。10秒経過したあと、stopと入力します。
# testpmd -- -i
(省略)
testpmd> start tx_first
(省略)
10秒経過後
testpmd> stop
Telling cores to stop...
Waiting for lcores to finish...
testpmd> stop
Telling cores to stop...
Waiting for lcores to finish...
---------------------- Forward statistics for port 0 ----------------------
RX-packets: 10308311 RX-dropped: 0 RX-total: 10308311
TX-packets: 10298580 TX-dropped: 0 TX-total: 10298580
----------------------------------------------------------------------------
---------------------- Forward statistics for port 1 ----------------------
RX-packets: 10298580 RX-dropped: 0 RX-total: 10298580
TX-packets: 10308311 TX-dropped: 0 TX-total: 10308311
----------------------------------------------------------------------------
(以下省略)
また、ホスト2でもstopを実行します。
testpmd> stop
(以下省略)
上記のように筆者の環境では10秒で上記の送受信パケット数でしたので、おおよそ1.0Mpps (packets/sec.)の転送性能でした。testpmdは64バイトのパケットを送信するので、データ転送レートに換算すると約0.5Gbpsです。10Gbit NICのN/W帯域をフルに使っているわけではないことが分かります。これには、いくつか理由がありますが、次回以降で見ていきましょう。
次回は、PMDスレッドの数やQueueを増やすことで転送性能の向上を行います。