次の方法で共有


Linux 上の Microsoft Azure ネットワーク アダプター (MANA) と DPDK

Microsoft Azure ネットワーク アダプター (MANA) は、より高いスループットと信頼性を実現Azure仮想マシン用の新しいハードウェアです。 MANA を使用するには、ユーザーは DPDK 初期化ルーチンを変更する必要があります。 MANA には、レガシ ハードウェアと比較して次の 2 つの変更が必要です。

  • ポーリング モード ドライバー (PMD) の MANA EAL 引数は、以前のハードウェアとは異なります。
  • Linux カーネルは、DPDK 初期化が始まる前に、MANA ネットワーク インターフェイスの制御を解放する必要があります。

MANA DPDK のセットアップ手順はコード例の中で説明されています。

はじめに

レガシ Azure Linux VM は、高速ネットワークのために mlx4 または mlx5 ドライバーとそれに付随するハードウェアに依存しています。 Azure DPDK ユーザーは、DPDK EAL にバスアドレスを渡すことによって、特定のインターフェースを含めるか除外するかを選択します。 MANA DPDK のセットアップ手順は、高速ネットワーク インターフェイスごとに 1 つのバス アドレスがあるという想定が正しくなくなったため、若干異なります。 PCI バス アドレスを使用するのではなく、MANA PMD は MAC アドレスを使用して、どのインターフェイスをバインドするべきかを決定します。

MANA DPDK EAL 引数

MANA PMD は、--vdev 引数が存在しない場合はシステム上のすべてのデバイスとポートをプローブします。--vdev 引数は必須ではありません。 テスト環境で多くの場合に望ましいのは、VM への SSH 接続のサービスを提供するために 1 つの (プライマリ) インターフェイスを利用できるようにしておくことです。 使用可能な VF のサブセットで DPDK を使用するには、ユーザーは MANA デバイスのバス アドレスと、インターフェイスの MAC アドレスの両方を --vdev 引数に渡す必要があります。 詳細については、MANA 上の DPDK EAL 初期化をデモするコード例が利用できます。

DPDK 環境抽象化レイヤー (EAL) に関する一般的な情報については、以下を参照してください。

MANA の DPDK 要件

カーネルのサポート

MANA ハードウェアで DPDK を実行するには、Linux カーネル 6.14 以降、または Linux カーネル 6.14 以降のイーサネットドライバーと InfiniBand ドライバーのバックポートが必要です。 また、DPDK とユーザースペースのドライバーの特定バージョンも必要です。 MANA DPDK には、次のドライバーのセットが必要です。

  • DPDK MANA ポールモードドライバー (最後の3つの安定バージョン)
  • Libmana ユーザー空間ドライバー (rdma-core v44 以降)

注記

DPDK は、最後の 3 つの安定したドライバー リリースを正式にサポートしています。 以前の DPDK バージョンをお持ちのお客様は、サポートされている安定版リリースのいずれかからすべての MANA パッチをバックポートする必要があります。

注記

MANA DPDK は、Windowsでは使用できません。Linux VM でのみ機能します。

サポートされている Marketplace イメージ

サポートされているマーケットプレース イメージの完全な一覧については、「Azure 高速ネットワークの概要」を参照してください。

例: MANA のチェック

注記

この記事は、lspci コマンドを含む pciutils パッケージがシステムにインストールされていることを前提としています。

# check for pci devices with ID:
#   vendor: Microsoft Corporation (1414)
#   class:  Ethernet Controller (0200)
#   device: Microsoft Azure Network Adapter VF (00ba)
if [[ -n `lspci -d 1414:00ba:0200` ]]; then
    echo "MANA device is available."
else
    echo "MANA was not detected."
fi

例: DPDK のインストール (Ubuntu 22.04)

注記

この記事は、互換性のあるカーネルと rdma-core がシステムにインストールされていることを前提としています。

DEBIAN_FRONTEND=noninteractive sudo apt-get install -q -y build-essential libudev-dev libnl-3-dev libnl-route-3-dev ninja-build libssl-dev libelf-dev python3-pip meson libnuma-dev

pip3 install pyelftools

# Try latest LTS DPDK, example uses DPDK tag v23.07-rc3
git clone https://github.com/DPDK/dpdk.git -b v23.07-rc3 --depth 1
pushd dpdk
meson build
cd build
ninja
sudo ninja install
popd

