CentOS8によるvDPAを使用したScalable Function(以下、SF)の設定方法について記載しました。
SFはLinux KernelのSub Functionを使用して実装された技術となっており、類似の技術としてIntel Scalable IOVがあります。*1
本ブログでは、vhost vDPAモジュールを使用したVMにおいて、SR-IOV VFの代わりに、SFを使用したVM間通信の設定方法について記載していきます。
SFの詳細はHome · Mellanox/scalablefunctions Wiki · GitHubを参照してください。
以下は関連記事の一覧となります。
1.構成
1-1.環境
IA server : ProLiant DL360p Gen8 or DL360 Gen9 System ROM : P71 01/22/2018 NIC : Mellanox ConnectX-6 Dx (MCX623106AS-CDAT) OS : CentOS8.4(2105) Kernel : 5.13.4-1.el8.elrepo.x86_64 Installed Environment Groups : @^graphical-server-environment @container-management @development @virtualization-client @virtualization-hypervisor @virtualization-tools Mellanox OFED : v5.4-1.0.3.0 qemu-kvm : v6.1.0-rc0 ovs : v2.14.1 libvirtd : v7.5.0
1-2.全体の流れ
事前準備
Kernelのビルド
関連アプリケーションのビルド
switchdev modeの有効化
ovsとVMの設定
動作確認
2.事前準備
特に記載しませんが、SELinux無効化、FW無効化、NTP時刻同期設定は事前に行っています。
2-1.Mellanoxドライバ(OFED)のインストール
isoファイルはMellanoxのサイトからDLしてください。Mellanox Download Site
DLしたisoファイルは、/root/tmp/に保存してください。
以下のコマンドにて、Mellanoxドライバをインストールしますが、ovs v2.14.1も同時にインストールされます。
dnf -y install tcl tk unbound && \ mount -t iso9660 -o loop /root/tmp/MLNX_OFED_LINUX-5.4-1.0.3.0-rhel8.4-x86_64.iso /mnt && \ /mnt/mlnxofedinstall --upstream-libs --dpdk --ovs-dpdk --with-mft --with-mstflint
インストールが完了したら、再起動してください。
reboot
2-2.Scalable Functionの準備
mstツールを使用して、H/WレベルでNICの設定を実施します。
始めにlshwコマンドでNICのbsf番号(0000:07:00.0, 0000:07:00.1)を確認します。
lshw -businfo -c network mst start mlxconfig -d 0000:07:00.0 set PF_BAR2_ENABLE=0 PER_PF_NUM_SF=1 PF_TOTAL_SF=236 PF_SF_BAR_SIZE=10 SRIOV_EN=1 NUM_OF_VFS=16 NUM_PF_MSIX_VALID=0 PF_NUM_PF_MSIX=1024 mlxconfig -d 0000:07:00.1 set PF_BAR2_ENABLE=0 PER_PF_NUM_SF=1 PF_TOTAL_SF=236 PF_SF_BAR_SIZE=10 SRIOV_EN=1 NUM_OF_VFS=16 NUM_PF_MSIX_VALID=0 PF_NUM_PF_MSIX=1024 [root@c84g155 ~]# lshw -businfo -c network Bus info Device Class Description ======================================================= pci@0000:04:00.0 ens1f0 network 82599ES 10-Gigabit SFI/SFP+ Network Connection pci@0000:04:00.1 ens1f1 network 82599ES 10-Gigabit SFI/SFP+ Network Connection pci@0000:03:00.0 eno1 network NetXtreme BCM5719 Gigabit Ethernet PCIe pci@0000:03:00.1 eno2 network NetXtreme BCM5719 Gigabit Ethernet PCIe pci@0000:03:00.2 eno3 network NetXtreme BCM5719 Gigabit Ethernet PCIe pci@0000:03:00.3 eno4 network NetXtreme BCM5719 Gigabit Ethernet PCIe pci@0000:07:00.0 ens2f0 network MT2892 Family [ConnectX-6 Dx] pci@0000:07:00.1 ens2f1 network MT2892 Family [ConnectX-6 Dx] [root@c84g155 ~]# mst start Starting MST (Mellanox Software Tools) driver set Loading MST PCI module - Success Loading MST PCI configuration module - Success Create devices Unloading MST PCI module (unused) - Success [root@c84g155 ~]# mlxconfig -d 0000:07:00.0 set PF_BAR2_ENABLE=0 PER_PF_NUM_SF=1 PF_TOTAL_SF=236 PF_SF_BAR_SIZE=10 SRIOV_EN=1 NUM_OF_VFS=16 NUM_PF_MSIX_VALID=0 PF_NUM_PF_MSIX=1024 Device #1: ---------- Device type: ConnectX6DX Name: MCX623106AS-CDA_Ax Description: ConnectX-6 Dx EN adapter card; 100GbE; Dual-port QSFP56; PCIe 4.0 x16; Secure Boot; No Crypto Device: 0000:07:00.0 Configurations: Next Boot New PF_BAR2_ENABLE False(0) False(0) PER_PF_NUM_SF True(1) True(1) PF_TOTAL_SF 236 236 PF_SF_BAR_SIZE 10 10 SRIOV_EN True(1) True(1) NUM_OF_VFS 16 16 NUM_PF_MSIX_VALID False(0) False(0) PF_NUM_PF_MSIX 1024 1024 Apply new Configuration? (y/n) [n] : y Applying... Done! -I- Please reboot machine to load new configurations. 0000:07:00.1 ens2f1も同様に設定してください。
補足
SRIOV_EN=1 と NUM_OF_VFS=16でSR-IOVの設定を実施していますが、今回は使用しませんので、設定に含めなくても問題ありません。
設定が完了したら、再起動してください。
reboot
3.Kernelビルド
Kernel5.13以上が必須となります。加えて、SFモジュールなどの有効化が必要となるため、ソースからビルドします。
3-1.elrepoのインストール
rpm --import https://www.elrepo.org/RPM-GPG-KEY-elrepo.org && \ dnf -y install https://www.elrepo.org/elrepo-release-8.el8.elrepo.noarch.rpm
3-2.epelなどのインストール
dnf -y install epel-release && \ dnf -y install http://repo.okay.com.mx/centos/8/x86_64/release/okay-release-1-5.el8.noarch.rpm && \ dnf -y --enablerepo=powertools install dwarves libbpf-devel
3-3.Kernel nosrc.rpmのインストールとソースのダウンロード
cd /usr/src && \ wget https://elrepo.org/linux/kernel/el8/SRPMS/kernel-ml-5.13.4-1.el8.elrepo.nosrc.rpm && \ dnf -y localinstall kernel-ml-5.13.4-1.el8.elrepo.nosrc.rpm wget https://cdn.kernel.org/pub/linux/kernel/v5.x/linux-5.13.4.tar.xz && \ cp linux-5.13.4.tar.xz /root/rpmbuild/SOURCES && \ rpmbuild -bp /root/rpmbuild/SPECS/kernel-ml-5.13.spec
3-4.builddepの実施
dnf builddep -y kernel
3-5.makeの準備
cd /root/rpmbuild/BUILD/kernel-ml-5.13.4/linux-5.13.4-1.el8.x86_64/ && \ make mrproper && \ make oldconfig
make oldconfig コマンドでは、各モジュールの有効化/無効化/モジュール化のプロンプトが表示されますが、膨大な量の項目が出力されますので、Enterキーを押し続けてください。
補足
make oldconfig コマンドを実行した後、cp /boot/config-4.18.0-305.3.1.el8.x86_64 .config が最初に実行されます。
そして、Kernel4.18とKernel5.13で設定項目が同じ場合にはKernel4.18の設定が引き継がれます。
さらに、Kernel5.13で新規追加された項目はDefault設定となっているため、この後、make menuconfig コマンドで個別に設定していきます。
3-6.make menuconfigによる設定
make menuconfig
上記コマンドを実行すると以下の画面が表示されます。
以下のモジュールを有効化/モジュール化します。
MLX5_ESWITCH MLX5_SF VDPA
以下の項目が[=y]もしくは[=m]となっていることを確認の上、[=n]になっていた場合は、[=m]に設定を変更してください。*4
設定項目はPromptに記載の文字列が該当します。(e.g. Mellanox Technologies MLX5 SRIOV E-Switch support)
設定項目の階層はLocationに従ってください。(e.g. -> Device Drivers -> Network device support)
MLX5 │ Symbol: MLX5_ESWITCH [=y] │ │ Type : bool │ │ Defined at drivers/net/ethernet/mellanox/mlx5/core/Kconfig:71 │ │ Prompt: Mellanox Technologies MLX5 SRIOV E-Switch support │ │ Depends on: NETDEVICES [=y] && ETHERNET [=y] && NET_VENDOR_MELLANOX [=y] && MLX5_CORE_EN [=y] && NET_SWITCHDEV [=y] │ │ Location: │ │ -> Device Drivers │ │ -> Network device support (NETDEVICES [=y]) │ │ -> Ethernet driver support (ETHERNET [=y]) │ │ -> Mellanox devices (NET_VENDOR_MELLANOX [=y]) │ │ (9) -> Mellanox 5th generation network adapters (ConnectX series) Ethernet support (MLX5_CORE_EN [=y]) │ │ Symbol: MLX5_SF [=y] │ │ Type : bool │ │ Defined at drivers/net/ethernet/mellanox/mlx5/core/Kconfig:217 │ │ Prompt: Mellanox Technologies subfunction device support using auxiliary device │ │ Depends on: NETDEVICES [=y] && ETHERNET [=y] && NET_VENDOR_MELLANOX [=y] && MLX5_CORE [=m] && MLX5_CORE_EN [=y] │ │ Location: │ │ -> Device Drivers │ │ -> Network device support (NETDEVICES [=y]) │ │ -> Ethernet driver support (ETHERNET [=y]) │ │ (1) -> Mellanox devices (NET_VENDOR_MELLANOX [=y]) │ │ │ │ │ │ Symbol: MLX5_SF_MANAGER [=y] │ │ Type : bool │ │ Defined at drivers/net/ethernet/mellanox/mlx5/core/Kconfig:226 │ │ Depends on: NETDEVICES [=y] && ETHERNET [=y] && NET_VENDOR_MELLANOX [=y] && MLX5_SF [=y] && MLX5_ESWITCH [=y] │ VDPA │ Symbol: VDPA [=m] │ │ Type : tristate │ │ Defined at drivers/vdpa/Kconfig:2 │ │ Prompt: vDPA drivers │ │ Depends on: NET [=y] │ │ Location: │ │ (1) -> Device Drivers │ │ │ │ │ │ Symbol: MLX5_VDPA [=y] │ │ Type : bool │ │ Defined at drivers/vdpa/Kconfig:45 │ │ Depends on: VDPA [=m] │ │ Selects: VHOST_IOTLB [=m] │ │ Selected by [m]: │ │ - MLX5_VDPA_NET [=m] && VDPA [=m] && MLX5_CORE [=m] │ │ │ │ │ │ Symbol: MLX5_VDPA_NET [=m] │ │ Type : tristate │ │ Defined at drivers/vdpa/Kconfig:53 │ │ Prompt: vDPA driver for ConnectX devices │ │ Depends on: VDPA [=m] && MLX5_CORE [=m] │ │ Location: │ │ -> Device Drivers │ │ (2) -> vDPA drivers (VDPA [=m]) │ │ Selects: MLX5_VDPA [=y] │ │ │ │ │ │ Symbol: VHOST_VDPA [=m] │ │ Type : tristate │ │ Defined at drivers/vhost/Kconfig:64 │ │ Prompt: Vhost driver for vDPA-based backend │ │ Depends on: VHOST_MENU [=y] && EVENTFD [=y] && VDPA [=m] │ │ Location: │ │ -> Device Drivers │ │ (6) -> VHOST drivers (VHOST_MENU [=y]) │ │ Selects: VHOST [=m] && IRQ_BYPASS_MANAGER [=m] │ │ │ │ │ │ Symbol: VP_VDPA [=m] │ │ Type : tristate │ │ Defined at drivers/vdpa/Kconfig:63 │ │ Prompt: Virtio PCI bridge vDPA driver │ │ Depends on: VDPA [=m] && PCI_MSI [=y] │ │ Location: │ │ -> Device Drivers │ │ (8) -> vDPA drivers (VDPA [=m]) │ │ Selects: VIRTIO_PCI_LIB [=y] │
設定が一通り完了したら、保存してください。
設定ファイルは以下のパスに保存されます。
/root/rpmbuild/BUILD/kernel-ml-5.13.4/linux-5.13.4-1.el8.x86_64/.config
3-7.configファイルの修正
sed -i -e 's/certs\/rhel.pem//g' /root/rpmbuild/BUILD/kernel-ml-5.13.4/linux-5.13.4-1.el8.x86_64/.config
上記コマンドは、.configファイルを以下のように修正しています。これを実行しないとmakeに失敗します。*5
Before CONFIG_SYSTEM_TRUSTED_KEYS="certs/rhel.pem" After CONFIG_SYSTEM_TRUSTED_KEYS=""
3-8.Kernelのビルド
LOCALVERSION=-SFvDPA make -j32 && \ make modules_install && \ make install
補足
-SFvDPA | OS起動時に表示される文字列です。e.g. CentOS Linux (5.13.4-1.el8.x86_64-SFvDPA) |
-j32 | 並列処理させるJob数を指定することによりmakeを高速化します。目安としてはCPUコア数の2倍程度 |
3-9.起動Kernelの設定
grubby --default-index grubby --default-kernel [root@c84g155 linux-5.13.4-1.el8.x86_64]# grubby --default-index 0 [root@c84g155 linux-5.13.4-1.el8.x86_64]# grubby --default-kernel /boot/vmlinuz-5.13.4-1.el8.x86_64-SFvDPA
本来であれば、上記の設定になっているはずです。
もし、異なっていた場合には、以下のコマンドで確認の上、新Kernelで起動するように設定してください。
Index番号の確認 grubby --info=ALL [root@c84g155 linux-5.13.4-1.el8.x86_64]# grubby --info=ALL index=0 kernel="/boot/vmlinuz-5.13.4-1.el8.x86_64-SFvDPA" args="ro crashkernel=auto resume=/dev/mapper/cl-swap rd.lvm.lv=cl/root rd.lvm.lv=cl/swap rhgb quiet $tuned_params" root="/dev/mapper/cl-root" initrd="/boot/initramfs-5.13.4-1.el8.x86_64-SFvDPA.img $tuned_initrd" title="CentOS Linux (5.13.4-1.el8.x86_64-SFvDPA) 8" id="f71e06bfa3c74d2c9b19e85ce38b4b57-5.13.4-1.el8.x86_64-SFvDPA" index=1 kernel="/boot/vmlinuz-4.18.0-305.3.1.el8.x86_64" args="ro crashkernel=auto resume=/dev/mapper/cl-swap rd.lvm.lv=cl/root rd.lvm.lv=cl/swap rhgb quiet $tuned_params" root="/dev/mapper/cl-root" initrd="/boot/initramfs-4.18.0-305.3.1.el8.x86_64.img $tuned_initrd" title="CentOS Linux (4.18.0-305.3.1.el8.x86_64) 8" id="f71e06bfa3c74d2c9b19e85ce38b4b57-4.18.0-305.3.1.el8.x86_64" index=2 kernel="/boot/vmlinuz-0-rescue-f71e06bfa3c74d2c9b19e85ce38b4b57" args="ro crashkernel=auto resume=/dev/mapper/cl-swap rd.lvm.lv=cl/root rd.lvm.lv=cl/swap rhgb quiet" root="/dev/mapper/cl-root" initrd="/boot/initramfs-0-rescue-f71e06bfa3c74d2c9b19e85ce38b4b57.img" title="CentOS Linux (0-rescue-f71e06bfa3c74d2c9b19e85ce38b4b57) 8" id="f71e06bfa3c74d2c9b19e85ce38b4b57-0-rescue" 起動Kernelの設定 grubby --set-default-index=0 [root@c84g155 linux-5.13.4-1.el8.x86_64]# grubby --set-default-index=0 The default is /boot/loader/entries/f71e06bfa3c74d2c9b19e85ce38b4b57-5.13.4-1.el8.x86_64-SFvDPA.conf with index 0 and kernel /boot/vmlinuz-5.13.4-1.el8.x86_64-SFvDPA
ビルドしたKernelで起動させるため、再起動します。
reboot
4.関連アプリケーションのビルド
qemu, libvirtd, iproute2-nextをビルドしてインストールします。
4-1.各種リポジトリの有効化
sed -i -e 's/enabled=0/enabled=1/g' /etc/yum.repos.d/CentOS-Linux-PowerTools.repo && \ dnf -y install https://pkgs.dyn.su/el8/base/x86_64/raven-release-1.0-1.el8.noarch.rpm && \ sed -i -e 's/enabled=0/enabled=1/g' /etc/yum.repos.d/raven.repo
4-2.必要なパッケージのインストール
dnf -y install cmake gcc libnl3-devel libudev-devel make numactl numactl-devel \ pkgconfig valgrind-devel pandoc libibverbs libmlx5 libmnl-devel meson ninja-build \ glibc-utils glib2 glib2-devel pixman pixman-devel zlib zlib-devel rpcgen python3-docutils \ gnutls gnutls-devel libxml2-devel yajl-devel libtirpc-devel libudev-devel libpciaccess-devel \ usbredir-devel spice-server-devel && \ wget https://cbs.centos.org/kojifiles/packages/pyelftools/0.26/1.el8/noarch/python3-pyelftools-0.26-1.el8.noarch.rpm && \ dnf -y localinstall python3-pyelftools-0.26-1.el8.noarch.rpm && \ dnf -y install https://rpmfind.net/linux/centos/8-stream/PowerTools/x86_64/os/Packages/meson-0.55.3-3.el8.noarch.rpm
4-3.qemuのビルド
cd /usr/src && \ git clone https://github.com/qemu/qemu.git && \ cd qemu/ && \ git checkout v6.1.0-rc0 && \ mkdir build && \ cd build/ && \ ../configure --enable-vhost-vdpa --target-list=x86_64-softmmu && \ make -j && \ make install
インストール後のVersion確認
/usr/local/bin/qemu-system-x86_64 --version [root@c84g155 ~]# /usr/local/bin/qemu-system-x86_64 --version QEMU emulator version 6.0.90 (v6.1.0-rc0) Copyright (c) 2003-2021 Fabrice Bellard and the QEMU Project developers
4-4.libvirtdのビルド
cd /usr/src && \ git clone https://github.com/libvirt/libvirt.git && \ cd libvirt/ && \ git checkout v7.5.0 && \ meson build && \ ninja -C build && \ ninja -C build install
インストール後のVersion確認
libvirtd -V [root@c84g155 ~]# libvirtd -V libvirtd (libvirt) 7.5.0
4-5.qemu実行Pathの変更
mv /usr/libexec/qemu-kvm /usr/libexec/qemu-kvm.org ln -s /usr/local/bin/qemu-system-x86_64 /usr/libexec/qemu-kvm
4-6.qemu実行ユーザの変更
vi /usr/local/etc/libvirt/qemu.conf user = "root" #comment out group = "root" #comment out
4-7.libvirt-sockの設定変更
青文字箇所を追記
vi /etc/rc.local
touch /var/lock/subsys/local
sleep 1
mkdir /var/run/libvirt
ln -s /var/local/run/libvirt/libvirt-sock /var/run/libvirt/libvirt-sock
sleep 1
exit 0
実行権限付与
chmod +x /etc/rc.d/rc.local
4-8.iproute2-nextのビルド
cd /usr/src && \ git clone git://git.kernel.org/pub/scm/network/iproute2/iproute2-next.git iproute2-next && \ cd iproute2-next && \ ./configure --include_dir /usr && \ make -j all && \ make install
インストール後のVersion確認
devlink -V [root@c84g155 ~]# devlink -V devlink utility, iproute2-5.13.0
ここで、一旦再起動しておきます。
reboot
5.switchdev modeの有効化
5-1.動作モードの変更
devlink dev eswitch set pci/0000:07:00.0 mode switchdev &&¥ devlink dev eswitch set pci/0000:07:00.1 mode switchdev
補足
0000:07:00.0 は、lshwコマンドで確認したNICのbsf番号です。
5-2.動作モードの確認
注目すべき箇所を赤文字で記載します。
devlink dev eswitch show pci/0000:07:00.0 devlink dev eswitch show pci/0000:07:00.1 devlink port show [root@c84g155 ~]# devlink dev eswitch show pci/0000:07:00.0 pci/0000:07:00.0: mode switchdev inline-mode none encap-mode basic [root@c84g155 ~]# devlink dev eswitch show pci/0000:07:00.1 pci/0000:07:00.1: mode switchdev inline-mode none encap-mode basic [root@c84g155 ~]# devlink port show pci/0000:07:00.0/65535: type eth netdev ens2f0 flavour physical port 0 splittable false pci/0000:07:00.1/131071: type eth netdev ens2f1 flavour physical port 1 splittable false
5-3.Scalable Functionの設定
devlink port add pci/0000:07:00.0 flavour pcisf pfnum 0 sfnum 11 devlink port function set pci/0000:07:00.0/32768 hw_addr CA:FE:C0:FF:EE:11 devlink port function set pci/0000:07:00.0/32768 state active devlink port add pci/0000:07:00.1 flavour pcisf pfnum 1 sfnum 12 devlink port function set pci/0000:07:00.1/98304 hw_addr CA:FE:C0:FF:EE:12 devlink port function set pci/0000:07:00.1/98304 state active [root@c84g155 ~]# devlink port add pci/0000:07:00.0 flavour pcisf pfnum 0 sfnum 11 pci/0000:07:00.0/32768: type eth netdev eth0 flavour pcisf controller 0 pfnum 0 sfnum 11 splittable false function: hw_addr 00:00:00:00:00:00 state inactive opstate detached [root@c84g155 ~]# devlink port function set pci/0000:07:00.0/32768 hw_addr CA:FE:C0:FF:EE:11 [root@c84g155 ~]# devlink port function set pci/0000:07:00.0/32768 state active [root@c84g155 ~]# devlink port add pci/0000:07:00.1 flavour pcisf pfnum 1 sfnum 12 pci/0000:07:00.1/98304: type eth netdev eth0 flavour pcisf controller 0 pfnum 1 sfnum 12 splittable false function: hw_addr 00:00:00:00:00:00 state inactive opstate detached [root@c84g155 ~]# devlink port function set pci/0000:07:00.1/98304 hw_addr CA:FE:C0:FF:EE:12 [root@c84g155 ~]# devlink port function set pci/0000:07:00.1/98304 state active
5-4.Scalable Functionの確認
注目すべき箇所を赤文字で記載します。
lshw -businfo -c network devlink port show en7f0pf0sf11 -jp devlink port show en7f1pf1sf12 -jp [root@c84g155 ~]# lshw -businfo -c network Bus info Device Class Description ========================================================== pci@0000:04:00.0 ens1f0 network 82599ES 10-Gigabit SFI/SFP+ Network Connection pci@0000:04:00.1 ens1f1 network 82599ES 10-Gigabit SFI/SFP+ Network Connection pci@0000:03:00.0 eno1 network NetXtreme BCM5719 Gigabit Ethernet PCIe pci@0000:03:00.1 eno2 network NetXtreme BCM5719 Gigabit Ethernet PCIe pci@0000:03:00.2 eno3 network NetXtreme BCM5719 Gigabit Ethernet PCIe pci@0000:03:00.3 eno4 network NetXtreme BCM5719 Gigabit Ethernet PCIe pci@0000:07:00.0 ens2f0 network MT2892 Family [ConnectX-6 Dx] pci@0000:07:00.1 ens2f1 network MT2892 Family [ConnectX-6 Dx] pci@0000:07:00.0 en7f0pf0sf11 network Ethernet interface pci@0000:07:00.1 en7f1pf1sf12 network Ethernet interface [root@c84g155 ~]# devlink port show en7f0pf0sf11 -jp { "port": { "pci/0000:07:00.0/32768": { "type": "eth", "netdev": "en7f0pf0sf11", "flavour": "pcisf", "controller": 0, "pfnum": 0, "sfnum": 11, "splittable": false, "function": { "hw_addr": "ca:fe:c0:ff:ee:11", "state": "active", "opstate": "attached" } } } } [root@c84g155 ~]# devlink port show en7f1pf1sf12 -jp { "port": { "pci/0000:07:00.1/98304": { "type": "eth", "netdev": "en7f1pf1sf12", "flavour": "pcisf", "controller": 0, "pfnum": 1, "sfnum": 12, "splittable": false, "function": { "hw_addr": "ca:fe:c0:ff:ee:12", "state": "active", "opstate": "attached" } } } }
補足
現段階でSFの設定は完了しましたが、SFをvdpaデバイスにバインドしていません。
このため、次のセクションでは、vdpaモジュールの有効化、既存ドライバのアンバインド、vdpaデバイスの追加を実施します。
これがSR-IOV VFとは大きく異なるポイントになります。
6.ovs-dpdkとVMの設定
6-1.全体の流れ ~概要~
以下のfig.1に記載されている(1)-(9)の順に設定していきます。
fig.1
6-2.全体の流れ ~コマンドのみ~
以下のコマンドを投入していきます。
詳細な解説は後述しますが、解説が不要な方はコマンドだけを実行してください。
1.vdpaモジュールの有効化とvdpaデバイスの追加 (1) modprobe vdpa modprobe vhost_vdpa echo mlx5_core.rdma.2 > /sys/bus/auxiliary/devices/mlx5_core.sf.2/mlx5_core.rdma.2/driver/unbind echo mlx5_core.eth.2 > /sys/bus/auxiliary/devices/mlx5_core.sf.2/mlx5_core.eth.2/driver/unbind echo mlx5_core.rdma.3 > /sys/bus/auxiliary/devices/mlx5_core.sf.3/mlx5_core.rdma.3/driver/unbind echo mlx5_core.eth.3 > /sys/bus/auxiliary/devices/mlx5_core.sf.3/mlx5_core.eth.3/driver/unbind vdpa dev add name vdpa0 mgmtdev auxiliary/mlx5_core.sf.2 vdpa dev add name vdpa1 mgmtdev auxiliary/mlx5_core.sf.3 2.ovsの初期設定 systemctl start openvswitch ovs-vsctl set Open_vSwitch . other_config:hw-offload=true other_config:tc-policy=none systemctl restart openvswitch 3.br30-ovsの設定 (2) ovs-vsctl add-br br30-ovs (3) ovs-vsctl add-port br30-ovs ens2f0 (4) ovs-vsctl add-port br30-ovs en7f0pf0sf11 4.br31-ovsの設定 (5) ovs-vsctl add-br br31-ovs (6) ovs-vsctl add-port br31-ovs ens2f1 (7) ovs-vsctl add-port br31-ovs en7f1pf1sf12 5.仮想マシンc77g153の設定 (8) virsh edit c77g153 <interface type='vdpa'> <source dev='/dev/vhost-vdpa-0'/> </interface> 6.仮想マシンc77g159の設定 (9) virsh edit c77g159 <interface type='vdpa'> <source dev='/dev/vhost-vdpa-1'/> </interface>
6-3.vdpaモジュールの有効化とvdpaデバイスの追加:(1)
vdpaモジュールの有効化、既存ドライバのアンバインド、vdpaデバイスの追加を実施します。
modprobe vdpa modprobe vhost_vdpa echo mlx5_core.rdma.2 > /sys/bus/auxiliary/devices/mlx5_core.sf.2/mlx5_core.rdma.2/driver/unbind echo mlx5_core.eth.2 > /sys/bus/auxiliary/devices/mlx5_core.sf.2/mlx5_core.eth.2/driver/unbind echo mlx5_core.rdma.3 > /sys/bus/auxiliary/devices/mlx5_core.sf.3/mlx5_core.rdma.3/driver/unbind echo mlx5_core.eth.3 > /sys/bus/auxiliary/devices/mlx5_core.sf.3/mlx5_core.eth.3/driver/unbind vdpa dev add name vdpa0 mgmtdev auxiliary/mlx5_core.sf.2 vdpa dev add name vdpa1 mgmtdev auxiliary/mlx5_core.sf.3
vdpaモジュール有効化
vhost_vdpaモジュール有効化
en7f0pf0sf11のrdmaドライバのアンバインド
en7f0pf0sf11のethドライバのアンバインド
en7f1pf1sf12のrdmaドライバのアンバインド
en7f1pf1sf12のethドライバのアンバインド
vdpa0デバイスの追加
vdpa1デバイスの追加
以下の設定になっていることを確認します。
注目すべき箇所は赤文字で記載します。
devlink dev show devlink port show vdpa mgmtdev show vdpa dev show ls -Fal /dev/ ls -Fal /sys/bus/vdpa/drivers/vhost_vdpa [root@c84g155 ~]# devlink dev show pci/0000:07:00.0 pci/0000:07:00.1 auxiliary/mlx5_core.sf.2 auxiliary/mlx5_core.sf.3 [root@c84g155 ~]# devlink port show pci/0000:07:00.0/65535: type eth netdev ens2f0 flavour physical port 0 splittable false pci/0000:07:00.0/32768: type eth netdev en7f0pf0sf11 flavour pcisf controller 0 pfnum 0 sfnum 11 splittable false function: hw_addr ca:fe:c0:ff:ee:11 state active opstate attached pci/0000:07:00.1/131071: type eth netdev ens2f1 flavour physical port 1 splittable false pci/0000:07:00.1/98304: type eth netdev en7f1pf1sf12 flavour pcisf controller 0 pfnum 1 sfnum 12 splittable false function: hw_addr ca:fe:c0:ff:ee:12 state active opstate attached [root@c84g155 ~]# vdpa mgmtdev show auxiliary/mlx5_core.sf.2: supported_classes net auxiliary/mlx5_core.sf.3: supported_classes net [root@c84g155 ~]# vdpa dev show vdpa0: type network mgmtdev auxiliary/mlx5_core.sf.2 vendor_id 5555 max_vqs 16 max_vq_size 256 vdpa1: type network mgmtdev auxiliary/mlx5_core.sf.3 vendor_id 5555 max_vqs 16 max_vq_size 256 [root@c84g155 ~]# ls -Fal /dev/ total 0 drwxr-xr-x 22 root root 3660 Jul 27 09:45 ./ dr-xr-xr-x. 17 root root 244 Jul 26 13:17 ../ crw-r--r-- 1 root root 10, 235 Jul 27 09:41 autofs ============ s n i p ============ crw------- 1 root root 10, 137 Jul 27 09:41 vhci crw------- 1 root root 10, 238 Jul 27 09:48 vhost-net crw------- 1 root root 240, 0 Jul 27 09:45 vhost-vdpa-0 crw------- 1 root root 240, 1 Jul 27 09:45 vhost-vdpa-1 [root@c84g155 ~]# ls -Fal /sys/bus/vdpa/drivers/vhost_vdpa total 0 drwxr-xr-x 2 root root 0 Jul 27 09:45 ./ drwxr-xr-x 3 root root 0 Jul 27 09:45 ../ --w------- 1 root root 4096 Jul 27 09:45 bind lrwxrwxrwx 1 root root 0 Jul 27 09:45 module -> ../../../../module/vhost_vdpa/ --w------- 1 root root 4096 Jul 27 09:45 uevent --w------- 1 root root 4096 Jul 27 09:45 unbind lrwxrwxrwx 1 root root 0 Jul 27 09:45 vdpa0 -> ../../../../devices/pci0000:00/0000:00:03.0/0000:07:00.0/mlx5_core.sf.2/vdpa0/ lrwxrwxrwx 1 root root 0 Jul 27 09:45 vdpa1 -> ../../../../devices/pci0000:00/0000:00:03.0/0000:07:00.1/mlx5_core.sf.3/vdpa1/
上記の出力結果より、以下のことが確認できます。
- devlinkデバイスとして、0000:07:00.0, 0000:07:00.1, auxiliary/mlx5_core.sf.2, auxiliary/mlx5_core.sf.3 が認識されている
- devlinkポートとして、pci/0000:07:00.0がen7f0pf0sf11 として認識されている
- vdpaの管理デバイスとして、auxiliary/mlx5_core.sf.2, auxiliary/mlx5_core.sf.3 が認識されている
- vdpaデバイスとして、auxiliary/mlx5_core.sf.2がvdpa0 として認識されている
- /dev/vhost-vdpa-0, /dev/vhost-vdpa-1がvhost_vdpaデバイスとして認識されている
- 0000:07:00.0/mlx5_core.sf.2/vdpa0, 0000:07:00.1/mlx5_core.sf.3/vdpa1がvhost_vdpaドライバに制御されている
6-4.ovsの初期設定
ovsは、既にインストール済みなので*6、systemctlからサービスをスタートします。
systemctl start openvswitch ovs-vsctl set Open_vSwitch . other_config:hw-offload=true other_config:tc-policy=none systemctl restart openvswitch
ovsサービスの起動
HW offloadとtc-policyの設定
ovsサービスの再起動(上記設定を反映させるため)
以下のコマンドで設定内容を確認します。
ovs-vsctl get Open_vSwitch . other_config [root@c84g155 ~]# ovs-vsctl get Open_vSwitch . other_config {hw-offload="true", tc-policy=none}
補足1
other_config:tc-policyについて、補足します。
tc-policyは、以下のオプションが設定可能です。
none | adds a TC rule to both the software and the hardware (default) |
skip_sw | adds a TC rule only to the hardware |
skip_hw | adds a TC rule only to the software |
補足2
設定を削除したい場合は、以下のようにコマンドを実行してください。
hw-offload がキーとなっていますので、tc-policyやhw-offloadなど、削除したい任意のキーを指定してください。
ovs-vsctl remove Open_vSwitch . other_config hw-offload
6-5.br30-ovsの設定:(2)(3)(4)
1つ目のブリッジを作成します。
(2) ovs-vsctl add-br br30-ovs (3) ovs-vsctl add-port br30-ovs ens2f0 (4) ovs-vsctl add-port br30-ovs en7f0pf0sf11
(2)ブリッジの作成
(3)アップリンクの作成(PFを指定し、外部NW向けのインターフェースを設定)
(4)ダウンリンクの作成(SFを指定し、VM向けのインターフェースを設定)
以下のコマンドで設定を確認します。
[root@c84g155 ~]# ovs-vsctl show 09598355-a1bf-4ce0-9edc-53c04d15ac8a Bridge br30-ovs Port br30-ovs Interface br30-ovs type: internal Port ens2f0 Interface ens2f0 Port en7f0pf0sf11 Interface en7f0pf0sf11 ovs_version: "2.14.1"
6-6.br31-ovsの設定:(5)(6)(7)
2つ目のブリッジを作成します。
(5) ovs-vsctl add-br br31-ovs (6) ovs-vsctl add-port br31-ovs ens2f1 (7) ovs-vsctl add-port br31-ovs en7f1pf1sf12
(2)(3)(4)と同様です。
以下のコマンドで設定を確認します。青文字が追加された部分です。
[root@c84g155 ~]# ovs-vsctl show
09598355-a1bf-4ce0-9edc-53c04d15ac8a
Bridge br30-ovs
Port br30-ovs
Interface br30-ovs
type: internal
Port ens2f0
Interface ens2f0
Port en7f0pf0sf11
Interface en7f0pf0sf11
Bridge br31-ovs
Port br31-ovs
Interface br31-ovs
type: internal
Port ens2f1
Interface ens2f1
Port en7f1pf1sf12
Interface en7f1pf1sf12
ovs_version: "2.14.1"
6-7.仮想マシンc77g153の設定:(8)
/var/lib/libvirt/images/にqcow2ファイルをアップロードしておいてください。
本ブログでは、CentOS7.7をインストールしたqcow2ファイルを予め準備していました。
加えて、一度virt-managerで仮想マシンを作成後、"virsh edit" コマンドで編集していきます。
VNCなどでホストOSにログインし、virt-managerを起動してください。
新規仮想マシンを作成する際、以下の[1]-[5]のデバイスを削除してください。*7
VM起動後、一旦shutdownします。
shutdown後、以下のようなデバイス構成になっていればOKです。
ここに記載されているNICはvDPAでは使用しませんが、sshできるようになるため、必要であれば管理用IPをアサインしてください。
shutdown後、virsh editコマンドで以下の設定を実施します。
(8) virsh edit c77g153 <devices> ============ s n i p ============ <interface type='vdpa'> <source dev='/dev/vhost-vdpa-0'/> </interface>
6-8.仮想マシンc77g159の設定:(9)
/dev/vhost-vdpa-1以外は、6-7と同様です。
(9) virsh edit c77g159 <devices> ============ s n i p ============ <interface type='vdpa'> <source dev='/dev/vhost-vdpa-1'/> </interface>
7.動作確認
7-1.事前準備
ホストOS c84g155で5つのコンソールを準備してください。
ConsoleA | tail -f /var/log/messages | VM起動時に確認すべきログを参照するため |
ConsoleB | watch ovs-ofctl -O OpenFlow14 dump-ports br30-ovs | c77g153のパケットカウントを確認するため |
ConsoleC | watch ovs-ofctl -O OpenFlow14 dump-ports br31-ovs | c77g159のパケットカウントを確認するため |
ConsoleD | virsh start c77g153; virsh console c77g153 | 仮想マシンc77g153のコンソール用 |
ConsoleE | virsh start c77g159; virsh console c77g159 | 仮想マシンc77g159のコンソール用 |
7-2.VMの起動
VMを起動する前に、ConsoleA, B, Cでは上記のコマンドを実行しておいてください。
その後、c77g153を起動します。
数秒待ってから、c77g159を起動します。
c77g153 or c77g159からPingを飛ばしてください。
例として、fig.1に従い、c77g153から ping 192.168.30.159 を実行します。
fig.1
以下、出力結果です。注目する箇所は赤文字で記載します。
ConsoleA
Jul 27 11:50:49 c84g155 systemd[1]: Starting Virtualization daemon... Jul 27 11:50:49 c84g155 systemd[1]: Started Virtualization daemon. Jul 27 11:50:49 c84g155 kvm[3831]: 1 guest now active Jul 27 11:50:49 c84g155 kvm[3832]: 0 guests now active Jul 27 11:50:49 c84g155 systemd[1]: Listening on Virtual machine log manager socket. Jul 27 11:50:49 c84g155 systemd[1]: Started Virtual machine log manager. Jul 27 11:50:49 c84g155 kernel: mlx5_core.sf mlx5_core.sf.2: mlx5_vdpa_set_status:1786:(pid 3806): performing device reset Jul 27 11:50:49 c84g155 systemd-machined[1192]: New machine qemu-1-c77g153. Jul 27 11:50:49 c84g155 systemd[1]: Started Virtual Machine qemu-1-c77g153. Jul 27 11:50:49 c84g155 kernel: cgroup: cgroup: disabling cgroup2 socket matching due to net_prio or net_cls activation Jul 27 11:50:49 c84g155 kvm[3850]: 1 guest now active Jul 27 11:50:59 c84g155 kernel: mlx5_core.sf mlx5_core.sf.3: mlx5_vdpa_set_status:1786:(pid 3803): performing device reset Jul 27 11:50:59 c84g155 systemd-machined[1192]: New machine qemu-2-c77g159. Jul 27 11:50:59 c84g155 systemd[1]: Started Virtual Machine qemu-2-c77g159. Jul 27 11:50:59 c84g155 kvm[3892]: 2 guests now active Jul 27 11:51:11 c84g155 kernel: mlx5_core.sf mlx5_core.sf.2: mlx5_vdpa_handle_set_map:475:(pid 3855): memory map update Jul 27 11:51:19 c84g155 ovs-vswitchd[3688]: ovs|00001|odp_util(handler10)|ERR|internal error parsing flow key recirc_id(0),dp_hash(0),skb_priority(0),in_port(5),skb_mark(0),ct_state(0),ct_zone(0),ct_mark(0),ct_label(0),eth(src=ca:fe:c0:ff:ee:11,dst=01:00:5e:00:00:16),eth_type(0x0800),ipv4(src=192.168.30.153,dst=224.0.0.22,proto=2,tos=0xc0,ttl=1,frag=no) Jul 27 11:51:19 c84g155 ovs-vswitchd[3688]: ovs|00002|odp_util(handler10)|ERR|internal error parsing flow key recirc_id(0),dp_hash(0),skb_priority(0),in_port(3),skb_mark(0),ct_state(0),ct_zone(0),ct_mark(0),ct_label(0),eth(src=ca:fe:c0:ff:ee:11,dst=01:00:5e:00:00:16),eth_type(0x0800),ipv4(src=192.168.30.153,dst=224.0.0.22,proto=2,tos=0xc0,ttl=1,frag=no) Jul 27 11:51:20 c84g155 kernel: Mirror/redirect action on Jul 27 11:51:26 c84g155 kernel: mlx5_core.sf mlx5_core.sf.3: mlx5_vdpa_handle_set_map:475:(pid 3897): memory map update Jul 27 11:51:29 c84g155 kernel: tc mirred to Houston: device br30-ovs is down Jul 27 11:51:29 c84g155 kernel: tc mirred to Houston: device br31-ovs is down Jul 27 11:51:34 c84g155 ovs-vswitchd[3688]: ovs|00001|odp_util(handler5)|ERR|internal error parsing flow key recirc_id(0),dp_hash(0),skb_priority(0),in_port(1),skb_mark(0),ct_state(0),ct_zone(0),ct_mark(0),ct_label(0),eth(src=ca:fe:c0:ff:ee:12,dst=01:00:5e:00:00:16),eth_type(0x0800),ipv4(src=192.168.30.159,dst=224.0.0.22,proto=2,tos=0xc0,ttl=1,frag=no) Jul 27 11:51:34 c84g155 ovs-vswitchd[3688]: ovs|00001|odp_util(handler3)|ERR|internal error parsing flow key recirc_id(0),dp_hash(0),skb_priority(0),in_port(4),skb_mark(0),ct_state(0),ct_zone(0),ct_mark(0),ct_label(0),eth(src=ca:fe:c0:ff:ee:12,dst=01:00:5e:00:00:16),eth_type(0x0800),ipv4(src=192.168.30.159,dst=224.0.0.22,proto=2,tos=0xc0,ttl=1,frag=no)
ConsoleB
[root@c84g155 ~]# ovs-ofctl -O OpenFlow14 dump-ports br30-ovs OFPST_PORT reply (OF1.4) (xid=0x2): 3 ports port LOCAL: rx pkts=0, bytes=0, drop=13, errs=0, frame=0, over=0, crc=0 tx pkts=0, bytes=0, drop=0, errs=0, coll=0 duration=135.157s port ens2f0: rx pkts=33, bytes=4723, drop=0, errs=0, frame=0, over=0, crc=0 tx pkts=34, bytes=4835, drop=0, errs=0, coll=0 duration=135.163s port en7f0pf0sf11: rx pkts=34, bytes=4699, drop=0, errs=0, frame=0, over=0, crc=0 tx pkts=167, bytes=16515, drop=0, errs=0, coll=0 duration=135.161s
ConsoleC
[root@c84g155 ~]# ovs-ofctl -O OpenFlow14 dump-ports br31-ovs OFPST_PORT reply (OF1.4) (xid=0x2): 3 ports port LOCAL: rx pkts=0, bytes=0, drop=13, errs=0, frame=0, over=0, crc=0 tx pkts=0, bytes=0, drop=0, errs=0, coll=0 duration=140.882s port ens2f1: rx pkts=34, bytes=4835, drop=0, errs=0, frame=0, over=0, crc=0 tx pkts=33, bytes=4723, drop=0, errs=0, coll=0 duration=140.875s port en7f1pf1sf12: rx pkts=33, bytes=4591, drop=0, errs=0, frame=0, over=0, crc=0 tx pkts=168, bytes=16627, drop=0, errs=0, coll=0 duration=140.887s
ConsoleD
[root@c77g153 ~]# ping 192.168.30.159 PING 192.168.30.159 (192.168.30.159) 56(84) bytes of data. 64 bytes from 192.168.30.159: icmp_seq=1 ttl=64 time=123 ms 64 bytes from 192.168.30.159: icmp_seq=2 ttl=64 time=0.809 ms 64 bytes from 192.168.30.159: icmp_seq=3 ttl=64 time=0.454 ms 64 bytes from 192.168.30.159: icmp_seq=4 ttl=64 time=0.457 ms --- 192.168.30.159 ping statistics --- 5 packets transmitted, 5 received, 0% packet loss, time 4005ms rtt min/avg/max/mdev = 0.454/25.142/123.539/49.198 ms
<補足>
performing device reset | mlx5_coreによりmlx5_vdpaが初期化されています。 |
memory map update | mlx5_core.sfによりmlx5_vdpaのメモリマッピングとアップデートが実行されています。なお、このログが出力されない限り、絶対に通信することはできないため、最重要メッセージとなります。 |
tc mirred to Houston | 一時的なエラーとして数行ほど出力されますが、特に問題ありません。 |
internal error parsing flow key | ovsがマルチキャスト関連のエラーを出していますが、特に問題はありません。気にしないでください。 |
en7f0pf0sf11, en7f1pf1sf12 | 各ポートのtx/rxのパケットカウントとバイトカウントが上昇していることが確認できます。 |
以上です。
8.最後に
以下のサイトを参考にさせて頂きました。
https://github.com/Mellanox/scalablefunctions/wiki
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/networking/devlink/devlink-port.rst?h=v5.12-rc3#n125
https://legacy.netdevconf.info/0x14/pub/slides/45/sf_mgmt_using_devlink_netdevconf_0x14.pdf
https://legacy.netdevconf.info/0x14/pub/papers/45/0x14-paper45-talk-paper.pdf
https://01.org/blogs/2019/assignable-interfaces-intel-scalable-i/o-virtualization-linux
SFはスケーラビリティに優れた軽量なSR-IOV VFと考えれば良いのではないかと思います。
もちろん、それだけには留まらない多くの利点があることは、上記URLを参照すれば、ご理解頂けると思います。
また、SFはvDPAと併用することにより、その真価が発揮されますが、クラウドネイティブ化を見据えたこのような技術の普及には、それほど多くの時間は掛からないと予想しています。
Intel Scalable IOVは2018年に登場しており、Linux KernelのSub FunctionやScalable Functionは、ここ数年に登場した比較的新しい技術となります。
一方で、SR-IOVは2007年に登場して、2010年頃から少しづつ普及したと記憶していますが、既に10年以上もの間、利用され続けている技術です。
低レイヤの技術は、上位レイヤの技術と比較して進化の速度が遅いとされていますが、今まさに新技術の転換期に差し掛かっているのだと思います。
私は技術者として、こういったトレンドを素早くキャッチし、実務レベルでも活用可能な技術力に昇華させておく必要があると考えています。
*1:Scalable IOVは、カーネルパラメータにintel_iommu=sm_onを設定することにより、scalable modeを有効化することができます。加えて、 ifcvfドライバに対応したNIC(Intel SmartNIC N3000 series , N5000 series)を使用する必要があります。
*2:対向機器に100Gbpsスイッチや100GNIC搭載サーバが用意できない場合を考慮し、ループ接続としています。但し、VMで生成したパケットが物理的に外部へ送信されることが重要と考えているため、fig.1の構成としています。
*3:私が理解した内容を記載しています。内容が誤っている場合には、ご指摘ください。
*4:[=m]はモジュール化されていることを示します。この場合、OS起動後にmodprobeで有効化することが可能です。しかし、[=n]の場合、ビルド対象から除外されるため、modprobeでも有効化することができませんので、注意してください。
*5:厳密には、make modules_installを実行したとき、エラーが出力されます。
*6:2-1.Mellanoxドライバ(OFED)のインストールで、インストール済みです。
*7:これはqemuのビルド時にspiceなどの関連パッケージをインストールしていないため、これらのデバイスを削除しないと仮想マシンが起動できませんでした。なお、vDPAとは直接関係がないため、これらの対処方法については割愛します。