dadv (dadv) wrote,
dadv
dadv

Categories:

Тюнинг FreeBSD 8.2. Часть 3. Ядерный планировщик.

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

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".

Tags: cpuset, dummynet, freebsd, mpd, networking, тюнинг
Subscribe
  • Post a new comment

    Error

    default userpic

    Your reply will be screened

    Your IP address will be recorded 

    When you submit the form an invisible reCAPTCHA check will be performed.
    You must follow the Privacy Policy and Google Terms of use.
  • 38 comments