例: Testpmd のセットアップと netvsc のテスト

MANA を使用して DPDK を実行するための次のコード例に注意してください。 MANA のパフォーマンスを最大限に高めるために、Azure 上での direct-to-vf 'netvsc' 構成を推奨します。

注記

DPDK では 2 MB または 1 GB の hugepage を有効にする必要があります。 例では、2 つの高速ネットワーク NIC が接続されたAzure VM を想定しています。

# Enable 2MB hugepages.
echo 1024 | tee /sys/devices/system/node/node*/hugepages/hugepages-2048kB/nr_hugepages

# Assuming use of eth1 for DPDK in this demo
PRIMARY="eth1"

# $ ip -br link show master eth1 
# > enP30832p0s0     UP             f0:0d:3a:ec:b4:0a <... # truncated
# grab interface name for device bound to primary
SECONDARY="`ip -br link show master $PRIMARY | awk '{ print $1 }'`"
# Get mac address for MANA interface (should match primary)
MANA_MAC="`ip -br link show master $PRIMARY | awk '{ print $3 }'`"


# $ ethtool -i enP30832p0s0 | grep bus-info
# > bus-info: 7870:00:00.0
# get MANA device bus info to pass to DPDK
BUS_INFO="`ethtool -i $SECONDARY | grep bus-info | awk '{ print $2 }'`"

# Set MANA interfaces DOWN before starting DPDK
ip link set $PRIMARY down
ip link set $SECONDARY down


## Move synthetic channel to user mode and allow it to be used by NETVSC PMD in DPDK
DEV_UUID=$(basename $(readlink /sys/class/net/$PRIMARY/device))
NET_UUID="f8615163-df3e-46c5-913f-f2d2f965ed0e"
modprobe uio_hv_generic
echo $NET_UUID > /sys/bus/vmbus/drivers/uio_hv_generic/new_id
echo $DEV_UUID > /sys/bus/vmbus/drivers/hv_netvsc/unbind
echo $DEV_UUID > /sys/bus/vmbus/drivers/uio_hv_generic/bind

# MANA single queue test
dpdk-testpmd -l 1-3 --vdev="$BUS_INFO,mac=$MANA_MAC" -- --forward-mode=txonly --auto-start --txd=128 --rxd=128 --stats 2

# MANA multiple queue test (example assumes > 9 cores)
dpdk-testpmd -l 1-6 --vdev="$BUS_INFO,mac=$MANA_MAC" -- --forward-mode=txonly --auto-start --nb-cores=4  --txd=128 --rxd=128 --txq=8 --rxq=8 --stats 2

トラブルシューティング

インターフェイスをダウンに設定できない。

MANA バインド デバイスを DOWN に設定できないと、パケット スループットが低下するまたはゼロになる可能性があります。 デバイスを解放できないと、送信キューに関連する EAL エラー メッセージが表示される可能性があります。

mana_start_tx_queues(): Failed to create qp queue index 0
mana_dev_start(): failed to start tx queues -19

大きなページを有効にできません。

hugepage を有効にし、情報が meminfo に表示されることを確かめてみてください。

EAL: No free 2048 kB hugepages reported on node 0
EAL: FATAL: Cannot get hugepage information.
EAL: Cannot get hugepage information.
EAL: Error - exiting with code: 1
Cause: Cannot init EAL: Permission denied

--vdev="net_vdev_netvsc0,iface=eth1" の使用によるスループットの低下

net_failsafe または net_vdev_netvsc ポーリング モード ドライバーのフェールオーバー構成は、Azureで高パフォーマンスを実現するために推奨されません。 DPDK バージョン 20.11 以上の netvsc 構成の方が良い結果をもたらす可能性があります。 最適なパフォーマンスのためには、Linux カーネル、rdma-core、DPDK パッケージが、DPDK と MANA のための要件一覧を満たしていることを確認してください。

rdma-core のバージョンの不一致

rdma-core と linux カーネルの不一致は、いつでも発生する可能性があります。これが発生するのは多くの場合、ユーザーが rdma-core、DPDK、linux カーネルのいずれかの組み合わせをソースからビルドしているケースです。 このタイプのバージョンの不一致は、MANA 仮想関数 (VF) のプローブが失敗する原因となる可能性があります。

EAL: Probe PCI driver: net_mana (1414:ba) device: 7870:00:00.0 (socket 0)
mana_arg_parse_callback(): key=mac value=00:0d:3a:76:3b:d0 index=0
mana_init_once(): MP INIT PRIMARY
mana_pci_probe_mac(): Probe device name mana_0 dev_name uverbs0 ibdev_path /sys/class/infiniband/mana_0
mana_probe_port(): device located port 2 address 00:0D:3A:76:3B:D0
mana_probe_port(): ibv_alloc_parent_domain failed port 2
mana_pci_probe_mac(): Probe on IB port 2 failed -12
EAL: Requested device 7870:00:00.0 cannot be used
EAL: Bus (pci) probe failed.
hn_vf_attach(): Couldn't find port for VF
hn_vf_add(): RNDIS reports VF but device not found, retrying

これは、mana_ib に対するバックポートされたパッチを含むカーネルをより新しいバージョンの rdma-core と共に使用していることが原因である可能性が高いです。 根本原因は、カーネル RDMA ドライバーとユーザー空間 rdma-core ライブラリの間の対話です。

RDMA 用 Linux カーネル uapi は RDMA プロバイダー ID のリストを持っていますが、バックポートされたバージョンのカーネルでは、この ID 値が rdma-core ライブラリ内のバージョンと異なる場合があります。

{!注} スニペットの例は、Ubuntu 5.150-1045 linux-azure および rdma-core v46.0 からの抜粋です

// Linux kernel header
// include/uapi/rdma/ib_user_ioctl_verbs.h
enum rdma_driver_id {
	RDMA_DRIVER_UNKNOWN,
	RDMA_DRIVER_MLX5,
	RDMA_DRIVER_MLX4,
	RDMA_DRIVER_CXGB3,
	RDMA_DRIVER_CXGB4,
	RDMA_DRIVER_MTHCA,
	RDMA_DRIVER_BNXT_RE,
	RDMA_DRIVER_OCRDMA,
	RDMA_DRIVER_NES,
	RDMA_DRIVER_I40IW,
	RDMA_DRIVER_IRDMA = RDMA_DRIVER_I40IW,
	RDMA_DRIVER_VMW_PVRDMA,
	RDMA_DRIVER_QEDR,
	RDMA_DRIVER_HNS,
	RDMA_DRIVER_USNIC,
	RDMA_DRIVER_RXE,
	RDMA_DRIVER_HFI1,
	RDMA_DRIVER_QIB,
	RDMA_DRIVER_EFA,
	RDMA_DRIVER_SIW,
	RDMA_DRIVER_MANA, //<- MANA added as last member of enum after backporting
};

// Example mismatched rdma-core ioctl verbs header
// on github: kernel-headers/rdma/ib_user_ioctl_verbs.h
// or in release tar.gz: include/rdma/ib_user_ioctl_verbs.h
enum rdma_driver_id {
	RDMA_DRIVER_UNKNOWN,
	RDMA_DRIVER_MLX5,
	RDMA_DRIVER_MLX4,
	RDMA_DRIVER_CXGB3,
	RDMA_DRIVER_CXGB4,
	RDMA_DRIVER_MTHCA,
	RDMA_DRIVER_BNXT_RE,
	RDMA_DRIVER_OCRDMA,
	RDMA_DRIVER_NES,
	RDMA_DRIVER_I40IW,
	RDMA_DRIVER_IRDMA = RDMA_DRIVER_I40IW,
	RDMA_DRIVER_VMW_PVRDMA,
	RDMA_DRIVER_QEDR,
	RDMA_DRIVER_HNS,
	RDMA_DRIVER_USNIC,
	RDMA_DRIVER_RXE,
	RDMA_DRIVER_HFI1,
	RDMA_DRIVER_QIB,
	RDMA_DRIVER_EFA,
	RDMA_DRIVER_SIW,
	RDMA_DRIVER_ERDMA,  // <- This upstream has two additional providers
	RDMA_DRIVER_MANA,   // <- So MANA's ID in the enum does not match
};

この不一致が原因で MANA プロバイダー コードは読み込みに失敗します。 MANA プロバイダーの代わりに ERDMA プロバイダーが読み込まれたことを確認するには、gdb を使用して dpdk-testpmd の実行をトレースします。 MANA driver_id は、カーネルと rdma-core の両方で一貫している必要があります。 これらの ID が一致すると、MANA PMD が正しく読み込まれます。