Compartir vía


Adaptador de red de Microsoft Azure (MANA) y DPDK en Linux

El adaptador de red de Microsoft Azure (MANA) es un nuevo hardware para máquinas virtuales Azure que permite un mayor rendimiento y confiabilidad. Para usar MANA, los usuarios deben modificar sus rutinas de inicialización del DPDK. MANA requiere dos cambios en comparación con el hardware heredado:

  • Los argumentos EAL de MANA para el controlador en modo de sondeo (PMD) difieren del hardware anterior.
  • El kernel de Linux debe liberar el control de las interfaces de red MANA antes de que comience la inicialización del DPDK.

El procedimiento de configuración del DPDK de MANA se describe en el código de ejemplo.

Introducción

Las máquinas virtuales de Linux de Azure heredadas se basan en los controladores mlx4 o mlx5 y el hardware adjunto para redes aceleradas. Los usuarios del DPDK de Azure seleccionarían interfaces específicas para incluir o excluir pasando direcciones de bus al EAL del DPDK. El procedimiento de configuración del DPDK de MANA difiere ligeramente, ya que la suposición de una dirección de bus por interfaz de redes aceleradas ya no es verdadera. En lugar de usar una dirección de bus PCI, el PMD de MANA usa la dirección MAC para determinar a qué interfaz se debe enlazar.

Argumentos de EAL del DPDK de MANA

El PMD de MANA sondea todos los dispositivos y puertos del sistema cuando no hay ningún argumento --vdev presente; el argumento --vdev no es obligatorio. En entornos de prueba, a menudo es conveniente dejar una interfaz (principal) disponible para atender la conexión SSH a la máquina virtual. Para usar el DPDK con un subconjunto de las máquinas virtuales disponibles, los usuarios deben pasar la dirección de bus del dispositivo MANA y la dirección MAC de las interfaces en el argumento --vdev. Para obtener más información, el código de ejemplo está disponible para demostrar la inicialización del EAL del DPDK en MANA.

Para obtener información general sobre la capa de abstracción del entorno (EAL) del DPDK:

Requisitos del DPDK para MANA

El uso de DPDK en hardware MANA requiere el kernel de Linux 6.2 o posterior o una ventanilla posterior de los controladores Ethernet e InfiniBand del kernel de Linux más reciente. También requiere versiones específicas de DPDK y controladores de espacio de usuario.

El DPDK de MANA requiere el siguiente conjunto de controladores:

  1. Controlador Ethernet del kernel de Linux (kernel 5.15 y versiones posteriores)
  2. Controlador InfiniBand del kernel de Linux (kernel 6.2 y versiones posteriores)
  3. Controlador en modo de sondeo DPDK MANA (DPDK 22.11 y versiones posteriores)
  4. Controladores de espacio de usuario de Libmana (rdma-core v44 y versiones posteriores)

Imágenes de Marketplace admitidas

Una lista no exhaustiva de imágenes con revisiones para DPDK con 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)

Nota:

El DPDK de MANA no está disponible para Windows; solo funcionará en máquinas virtuales Linux.

Ejemplo: comprobar la presencia de MANA

Nota:

En este artículo se supone que el paquete pciutils que contiene el comando lspci está instalado en el sistema.

# 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

Ejemplo: instalación del DPDK (Ubuntu 22.04)

Nota:

En este artículo se da por supuesto que el kernel compatible y rdma-core están instalados en el sistema.

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

Ejemplo: configuración de testpmd y prueba de netvsc

Tenga en cuenta el código de ejemplo siguiente para ejecutar el DPDK con MANA. Se recomienda la configuración "netvsc" directa a vf en Azure para obtener el máximo rendimiento con MANA.

Nota:

DPDK requiere que se habiliten 2 MB o 1GB de enormes páginas. En el ejemplo se supone que una máquina virtual de Azure con 2 NIC de red aceleradas conectadas.

# 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

Solución de problemas

No se puede establecer la interfaz fuera de servicio.

Si no se configura el dispositivo enlazado a MANA en DOWN, se puede producir un rendimiento de paquetes bajo o igual a cero. El error al liberar el dispositivo puede dar lugar al mensaje de error EAL relacionado con las colas de transmisión.

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

Error al habilitar páginas enormes.

Intente habilitar páginas enormes y asegurarse de que la información sea visible en 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

Bajo rendimiento con el uso de --vdev="net_vdev_netvsc0,iface=eth1"

La configuración de conmutación por error de los controladores en modo de sondeo net_failsafe o net_vdev_netvsc no se recomienda para un alto rendimiento en Azure. La configuración de netvsc con el DPDK versión 20.11 o posterior puede dar mejores resultados. Para obtener un rendimiento óptimo, asegúrese de que los paquetes del kernel de Linux, rdma-core y DPDK cumplen los requisitos enumerados para el DPDK y MANA.

Error de coincidencia de versiones para rdma-core

Los errores de coincidencia en rdma-core y el kernel de Linux pueden producirse en cualquier momento; a menudo se producen cuando un usuario crea alguna combinación de rdma-core, DPDK y el kernel de Linux desde el origen. Este tipo de error de coincidencia de versiones puede provocar un sondeo con errores de la función virtual de 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

Esto probablemente resulta de usar un kernel con revisiones con copia de seguridad para mana_ib con una versión más reciente de rdma-core. La causa principal es una interacción entre los controladores RDMA del kernel y las bibliotecas rdma-core del espacio de usuario.

El kernel de Linux uapi para RDMA tiene una lista de identificadores de proveedor RDMA, en versiones de backported del kernel este valor de id. puede diferir de la versión de las bibliotecas rdma-core.

{! NOTA} Los fragmentos de código de ejemplo proceden de Ubuntu 5.150-1045 linux-azure y 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
};

Esta falta de coincidencia da como resultado que el código de proveedor de MANA no se cargue. Use gdb para realizar un seguimiento de la ejecución de dpdk-testpmd para confirmar que el proveedor ERDMA se carga en lugar del proveedor de MANA. El controlador_id de MANA debe ser coherente para el kernel y rdma-core. El PMD de MANA se carga correctamente cuando coinciden esos identificadores.