dadv: (Default)
[personal profile] dadv

В продолжение темы.

3. Ядерный планировщик.

Речь пойдет о дефолтном планировщике SCHED_ULE.

Начиная с 7.1-RELEASE, в системе есть команда cpuset, позволяющая привязывать исполнение процессов и отдельных тредов (включая треды ядра) к любому подмножеству ядер CPU, вплоть до ограничения единственным ядром. Разумеется, в системе есть и соответствующий API, доступный драйверам.

  • Драйвер igb, создавая несколько очередей пакетов (см. предыдущий пост по ссылке выше), наивно привязывает очередь с номером Y к процессору с тем же номером, делая это одинаково для всех сетевых карт. В итоге, трафик PPPoE/GRE, приходящий через все сетевые карты igb, оказывается отнесен к нулевым очередям каждой сетевой и, в итоге, к нулевому ядру процессора. Это создает значительный дисбаланс в загрузке ядер, который, к счастью, легко исправить перепривязкой прерываний igb к различным ядрам CPU при использовании прямой обработки пакетов, без очереди netisr.

    Команда sysctl -n kern.smp.cpus возвращает количество процессорных ядер в системе, а vmstat -ai показывает все прерывания, включая те, что используются очередями igb. Например, привязав очередь Y сетевого интерфейса igbX к процессору P=(X+Y)%N (где N - количество ядер CPU, а % - взятие остатка от деления по модулю N), мы получим разнесение нулевых очередей разных интерфейсов igb по разным ядрам. Ровно это и делает стартовый скрипт, который кладем в /usr/local/etc/rc.d/cpuset-igb:

    #!/bin/sh
    
    # PROVIDE: cpuset-igb
    # REQUIRE: FILESYSTEMS
    # BEFORE:  netif
    # KEYWORD: nojail
    
    case "$1" in
    *start)
      echo "Binding igb(4) IRQs to CPUs"
      cpus=`sysctl -n kern.smp.cpus`
      vmstat -ai | sed -E '/^irq.*que/!d; s/^irq([0-9]+): igb([0-9]+):que ([0-9]+).*/\1 \2 \3/' |\
      while read irq igb que
      do
        cpuset -l $(( ($igb+$que) % $cpus )) -x $irq
      done
      ;;
    esac

    Проверить привязку ядерных тредов к ядрам процессора можно командами procstat -a -t или top -SHPI

  • При желании то же можно делать для драйвера em (проследив, чтобы наиболее занятые его треды попадали на другие ядра CPU).

  • В версии 8.2 особой странностью отличается системный тред, исполняющий код dummynet. По умолчанию, он, как и большинство других тредов, не привязан к конкретному CPU и было замечено, что при средней или небольшой сетевой нагрузке планировщик перемещает его с CPU0 на CPU1 процессора Core i3 и обратно и на него тратится 86% времени одного ядра. А если привязать тред dummynet к CPU0, его потребление тут же падает до 0.0% и остается таким, пока сетевая нагрузка не станет расти к пиковым величинам. Причем работу свою dummynet продолжает выполнять, как и прежде, корректно, несмотря на то, что грузит собой CPU уже неощутимо мало. В пиковых нагрузках dummynet, привязанный к CPU0, потребляет в моих условиях немногим более 10% одного ядра.

    Привязывается dummynet к CPU0 одной командой cpuset -l 0 -t $(procstat -t 0 | awk '/dummynet/ {print $2}')

    Аналогичные странные эффекты наблюдаются с dummynet и на четырехядерных системах - привязка dummynet к CPU0 даёт нулевую загрузку CPU в непиковое время, перепривязка на CPU1 может тут же дать 80% загрузки, на CPU2 - 5%, на CPU3 около 1.5% (цифры неточные, но порядок величин сохранён). Эта проблема ещё ждет своего исправления, но обходной путь - привязка dummynet к CPU0 - вполне надежен.

  • Остальные процессы и треды привязывать вручную не пришлось, они ведут себя корректно при автоматической балансировке загрузки ядер планировщиком SCHED_ULE и загрузка ядер на моих конфигурациях получается приблизительно ровной.

В основном, это всё, что касается тюнинга 8.2 под "high-load mpd".

From: [identity profile] dadv.livejournal.com
Я ни разу не наблюдал такую проблему с ng_queue, помочь ничем не смогу. Погуглите, вроде бы эта проблема не редко встречается, наверняка найдется решение. В крайнем случае надо писать в net@

Profile

dadv: (Default)
Choose your future

July 2024

M T W T F S S
12 34567
891011121314
15161718192021
22232425262728
293031    

Tags

Style Credit

Powered by Dreamwidth Studios