SMP-affinity

Written by

in

Не многие знают, что они могут значительно повысить производительность сетевой подсистемы Linux на мультипроцессорных или многоядерных системах за счёт распределения системных прерываний от сетевых адаптеров на различные процессоры/ядра.

Дело в том, что при интенсивной сетевой нагрузке сетевые платы вызывают слишком много системных прерываний (Вы можете посмотреть нагрузку на процессоры Вашего сервера создаваемую обработкой системных прерываний с помощью утилиты top – параметр si), что влечёт за собой потерю пакетов проходящих на/через сетевые интерфейсы.

Допустим, что у Вас в системе есть два процессора и два сетевых адаптера, сделаем так, чтобы системные прерывания от eth0 обрабатывались первым процессором, а прерывания от второго сетевого адаптера eth1 обрабатывались вторым процессором.

Проверим как обрабатываются прерывания от сетевых адаптеров в данный момент: cat /proc/interrupts

           CPU0       CPU1
  0: 1025359421 1011223877    IO-APIC-edge  timer
  1:          7     443237    IO-APIC-edge  i8042
  6:          3          2    IO-APIC-edge  floppy
  7:          0          0    IO-APIC-edge  parport0
  8:          0   18718112    IO-APIC-edge  rtc
  9:          1          0    IO-APIC-level  acpi
 12:   11950434        756    IO-APIC-edge  i8042
90:      790345          0    IO-APIC-level  eth0
169:         69   10339595    IO-APIC-level  uhci_hcd:usb5, HDA Intel, i915@pci:0000:00:02.0
177:          79073095  0     IO-APIC-level  eth1
209:          0          0    IO-APIC-level  uhci_hcd:usb4
217:     212348          1    IO-APIC-level  ehci_hcd:usb1, uhci_hcd:usb2
225:   24498064       3245    IO-APIC-level  uhci_hcd:usb3, libata
NMI:          0          0
LOC: 2036559271 2036559270
ERR:          0
MIS:          0

как мы можем видеть в приведённом примере первый сетевого адаптер «висит» на IRQ 90, а второй на IRQ 177. Причём явно видно что прерывания как от первого, так и второго сетевого адаптера обрабатываются первым процессором в системе.

Исправим данную ситуацию, для этого нам необходимо записать число “2″ в файл /proc/irq/177/smp_affinity

echo \"2\" >/proc/irq/177/smp_affinity

после этого посмотрим как изменилась ситуация:

cat /proc/interrupts
           CPU0       CPU1
  0: 1025359421 1011223877    IO-APIC-edge  timer
  1:          7     443237    IO-APIC-edge  i8042
  6:          3          2    IO-APIC-edge  floppy
  7:          0          0    IO-APIC-edge  parport0
  8:          0   18718112    IO-APIC-edge  rtc
  9:          1          0    IO-APIC-level  acpi
 12:   11950434        756    IO-APIC-edge  i8042
90:      790345          0    IO-APIC-level  eth0
169:         69   10339595    IO-APIC-level  uhci_hcd:usb5, HDA Intel, i915@pci:0000:00:02.0
177:   79073095    3672362    IO-APIC-level  eth1
209:          0          0    IO-APIC-level  uhci_hcd:usb4
217:     212348          1    IO-APIC-level  ehci_hcd:usb1, uhci_hcd:usb2
225:   24498064       3245    IO-APIC-level  uhci_hcd:usb3, libata
NMI:          0          0
LOC: 2036559271 2036559270
ERR:          0
MIS:          0

как видим счётчик прерываний для eth1 на CPU0 не изменился, но появились цифры ниже CPU1 т.е. обработка прерываний от второго сетевого адаптера eth1 обрабатывается вторым процессором в системе.

Небольшое объяснение насчёт того, что же значит цифра 2 !
Linux каждому cpu в системе ставит в соответствие некую цифру обозначающую данный процессор в системе. Ниже приведена таблица для 4-х процессорной системы

            двоичный    шестнадцатеричный
    CPU 0    0001         1
    CPU 1    0010         2
    CPU 2    0100         4
    CPU 3    1000         8

