10GbE baixo desempenho pktgen be2net

2

Estou testando o desempenho da rede de duas estações de trabalho, cada uma com processadores quad core Xeon de 2,4 GHz e adaptadores de servidor PCIe de porta dupla 10GbE NC550SFP, conectados de costas um ao outro.

Eu verifiquei a largura de banda da RAM, que é ~ 12Gbps, então não há gargalos aqui. A velocidade do barramento PCIe também está ok.

Estou testando o máximo de pps usando o tamanho mínimo de pacote para UDP e os resultados são miseráveis em comparação com estes: 2012-lpc-networking-qdisc-fastabend.pdf (desculpe, posso postar apenas um link). Se eu aumentar o tamanho do pacote e o MTU, posso chegar perto da velocidade da linha (~ 9.9Gbps).

Estou usando o pktgen com scripts NST, interfaces macvlan para vários threads e só recebo ~ 1Mpps, todos os quatro núcleos em 100%.

Para melhorar o desempenho de TX do pktgen, deparei com este documento: Dimensionamento na pilha de redes Linux

Eu verifiquei e sim, eu tenho mq qdiscs, que devem produzir o melhor desempenho:

# ip link list | grep eth3
5: eth3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP qlen 1000

Acho que o problema está no fato de que apenas uma fila TX é usada:

# dmesg | grep be2net
[    4.528058] be2net 0000:01:00.1: irq 47 for MSI/MSI-X
[    4.528066] be2net 0000:01:00.1: irq 48 for MSI/MSI-X
[    4.528073] be2net 0000:01:00.1: irq 49 for MSI/MSI-X
[    4.528079] be2net 0000:01:00.1: irq 50 for MSI/MSI-X
[    4.528104] be2net 0000:01:00.1: enabled 4 MSI-x vector(s)
[    4.696026] be2net 0000:01:00.1: created 4 RSS queue(s) and 1 default RX queue
[    4.761108] be2net 0000:01:00.1: created 1 TX queue(s)

Eu recebi uma dica sobre como habilitar várias filas TX de Dimensionamento na pilha de redes Linux :

The driver for a multi-queue capable NIC typically provides a kernel module parameter or specifying the number of hardware queues to configure. In the bnx2x driver, for instance, this parameter is called num_queues. A typical RSS configuration would be to have one receive queue for each CPU if the device supports enough queues, or otherwise at least one for each memory domain, where a memory domain is a set of CPUs that share a particular memory level (L1, L2, NUMA node, etc.).

Eu procurei por toda a documentação do driver be2net da Emulex, até enviei um e-mail, sem sorte. Eu também folheei a fonte do kernel.

Eu tenho a última versão do kernel (3.10) no Ubuntu 12.04 com o firmware mais recente nas NICs.

Idéias, alguém?

Obrigado!

    
por mrg2k8 05.07.2013 / 00:57

1 resposta

1

Eu tive um desafio semelhante (?) em uma caixa do Red Hat Enterprise Linux. Eu li o mesmo artigo, e concluí que meu problema real era que o padrão era usar todos os IRQs possíveis para obter cada CPU envolvida no trabalho de pacotes de rede. Concentrei a atividade de IRQ em um subconjunto de núcleos disponíveis e, em seguida, direcionei o trabalho de acordo. Aqui está o arquivo rc.local:

# Reserve CPU0 as the default default IRQ handler
for IRQ in 'grep eth0 /proc/interrupts | cut -d ':' -f 1'; do echo 2 > /proc/irq/$IRQ/smp_affinity; done
for IRQ in 'grep eth1 /proc/interrupts | cut -d ':' -f 1'; do echo 2 > /proc/irq/$IRQ/smp_affinity; done
for IRQ in 'grep eth2 /proc/interrupts | cut -d ':' -f 1'; do echo 2 > /proc/irq/$IRQ/smp_affinity; done
for IRQ in 'grep eth4 /proc/interrupts | cut -d ':' -f 1'; do echo $(( (($IRQ & 1) + 1) << 2 )) > /proc/irq/$IRQ/smp_affinity; done

Aqui está o arquivo cgrules.conf que define / diferencia meu servidor web apache do 10gbe, de modo que o throughput de rede sério pode acontecer como deveria:

apache      cpuset,cpu  apache/

E aqui está o arquivo cgconfig.conf que realmente separa o servidor do resto das atividades da CPU:

mount {
    cpuset  = /cgroup/cpuset;
    cpu = /cgroup/cpu;
    cpuacct = /cgroup/cpuacct;
    memory  = /cgroup/memory;
    devices = /cgroup/devices;
    freezer = /cgroup/freezer;
    net_cls = /cgroup/net_cls;
    blkio   = /cgroup/blkio;
}

group apache {
    cpuset {
        cpuset.memory_spread_slab="0";
        cpuset.memory_spread_page="0";
        cpuset.memory_migrate="0";
        cpuset.sched_relax_domain_level="-1";
        cpuset.sched_load_balance="1";
        cpuset.mem_hardwall="0";
        cpuset.mem_exclusive="0";
        cpuset.cpu_exclusive="0";
        cpuset.mems="1";
        cpuset.cpus="4-7,12-15";
    }
}

group apache {
    cpu {
        cpu.rt_period_us="1000000";
        cpu.rt_runtime_us="0";
        cpu.cfs_period_us="100000";
        cpu.cfs_quota_us="-1";
        cpu.shares="1024";
    }
}

Uma configuração padrão (sem o IRQ e hacks cgroups) eu medi cerca de 5 Gb / s de throughput de rede. Com os IRQs concentrados e aleatórios, o IO da rede se afastou, eu medi o desempenho próximo de wirespeed (9.5Gb / s) usando netperf.

n.b. pacotes gigantescos não faziam diferença, seja para os números antes ou depois.

    
por 14.12.2014 / 23:48