NAPI vs Interrupções adaptativas

12

Alguém poderia explicar como as duas tecnologias a seguir são usadas para mitigar a sobrecarga de interrupção sob alta carga de rede?

  1. Adaptive-rx / Adaptive-tx e
  2. NAPI;

Gostaria de receber uma resposta que explica a diferença mais próxima do nível de origem do kernel do Linux? Também gostaria de saber como forçar a NIC a fazer polling / interromper o modo de coalescência na carga que é ~ 400Mbps.

Mais informações:

O problema parece ser que os drivers bnx2 e e1000 ignoram o comando "ethtool -C adaptive-rx on". Isso é provavelmente porque esses drivers não suportam interrupções adaptáveis. Embora o manual de referência do Broadcom Programmer diz que esse recurso deve ser suportado pelo hardware NIC BCM5709.

Então eu decidi experimentar o NAPI e reduzir o peso de 64 para 16 na chamada de função netif_napi_add () para forçar a NIC no modo de polling com uma carga muito menor, mas infelizmente isso não funcionou. Eu acho que o NAPI não precisa de nenhum suporte especial de hardware no NIC, correto?

O hardware que estou usando é o NIC BCM5709 (ele usa o driver bnx2). E o SO é o Ubuntu 10.04. A CPU é o XEON 5620.

    
por Hans Solo 01.03.2011 / 02:13

1 resposta

18

O principal princípio por trás da moderação de interrupção é gerar menos de uma interrupção por quadro recebido (ou uma interrupção por conclusão do quadro de transmissão), reduzindo a sobrecarga do sistema operacional encontrada durante a manutenção de interrupções. O controlador BCM5709 suporta alguns métodos no hardware para interrupções de coalescência, incluindo:

  • Gera uma interrupção após receber X frames (rx-frames no ethtool)
  • Gera uma interrupção quando não mais quadros são recebidos após X usecs (rx-usecs no ethtool)

O problema com o uso desses métodos de hardware é que você precisa selecioná-los para otimizar a taxa de transferência ou a latência, não é possível ter os dois. Gerar uma interrupção para cada quadro recebido (rx-frames = 1) minimiza a latência, mas faz isso a um alto custo em termos de sobrecarga do serviço de interrupção. Definir um valor maior (digamos rx-frames = 10) reduz o número de ciclos de CPU consumidos gerando apenas uma interrupção para cada dez quadros recebidos, mas você também encontrará uma maior latência para os primeiros quadros desse grupo de dez. / p>

A implementação da NAPI tenta aproveitar o fato de que o tráfego vem em grupos, para que você gere uma interrupção imediatamente no primeiro quadro recebido e, em seguida, alterne imediatamente para o modo de pesquisa (ou seja, desative as interrupções) porque mais tráfego estará próximo. Depois que você tiver pesquisado algum número de quadros (16 ou 64 em sua pergunta) ou algum intervalo de tempo, o driver reativará as interrupções e recomeçará novamente.

Se você tem uma carga de trabalho previsível, os valores fixos podem ser selecionados para qualquer um dos itens acima (NAPI, rx-frames, rx-usecs) que oferecem a compensação certa, mas a maioria das cargas de trabalho varia e você acaba fazendo sacrifícios. É aqui que o adaptive-rx / adaptive-tx entra em ação. A ideia é que o driver monitore constantemente a carga de trabalho (quadros recebidos por segundo, tamanho de quadro, etc.) e ajuste o esquema de coalescência de interrupção de hardware para otimizar a latência em situações de baixo tráfego ou otimizar o throughput em situações de alto tráfego. É uma teoria legal, mas pode ser difícil de implementar na prática. Apenas alguns drivers o implementam (consulte link ) e o bnx2 / e1000 os motoristas não estão nessa lista.

Para uma boa descrição de como cada campo de coalescência de ethtool deve funcionar, dê uma olhada nas definições da estrutura ethtool_coalesce no seguinte endereço:

link

Para sua situação específica (~ 400Mb / s throughput), sugiro ajustar os valores de rx-frames e rx-usecs para as melhores configurações para sua carga de trabalho. Observe tanto a sobrecarga do ISR quanto a sensibilidade do seu aplicativo (httpd? Etc.) à latência.

Dave

    
por 14.03.2011 / 20:14