====== Разнесение сетевых очередей по прерываниям на пограничных маршрутизаторах ======
Значительную долю нагрузки на процессоры шлюзов составляют прерывания, генерируемые сетевыми картами как сигнал на заполнение буфера устройства пакетами данных. Современные сетевые карты имеют несколько очередей (буферов) пакетов, как входящих, так и исходящих, с выделенными прерываниями для каждой очереди. По умолчанию все прерывания от всех очередей всех сетевых карт обрабатываются первым ядром, что, очевидно, быстро приводит к его перегрузке и, как следствие неспособности обработать прерывания, потерям пакетов.\\
Решение данной проблемы заключается в разнесении прерываний от разных устройств на разные процессорные ядра.\\
Ниже приведён пример таблицы прерываний 4-x ядерного сервера с двумя сетевыми интерфейсами, каждый из которых имеет по одной исходящей (tx) и входящей (rx) очереди:
CPU0 CPU1 CPU2 CPU3
46: 0 0 2522395854 0 PCI-MSI-edge eth1-rx-0
47: 0 0 0 3223164197 PCI-MSI-edge eth1-tx-0
48: 3194 0 0 0 PCI-MSI-edge eth1
49: 0 0 0 1519085293 PCI-MSI-edge eth2-rx-0
50: 0 0 1572863429 0 PCI-MSI-edge eth2-tx-0
51: 3142 0 0 0 PCI-MSI-edge eth2
Как мы можем видеть, незначительное количество прерываний генерируется самими интерфейсами (eth1,eth2). Эти прерывания не имеют отношения к трафику. Основная же масса прерываний распределена по очередям rx и tx. В целях оптимизации использования процессорного кеша рекомендуется, в случае, когда данные входят в один интерфейс и уходят с другого (FORWARD), обрабатывать прерывания rx первого и tx второго на одном ядре, что и имеет место быть в данном примере.
Чтобы привязать прерывания к ядрам так, как показано в примере, надо выполнить следующее:
echo "4" > /proc/irq/46/smp_affinity
echo "8" > /proc/irq/47/smp_affinity
echo "8" > /proc/irq/49/smp_affinity
echo "4" > /proc/irq/50/smp_affinity
Ядра здесь имеют следующие номера:
* CPU0 - 1
* CPU1 - 2
* CPU2 - 4
* CPU3 - 8