Adaptador de Rede do Microsoft Azure (MANA) e DPDK no Linux
O Adaptador de Rede do Microsoft Azure (MANA) é um novo hardware para máquinas virtuais do Azure que permite maior taxa de transferência e confiabilidade. Para fazer uso do MANA, os usuários precisam modificar suas rotinas de inicialização do DPDK. O MANA requer duas alterações com relação ao hardware obsoleto:
- Os argumentos da EAL do MANA para o driver no modo de sondagem (PMD) diferem dos do hardware anterior.
- O kernel do Linux deve liberar o controle das interfaces de rede MANA antes do início da inicialização do DPDK.
O procedimento de configuração do DPDK do MANA está descrito no exemplo de código..
Introdução
As VMs herdadas do Linux no Azure dependem dos drivers mlx4 ou mlx5 e do hardware que as acompanha para obter uma rede acelerada. Os usuários do DPDK do Azure devem selecionar interfaces específicas para incluir ou excluir ao transmitir endereços de barramento para a EAL do DPDK. O procedimento de instalação do DPDK do MANA difere ligeiramente, já que a suposição de um dos endereços de barramento por interface de Rede Acelerada não é mais verdadeira. Em vez de usar um endereço de barramento PCI, o PMD do MANA usa o endereço MAC para determinar a qual interface ele deve se vincular.
Argumentos da EAL do DPDK do MANA
O PMD do MANA sonda todos os dispositivos e portas no sistema quando nenhum argumento --vdev
está presente; o argumento --vdev
não é obrigatório. Em ambientes de teste, costuma ser desejável deixar uma interface (primária) disponível para a manutenção da conexão SSH com a VM. Para usar o DPDK com um subconjunto das VFs disponíveis, os usuários devem transmitir tanto o endereço do barramento do dispositivo MANA quanto o endereço MAC das interfaces no argumento --vdev
. Para obter mais detalhes, o exemplo de código está disponível para demonstrar a inicialização da EAL do DPDK no MANA.
Para obter informações de caráter geral sobre a Camada de Abstração do Ambiente (EAL) do DPDK:
Requisitos do DPDK para o MANA
A utilização do DPDK no hardware MANA requer o kernel Linux 6.2 ou posterior ou um backport dos drivers Ethernet e InfiniBand do kernel Linux mais recente. Ele também requer versões específicas do DPDK e dos drivers de espaço do usuário.
O DPDK do MANA requer o seguinte conjunto de drivers:
- Driver Ethernet do kernel do Linux (kernel 5.15 e posterior)
- Driver InfiniBand do kernel Linux (kernel 6.2 e posterior)
- Driver de modo de pool MANA do DPDK (DPDK 22.11 e posterior)
- Drivers de espaço do usuário Libmana (rdma-core v44 e posterior)
Imagens do Marketplace com suporte
Uma lista não exaustiva de imagens com correções retroativas para DPDK com 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)
Observação
O DPDK do MANA não está disponível para Windows e só funcionará em VMs do Linux.
Exemplo: verificar se existe um MANA
Observação
Este artigo pressupõe que o pacote pciutils contendo o comando lspci esteja instalado no 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
Exemplo: instalação do DPDK (Ubuntu 22.04)
Observação
Este artigo pressupõe que um kernel e um rdma-core compatíveis estejam instalados no 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
Exemplo: configuração de testpmd e teste de netvsc
Observe o exemplo de código a seguir para executar o DPDK com o MANA. A configuração "netvsc" direto para vf no Azure é recomendada para o máximo desempenho com o MANA.
Observação
O DPDK requer que páginas enormes de 2MB ou 1GB sejam habilitadas. O exemplo pressupõe uma VM do Azure com duas NICs de rede acelerada 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
Solução de problemas
Falha ao configurar a interface como inoperante (d0wn).
Não configurar o dispositivo vinculado ao MANA como DOWN (inoperante) pode resultar em uma taxa de transferência de pacotes baixa ou igual a zero. Não liberar o dispositivo pode resultar na mensagem de erro da EAL relacionada às filas de espera de transmissão.
mana_start_tx_queues(): Failed to create qp queue index 0
mana_dev_start(): failed to start tx queues -19
Falha ao habilitar as páginas enormes.
Tente habilitar as páginas enormes e garantir que as informações fiquem visíveis no 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
Baixa taxa de transferência com uso de --vdev="net_vdev_netvsc0,iface=eth1"
A configuração de failover dos drivers no modo de sondagem net_failsafe
ou net_vdev_netvsc
não é recomendada para um alto desempenho no Azure. A configuração de netvsc com o DPDK versão 20.11 ou superior pode fornecer melhores resultados. Para obter um desempenho otimizado, certifique-se de que seus pacotes de kernel do Linux, rdma-core e DPDK cumprem os requisitos listados para o DPDK e o MANA.
Incompatibilidade de versão para rdma-core
Incompatibilidades no rdma-core e no kernel Linux podem ocorrer a qualquer momento; geralmente ocorrem quando um usuário está criando alguma combinação de rdma-core, DPDK e o kernel Linux da origem. Esse tipo de incompatibilidade de versão pode causar uma falha na investigação da VF (função virtual) MANA.
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
Isso provavelmente é resultado do uso de um kernel com patches backported para mana_ib com uma versão mais recente do rdma-core. A causa raiz é uma interação entre os drivers RDMA do kernel e as bibliotecas rdma-core de espaço do usuário.
O uapi do kernel do Linux para RDMA tem uma lista de IDs de provedor de RDMA; em versões com suporte do kernel, esse valor de ID pode ser diferente da versão nas bibliotecas rdma-core.
{!OBSERVAÇÃO} Os snippets de exemplo são de Ubuntu 5.150-1045 linux-azure e 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
};
Essa incompatibilidade faz com que o código do provedor MANA não seja carregado. Use gdb
para rastrear a execução de dpdk-testpmd
para confirmar se o provedor ERDMA foi carregado em vez do provedor MANA. O driver_id MANA deve ser consistente para o kernel e o rdma-core. O PMD do MANA é carregado corretamente quando essas IDs correspondem.