다음을 통해 공유


Linux의 MANA(Microsoft Azure Network Adapter) 및 DPDK

MANA(Microsoft Azure Network Adapter)는 더 높은 처리량과 안정성을 지원하는 Azure 가상 머신을 위한 새로운 하드웨어입니다. MANA를 사용하려면 사용자가 DPDK 초기화 루틴을 수정해야 합니다. MANA에는 레거시 하드웨어에 비해 두 가지 변경이 필요합니다.

  • PMD(폴링 모드 드라이버)에 대한 MANA EAL 인수는 이전 하드웨어와 다릅니다.
  • Linux 커널은 DPDK 초기화가 시작되기 전에 MANA 네트워크 인터페이스의 제어를 해제해야 합니다.

MANA DPDK에 대한 설정 절차는 예제 코드에 요약되어 있습니다.

소개

레거시 Azure Linux VM은 가속화된 네트워킹을 위해 mlx4 또는 mlx5 드라이버와 함께 제공되는 하드웨어를 사용합니다. Azure DPDK 사용자는 버스 주소를 DPDK EAL에 전달하여 포함하거나 제외할 특정 인터페이스를 선택합니다. 가속화된 네트워킹 인터페이스당 하나의 버스 주소라는 가정이 더 이상 true가 되지 않으므로 MANA DPDK에 대한 설정 절차는 약간 다릅니다. MANA PMD는 PCI 버스 주소를 사용하는 대신 MAC 주소를 사용하여 바인딩해야 하는 인터페이스를 결정합니다.

MANA DPDK EAL 인수

MANA PMD는 --vdev 인수가 없을 때 시스템의 모든 디바이스와 포트를 검색합니다. --vdev 인수는 필수가 아닙니다. 테스트 환경에서는 VM에 대한 SSH 연결을 서비스하는 데 사용할 수 있는 하나의(기본) 인터페이스를 그대로 두는 것이 좋습니다. 사용 가능한 VF의 하위 집합과 함께 DPDK를 사용하려면 사용자는 MANA 디바이스의 버스 주소와 --vdev 인수에 있는 인터페이스의 MAC 주소를 모두 전달해야 합니다. 자세한 내용은 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 이미지

MANA가 포함된 DPDK용 백포트 패치가 포함된 이미지의 비 한정적 목록:

  • Red Hat Enterprise Linux 8.9
  • Red Hat Enterprise Linux 9.4
  • 정식 Ubuntu 서버 20.04(5.15.0-1045-azure)
  • 정식 Ubuntu 서버 22.04(5.15.0-1045-azure)

참고 항목

Windows에서는 MANA DPDK를 사용할 수 없습니다. Linux VM에서만 작동합니다.

예: MANA 확인

참고 항목

이 문서에서는 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)

참고 항목

이 문서에서는 호환되는 커널과 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를 사용하려면 2MB 또는 1GB의 거대한 페이지가 필요합니다. 예에서는 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으로 설정하지 못하면 패킷 처리량이 낮거나 0이 될 수 있습니다. 디바이스를 해제하지 못하면 전송 큐와 관련된 EAL 오류 메시지가 발생할 수 있습니다.

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

거대한 페이지를 사용하도록 설정하지 못했습니다.

거대한 페이지를 사용하도록 설정하고 정보가 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 폴 모드 드라이버의 장애 조치(failover) 구성은 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

이는 최신 버전의 rdma-core와 함께 mana_ib용 백포트 패치가 포함된 커널을 사용한 결과일 가능성이 높습니다. 근본 원인은 커널 RDMA 드라이버와 사용자 공간 rdma-core 라이브러리 간의 상호 작용입니다.

RDMA용 Linux 커널 uapi에는 RDMA 공급자 ID 목록이 있습니다. 백포트된 커널 버전에서는 이 ID 값이 rdma-core 라이브러리의 버전과 다를 수 있습니다.

{!NOTE} 코드 조각 예는 Ubuntu 5.150-1045 linux-azurerdma-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 공급자 코드가 로드되지 않습니다. gdb를 사용하여 dpdk-testpmd의 실행을 추적하여 MANA 공급자 대신 ERDMA 공급자가 로드되었는지 확인합니다. MANA 드라이버 ID는 커널과 rdma-core 모두에서 일관되어야 합니다. 해당 ID가 일치하면 MANA PMD가 올바르게 로드됩니다.