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 SO encontrada ao reparar interrupções. O controlador BCM5709 suporta alguns métodos em hardware para interrupções coalescentes, incluindo:
- Gere uma interrupção após receber quadros X (quadros rx no ethtool)
- Gere uma interrupção quando nenhum quadro for recebido após o 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 pode ter os dois. A geração de uma interrupção para cada quadro recebido (rx-quadros = 1) minimiza a latência, mas o faz 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 latência mais alta para os primeiros quadros naquele grupo de dez.
A implementação da NAPI tenta aproveitar o fato de o tráfego chegar 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 ficará logo atrás. Depois de pesquisar um número de quadros (16 ou 64 na sua pergunta) ou algum intervalo de tempo, o driver reativará as interrupções e reiniciará.
Se você possui uma carga de trabalho previsível, é possível selecionar valores fixos para qualquer um dos itens acima (NAPI, rx-frames, rx-usecs) que oferecem a troca certa, mas a maioria das cargas de trabalho varia e você acaba fazendo alguns sacrifícios. É aqui que o adaptive-rx / adaptive-tx entra em cena. A idéia é que o driver monitore constantemente a carga de trabalho (quadros recebidos por segundo, tamanho do 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 rendimento em situações de alto tráfego. É uma teoria interessante, mas pode ser difícil de implementar na prática. Apenas alguns drivers o implementam (consulte http://fxr.watson.org/fxr/search?v=linux-2.6&string=use_adaptive_rx_coalesce ) e os drivers bnx2 / e1000 não estão nessa lista.
Para uma boa descrição de como cada campo coalescente ethtool deve funcionar, consulte as definições da estrutura ethtool_coalesce no seguinte endereço:
http://fxr.watson.org/fxr/source/include/linux/ethtool.h?v=linux-2.6#L111
Para sua situação específica (taxa de transferência de ~ 400 Mb / s), sugiro ajustar os valores de rx-frames e rx-usecs para obter 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