Il principio principale alla base della moderazione degli interrupt è generare meno di un interrupt per frame ricevuto (o un interrupt per completamento del frame di trasmissione), riducendo il sovraccarico del sistema operativo rilevato durante la manutenzione degli interrupt. Il controller BCM5709 supporta un paio di metodi nell'hardware per interruzioni di coalescenza, tra cui:
- Genera un interrupt dopo aver ricevuto X frame (rx-frames in ethtool)
- Genera un interrupt quando non si ricevono più frame dopo X usecs (rx-usecs in ethtool)
Il problema con l'utilizzo di questi metodi hardware è che è necessario selezionarli per ottimizzare la velocità effettiva o la latenza, non è possibile avere entrambi. La generazione di un interrupt per ciascun frame ricevuto (rx-frame = 1) riduce al minimo la latenza, ma lo fa a un costo elevato in termini di sovraccarico del servizio di interrupt. L'impostazione di un valore più grande (ad esempio rx-frame = 10) riduce il numero di cicli della CPU consumati generando un solo interrupt per ogni dieci frame ricevuti, ma si verificherà anche una latenza più elevata per i primi frame in quel gruppo di dieci.
L'implementazione NAPI tenta di sfruttare il fatto che il traffico arriva in gruppi, in modo da generare immediatamente un interrupt sul primo frame ricevuto, quindi passare immediatamente alla modalità polling (ovvero disabilitare gli interrupt) perché più traffico sarà chiuso dietro. Dopo aver eseguito il polling per un numero di frame (16 o 64 nella tua domanda) o un intervallo di tempo, il driver riattiverà gli interrupt e ricomincerà da capo.
Se si dispone di un carico di lavoro prevedibile, è possibile selezionare valori fissi per uno dei precedenti (NAPI, rx-frame, rx-usecs) che offrono il giusto compromesso, ma la maggior parte dei carichi di lavoro varia e si finisce per fare alcuni sacrifici. È qui che entrano in gioco adaptive-rx / adaptive-tx. L'idea è che il driver monitora costantemente il carico di lavoro (frame ricevuti al secondo, dimensione dei frame, ecc.) E sintonizza lo schema di coalescenza di interruzione hardware per ottimizzare la latenza in situazioni di traffico ridotto o ottimizzare il throughput in situazioni di traffico elevato. È una teoria interessante, ma può essere difficile da implementare nella pratica. Solo pochi driver lo implementano (vedi http://fxr.watson.org/fxr/search?v=linux-2.6&string=use_adaptive_rx_coalesce ) e i driver bnx2 / e1000 non sono in quella lista.
Per una buona descrizione di come dovrebbe funzionare ciascun campo di coalescenza di ethtool, dai un'occhiata alle definizioni per la struttura ethtool_coalesce al seguente indirizzo:
http://fxr.watson.org/fxr/source/include/linux/ethtool.h?v=linux-2.6#L111
Per la tua particolare situazione (throughput di ~ 400Mb / s), suggerirei di ottimizzare i valori dei frame rx e dei valori rx-usecs per le migliori impostazioni per il tuo carico di lavoro. Osserva sia l'overhead dell'ISR sia la sensibilità della tua applicazione (httpd? Ecc.) Alla latenza.
Dave