т.е. если бы у нас в вышеприведённом примере было не 2 а четыре процессора и мы бы хотели обрабатывать прерывания от eth1 на третьем процессоре CPU2, то нам для этого пришлось бы вместо 2 записать цифру 4 в файл /proc/irq/177/smp_affinity .

Любознательный читатель может спросить, что же было бы если бы мы записали в данный файл число которого нет в приведённой таблице, например echo “3″ >/proc/irq/177/smp_affinity. Ответ прост прерывания от eth1 обрабатывались бы первым и вторым процессором т.к.

           двоичный     шестнадцатеричный
    CPU 0    0001         1
  + CPU 2    0010         2
    -----------------------
             0011         3

Стоит особо отметить, нет смысла обрабатывать системные прерывания от одного сетевого адаптера на нескольких процессорах/ядрах т.к. суммарно system interrupts от данного адаптера никогда не превысит 100%, т.е. максимум, что Вы сможете получить это 50% загрузки на одном процессоре/ядре и 50% на другом.

Дополнение: у компании Intel существуют чипсеты 82575 и 82576 сетевые карты на базе которых имеют несколько очередей каждая из которых может обрабатываться отдельным ядром/процессором.

Выглядит это следующим образом

cat /proc/interrupts
           CPU0       CPU1       CPU2       CPU3       CPU4       CPU5       CPU6       CPU7
  0:   72718527   72693470   72701000   72694778   72698856   72705975   72697612   72709066    IO-APIC-edge  timer
  1:          0          1          0          0          0          0          1          0    IO-APIC-edge  i8042
  6:          0          0          2          0          0          0          1          0    IO-APIC-edge  floppy
  8:          0          0          0          0          0          1          0          0    IO-APIC-edge  rtc
  9:          0          0          0          0          0          0          0          1   IO-APIC-level  acpi
 14:     143672     144923     144966     146156     144955     144426     144156     144955    IO-APIC-edge  ata_piix
 15:     892735     915776     908202     913235     910358     903767     912399     900143    IO-APIC-edge  ide1
 58:          0          0          0          0          0          0          0          0   IO-APIC-level  uhci_hcd:usb3
 66:         64          0          0 2259148530          0          0          0          0       PCI-MSI-X  eth0-tx0
 74: 2992330737          0          0          0          0          0          0          0       PCI-MSI-X  eth0-rx0
 82:       4197 3028991669          0          0          0          0          0          0       PCI-MSI-X  eth0-rx1
 90:       4091          0 3008220806          0          0          0          0          0       PCI-MSI-X  eth0-rx2
 98:       4092          0          0 2999334745          0          0          0          0       PCI-MSI-X  eth0-rx3
106:          2          0          0          0          0          0          0          0       PCI-MSI-X  eth0
114:          7          0          0          0          0          0          0 2265679966       PCI-MSI-X  eth1-tx0
122:          1          0          0          0 3906833163          0          0          0       PCI-MSI-X  eth1-rx0
130:          1          0          0          0          0 3957703625          0          0       PCI-MSI-X  eth1-rx1
138:          1          0          0          0          0          0 3918250115          0       PCI-MSI-X  eth1-rx2
146:          1          0          0          0          0          0          0 3928688764       PCI-MSI-X  eth1-rx3
154:          2          0          0          0          0          0          0          0       PCI-MSI-X  eth1
169:          0          0          0          0          0          0          0          0   IO-APIC-level  uhci_hcd:usb5
177:          1          0          0          0          1          1          1          1   IO-APIC-level  uhci_hcd:usb4, aic94xx
185:          0          0          0          0          0          0          0          0   IO-APIC-level  ehci_hcd:usb1, uhci_hcd:usb2
NMI:          0          0          0          0          0          0          0          0
LOC:  581643579  581643516  581643609  581643411  581643494  581643475  581643531  581643008
ERR:          0
MIS:          0

За данную информацию спасибо Marian Ivasiuk

Подробнее прочитать о SMP-Affinity можно по этому адресу http://www.cs.uwaterloo.ca/~brecht/servers/apic/SMP-affinity.txt
http://centos.alt.ru/?p=26

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *