Только одно ядро ​​ЦП обрабатывает сетевые прерывания - PullRequest
0 голосов
/ 29 апреля 2018

Я разработал сервер потокового видео в golang, который принимает несколько потоков через обычное TCP-соединение и транслирует их по HTTP.

Это работает на моем кластере raspberryPi, который я использую в Docker Swarm. Сервер горизонтально распределен между всеми малинами. Все экземпляры получают все потоки, распределение нагрузки происходит при распределении между многими клиентами по HTTP.

Один поток довольно тяжелый, около 16 Мбит / с используемой полосы пропускания.

Это работает довольно хорошо, так как я получаю 32 кадра в секунду почти без задержки.

Я решил проверить, сколько процессора и памяти мои программы используют через htop. Когда я запускаю его как пользователь root, я вижу, что мой сервер использует около 50% ЦП, что, по моему мнению, было нормально, так как он принимал 4 одновременных потока со скоростью 32 кадра в секунду. Но затем я запустил htop с пользователем pi и заметил, что другой процесс ksoftirqd потребляет еще 50% ЦП (не знаю, почему я не вижу процесс при запуске htop от имени root).

Я провел некоторое исследование и узнал, что это особый небольшой процесс, который обрабатывает отложенные системные прерывания (или что-то подобное). Это имеет смысл, поскольку я получаю большую нагрузку через интерфейс eth0.

Затем я посмотрел в /proc/interrupts:

       CPU0       CPU1       CPU2       CPU3
 16:          0          0          0          0  bcm2836-timer   0 Edge      arch_timer
 17:   92241367  299499641  352012196  317363321  bcm2836-timer   1 Edge      arch_timer
 23:     288978          0          0          0  ARMCTRL-level   1 Edge      3f00b880.mailbox
 24:   25146874          0          0          0  ARMCTRL-level   2 Edge      VCHIQ doorbell
 46:          0          0          0          0  ARMCTRL-level  48 Edge      bcm2708_fb dma
 48:          0          0          0          0  ARMCTRL-level  50 Edge      DMA IRQ
 50:          0          0          0          0  ARMCTRL-level  52 Edge      DMA IRQ
 51:     530982          0          0          0  ARMCTRL-level  53 Edge      DMA IRQ
 54:      13573          0          0          0  ARMCTRL-level  56 Edge      DMA IRQ
 55:          0          0          0          0  ARMCTRL-level  57 Edge      DMA IRQ
 56:          0          0          0          0  ARMCTRL-level  58 Edge      DMA IRQ
 59:       3354          0          0          0  ARMCTRL-level  61 Edge      bcm2835-auxirq
 62: 3696376760          0          0          0  ARMCTRL-level  64 Edge      dwc_otg, dwc_otg_pcd, dwc_otg_hcd:usb1
 79:          0          0          0          0  ARMCTRL-level  81 Edge      3f200000.gpio:bank0
 80:          0          0          0          0  ARMCTRL-level  82 Edge      3f200000.gpio:bank1
 83:          0          0          0          0  ARMCTRL-level  85 Edge      3f804000.i2c
 84:          0          0          0          0  ARMCTRL-level  86 Edge      3f204000.spi
 86:     460008          0          0          0  ARMCTRL-level  88 Edge      mmc0
 87:       5270          0          0          0  ARMCTRL-level  89 Edge      uart-pl011
 92:    4975621          0          0          0  ARMCTRL-level  94 Edge      mmc1
220:       3352          0          0          0  bcm2835-auxirq   0 Edge      serial
FIQ:              usb_fiq
IPI0:          0          0          0          0  CPU wakeup interrupts
IPI1:          0          0          0          0  Timer broadcast interrupts
IPI2:   41355699  278691553  311249136  291769396  Rescheduling interrupts
IPI3:       7758       9176       8710       9334  Function call interrupts
IPI4:          0          0          0          0  CPU stop interrupts
IPI5:    1387927    1201820    2860486    1356720  IRQ work interrupts
IPI6:          0          0          0          0  completion interrupts
Err:          0

Как вы можете видеть, прерывание 62 - это то, которое вызывается чаще всего и обрабатывается только CPU0. Я подозреваю, что это прерывание является прерыванием eth0 (как я могу это подтвердить?). Поэтому я подумал, что могу настроить это так, чтобы прерывание обрабатывалось всеми процессорами.

Итак, я посмотрел на /proc/irq/62/smp_affinity_list, и его содержимое равно 0-3, которое кажется правильным, а содержимое файла /proc/irq/62/smp_affinity равно f, которое также кажется правильным.

Так что я не понимаю, почему прерывание 62 обрабатывается только CPU0.

Также не понимаю, почему я могу видеть ksoftirqd в htop, только если я запускаю его как pi вместо root (владелец процесса - root).

Как я могу настроить Raspberry для обработки этого прерывания на всех процессорах?

* РЕДАКТИРОВАТЬ *

Я проверял это только на одной из малины, принадлежащей скоплению. Проверяя это на других хостах, я увидел похожие результаты (только чуть более низкое использование процессора). Как ни странно, на другой малине нет ksoftirqd процесса, потребляющего столько ресурсов ЦП.

...