次の方法で共有


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.2 以降、または最新の Linux カーネルからのイーサネットと InfiniBand のドライバーのバックポートが必要です。 また、DPDK とユーザースペースのドライバーの特定バージョンも必要です。

MANA DPDK には、次のドライバーのセットが必要です。

  1. Linux カーネル イーサネット ドライバー (カーネル 5.15 以降)
  2. Linux カーネル InfiniBand ドライバー (カーネル 6.2 以降)
  3. DPDK MANA ポーリング モード ドライバー (DPDK 22.11 以降)
  4. Libmana ユーザースペース ドライバー (rdma-core v44 以降)

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

DPDK と MANA に対するバックポートされたパッチが存在するイメージの完全ではないリスト:

  • Red Hat Enterprise Linux 8.9
  • Red Hat Enterprise Linux 9.4
  • Canonical Ubuntu Server 20.04 (5.15.0-1045-azure)
  • Canonical Ubuntu Server 22.04 (5.15.0-1045-azure)

Note

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

例: MANA のチェック

Note

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

# check for pci devices with ID:
#   vendor: Microsoft Corporation (1414)
#   class:  Ethernet Controller (0200)
#   device: Microsft 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)

Note

この記事は、互換性のあるカーネルと 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 での VF への直接の 'netvsc' 構成をお勧めします。

Note

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 を有効にできない。

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" の使用によるスループットの低下

Azure でのハイ パフォーマンスのためには、net_failsafe または net_vdev_netvsc ポーリング モード ドライバーのフェールオーバー構成はお勧めしません。 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 が正しく読み込まれます。