x**3な人生

基本的にはメモ

複数のDPDKプロセスを動かす

はじめに

'file-prefix'オプションを使うと同一ホストで複数のDPDKプロセスを動かすことが出来ます。ドキュメントをよく読めば書いてあるのですが、忘れやすい&見つけにくいのでメモ。
(1) http://dpdk.org/doc/guides/linux_gsg/build_sample_apps.html
(2) http://dpdk.org/doc/guides/nics/tap.html

オプション一覧を説明しているのが(1)で、(2)がサンプルです。ただし「複数プロセスを動かすためには・・・」という説明ではないですね。

file-prefixオプション

hugepageファイルにprefixを付けるためのオプションです。hugepageファイルに識別子を付けて使い分けるためです。

--file-prefix: The prefix text used for hugepage filenames.

もし単にl2fwdを2つ動かそうとすると、2つめのプロセスはこんな感じで失敗します。

$ sudo ./build/app/l2fwd -c 0x0c -n 4  -- -p 0x0c
...
EAL: FATAL: Cannot get hugepage information.
EAL: Cannot get hugepage information.
EAL: Error - exiting with code: 1
...

一方、それぞれの起動コマンドに'file-prefix'と'-m'を追加すると、エラーは発生しません。'-m'はメモリサイズを制限するためのオプションで、付けないとDPDKは使える分だけのメモリを使おうとするので2つ以上のプロセスを起動できませんので素直に付けます。

$ sudo ./build/app/l2fwd -c 0x03 -n 4 --file-prefix=b -m 1024 -- -p 0x03
$ sudo ./build/app/l2fwd -c 0x0c -n 4 --file-prefix=a  -m 1024 -- -p 0x0c

仮想デバイスを使う

上の(2)ではTun/Tap Poll Mode Driverを使用することで、物理NICを介することなくpktgenの入出力ポートを接続します。DPDKではこれ以外にも様々な仮想デバイスをサポートしています。詳しくは以下のリンクを参照してください。
http://dpdk.org/doc/guides/nics/index.html

仮想デバイスを作成するには'vdev'オプションを用います。以下の例では2つの仮想NIC(vtap0, vtap1)を作成します。

$ sudo app -c ... \
--vdev=net_tap0,iface=vtap0 --vdev=net_tap1,iface=vtap1 \
...

'net_tap'がTun/Tapのための識別子でそのあとに任意の数字を付与します。vhostインターフェースを作成する場合は例えば'net_vhost0'となります。また'iface'は仮想NICに与える名前であり任意の文字列を指定できます。
なお'vdev'オプションは'='ではなくスペースで区切る事も出来ます。

--vdev net_tap0,iface=vtap0 --vdev net_tap1,iface=vtap1 \

アプリケーションを起動したあと、仮想NICが作成されたことを確認できます。

$ ip a
...
10: vtap0: <BROADCAST,MULTICAST> mtu 1500 qdisc multiq state DOWN group default qlen 1000
    link/ether 2a:b6:ea:6e:a5:e8 brd ff:ff:ff:ff:ff:ff
11: vtap1: <BROADCAST,MULTICAST> mtu 1500 qdisc multiq state DOWN group default qlen 1000
    link/ether c2:7c:5b:51:e8:66 brd ff:ff:ff:ff:ff:ff

pktgenを動かす

最後に(2)の例に従ってpktgenを動かしてみます(DPDKは1つしか動かしませんが)。CPUは4cores/8threads以上のものを使用します。
私の環境は以下の通りです。

(2)では高価なマシンを用いているようで、'--socket-mem 512,512'で2つのNUMAノードに512MBずつメモリを割り当てたり、'-b'オプションで物理ポートを明示的に使用しない様にしています。

sudo ./app/app/x86_64-native-linuxapp-gcc/app/pktgen -l 1-5 -n 4        \
 --proc-type auto --log-level 8 --socket-mem 512,512 --file-prefix pg   \
 --vdev=net_tap0 --vdev=net_tap1 -b 05:00.0 -b 05:00.1                  \
 -b 04:00.0 -b 04:00.1 -b 04:00.2 -b 04:00.3                            \
 -b 81:00.0 -b 81:00.1 -b 81:00.2 -b 81:00.3                            \
 -b 82:00.0 -b 83:00.0 -- -T -P -m [2:3].0 -m [4:5].1                   \
 -f themes/black-yellow.theme

私の環境ではNUMAノードが1つのみ、DPDKにNICを割り当てていないので、以下の様になります。環境によりcoremaskやポートの割り当て方が少し異なります。オプションの詳細はマニュアル(http://pktgen-dpdk.readthedocs.io/en/latest/usage_pktgen.html#usage-pktgen)を参照してください。

./app/x86_64-native-linuxapp-gcc/pktgen -c 0xf -n 4 -m 1024 \
--proc-type auto --log-level 7 --file-prefix pktgen \
--vdev net_tap0,iface=vtap0 --vdev net_tap1,iface=vtap1 \
-- -T -P -m [1:2].0 -m [3:4].1 \
-f themes/white-black.theme

pktgenが起動すると、'ip -a'で2つの仮想デバイスが作成されたことを確認できます。別の端末を開いてこれらのデバイスを有効化してIPアドレスを割り当てます。

# vtap0
$ sudo ip link set vtap0 up
$ sudo ip addr add 192.168.0.250/24 dev vtap0
# vtap1
$ sudo ip link set vtap1 up
$ sudo ip addr add 192.168.1.250/24 dev vtap1

再度'ip -a'で有効化されたことを確認します。

...
10: vtap0: <BROADCAST,MULTICAST,PROMISC,UP,LOWER_UP> mtu 1500 qdisc multiq state UNKNOWN group default qlen 1000
    link/ether be:82:c8:2f:da:60 brd ff:ff:ff:ff:ff:ff
    inet 192.168.0.250/24 scope global vtap0
       valid_lft forever preferred_lft forever
    inet6 fe80::bc82:c8ff:fe2f:da60/64 scope link
       valid_lft forever preferred_lft forever
11: vtap1: <BROADCAST,MULTICAST,PROMISC,UP,LOWER_UP> mtu 1500 qdisc multiq state UNKNOWN group default qlen 1000
    link/ether ca:0c:e3:15:75:e5 brd ff:ff:ff:ff:ff:ff
    inet 192.168.1.250/24 scope global vtap1
       valid_lft forever preferred_lft forever
    inet6 fe80::c80c:e3ff:fe15:75e5/64 scope link
       valid_lft forever preferred_lft forever

最後にsocatコマンドで2つの仮想デバイスを接続し、pktgenからパケットを流してみます。まずsocatでvtap0をvtap1を指定して接続します。

sudo socat interface:vtap0 interface:vtap1

次にpktgenの端末から転送を開始します。

Pktgen:/> start 0

するとポート0からポート1へ転送へされていることが確認できます。ただしsocatの転送性能がボトルネックになっているようで、スループットはRx/Tx = 49/552 Mbps程度となっています。

- Ports 0-1 of 2   <Main Page>  Copyright (c) <2010-2017>, Intel Corporation
  Flags:Port      :   P--------------:0   P--------------:1
Link State        :   <UP-10000-FD>       <UP-10000-FD>     ----TotalRate----
Pkts/s Max/Rx :                        15/0            73738/73262             73738/73262
           Max/Tx  :   997888/822720                             0/0         997888/822720
MBits/s Rx/Tx  :                     0/552                           49/0                        49/552
Broadcast        :                             0                                0
...

以上