dadv: (Default)
Choose your future ([personal profile] dadv) wrote2011-04-26 09:49 pm

Тюнинг 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".

[identity profile] orao.livejournal.com 2011-05-25 07:48 am (UTC)(link)
Аналогичные странные эффекты наблюдаются с dummynet и на четырехядерных системах - привязка dummynet к CPU0 даёт нулевую загрузку CPU в непиковое время, перепривязка на CPU1 может тут же дать 80% загрузки, на CPU2 - 5%, на CPU3 около 1.5% (цифры неточные, но порядок величин сохранён). Эта проблема ещё ждет своего исправления, но обходной путь - привязка dummynet к CPU0 - вполне надежен.
Ты юзеров mpd дамминетом тоесть шейпишь, не ng_car?

[identity profile] dadv.livejournal.com 2011-05-25 09:27 am (UTC)(link)
Да. Мне не надо шейпить локалку.

[identity profile] dadv.livejournal.com 2011-05-25 09:28 am (UTC)(link)
Точнее надо, но на констатную скорость, независимо от тарифа.

[identity profile] orao.livejournal.com 2011-05-25 09:58 am (UTC)(link)
А считаешь при этом как?

[identity profile] dadv.livejournal.com 2011-05-25 10:05 am (UTC)(link)
Тут - никак. Дальше по трассе есть netflow на цисках.

[identity profile] stalex.livejournal.com 2011-08-19 06:24 pm (UTC)(link)
про привязку dummynet к ядру и правда фича на 8.2 stable тоже сработала. спасибо :). Кстати у вас не включенна ли net.inet.ip.dummynet.io_fast ?
тк у меня при включении оказывается что не шейпит вообще

[identity profile] dadv.livejournal.com 2011-08-20 07:22 am (UTC)(link)
io_fast включено, об этом написано в предыдущем посте.
При включении шейпит без проблем. Просто, пока поток не превышает указанной скорости, пакеты идут мимо очередей (то есть, не получают лишней задержки) и застаиваются в очередях только при превышении скорости.

ng_queue и 100% загрузки ядра

[identity profile] pavel sivak (from livejournal.com) 2011-11-02 04:52 pm (UTC)(link)
Привет!
Спасибо за отличную статью!
Не нашел только описания проблемы с ng_queue - со своей стороны имею 2-х процессорную платформу с Xeon 5645. mpd5 в качестве pptp сервера. Две сетевые на 82576 в LACP(итого 4 гигабита/с).
При высокой нагрузке(400 kpps, ~1000 сессий) процессы ng_queue начинают съедать одно из ядер на 100%, при этом появляются потери на пользователей и увеличиваются задержки. Тюнинг с увеличением буферов net.graph.maxdgram=8388608 и net.graph.recvspace=8388608 не помогает, даже быстрее выедается одно из ядер.
Есть ли советы по этому случаю? Если что готов тест в реалтайме. Заранее спасибо.

Re: ng_queue и 100% загрузки ядра

[identity profile] dadv.livejournal.com 2011-11-03 04:50 am (UTC)(link)
Я ни разу не наблюдал такую проблему с ng_queue, помочь ничем не смогу. Погуглите, вроде бы эта проблема не редко встречается, наверняка найдется решение. В крайнем случае надо писать в net@

[identity profile] adeep.livejournal.com 2011-11-13 06:22 pm (UTC)(link)
Привет.
Не встречался с ситуацией, когда mpd создает дублирующую ноду?

ng180: flags=88d1 UP,POINTOPOINT,RUNNING,NOARP,SIMPLEX,MULTICAST metric 0 mtu 1492
inet 10.100.10.4 -- 10.100.100.217 netmask 0xffffffff
inet6 fe80::21e:67ff:fe1a:2321%ng180 prefixlen 64 scopeid 0xc7
nd6 options=21 PERFORMNUD,AUTO_LINKLOCAL

ng562: flags=88d1 UP,POINTOPOINT,RUNNING,NOARP,SIMPLEX,MULTICAST metric 0 mtu 1492
inet 10.100.10.4 -- 10.100.100.217 netmask 0xffffffff
inet6 fe80::21e:67ff:fe1a:2321%ng562 prefixlen 64 scopeid 0x245
nd6 options=21 PERFORMNUD,AUTO_LINKLOCAL

И первая (более старая) автоматически не закрывается. Соответственно абонент не работает, но если ей сделать ifconfig ng180 down то трафик нормально ходит через вторую.
Но первая все равно в системе остается.

[identity profile] dadv.livejournal.com 2011-11-14 05:21 am (UTC)(link)
Это не "дублирующая нода", это одинаковые IP-адреса на двух разных ng-интерфейсах. У меня такого быть не может, потому что IP выдаёт RADIUS и он каждому логину выдаёт его собственный IP и не разрешает повторные логины. У тебя всё зависит от того, откуда mpd берет IP для выдачи клиенту.

[identity profile] adeep.livejournal.com 2011-11-14 11:09 am (UTC)(link)
ip выдает радиус, радиус не допускает одновременного логина. Такое появилось только на свежесобранном NAS с 9.0+mpd5 (остальные все еще на 7.х крутятся).
Причем эти ноды через какое-то время закрываются, но не все

[identity profile] dadv.livejournal.com 2011-11-14 11:14 am (UTC)(link)
Я бы не стал ставить dot-zero release в работу, а 9.0 вообще ещё CURRENT.

[identity profile] adeep.livejournal.com 2011-11-14 12:39 pm (UTC)(link)
у меня 8-STABLE за последний год очень нестабильно вела себя в роли NAS. Время произвольного ребута от 5 минут до суток, но без него не обходилось. 9.0-RC2 тьфу, тьфу уже сутки стоит.
Разве что эта фича.

7-STABLE к сожалению себя изжил. Очень спасает net.isr в 9ке с разделением по процессорам (с патчем для него, что был на наге)

[identity profile] dadv.livejournal.com 2011-11-14 12:42 pm (UTC)(link)
net.isr.bindthreads=1 в loader.conf мне сильно помог против паник, при условии net.isr.direct=1 и net.isr.direct_force=1 (ноль делать нельзя, ноль это просьба паниковать почаще).

[identity profile] kes777.livejournal.com 2011-12-25 06:59 pm (UTC)(link)
# uname -a
FreeBSD flux 9.0-CURRENT FreeBSD 9.0-CURRENT #4: Fri Jun 10 01:30:12 UTC 2011 @:/usr/obj/usr/src/sys/PAE_KES i386

вообще никаких паник, правда пользователей меньше ~300 висит

# sysctl -a net.isr
net.isr.numthreads: 4
net.isr.maxprot: 16
net.isr.defaultqlimit: 256
net.isr.maxqlimit: 10240
net.isr.bindthreads: 0
net.isr.maxthreads: 4
net.isr.direct: 0
net.isr.direct_force: 0

[identity profile] dadv.livejournal.com 2011-12-26 05:15 am (UTC)(link)
Менее 300 может работать и без паник, да и вообще нельзя сравнивать 8.2 и 9.0

[identity profile] kes777.livejournal.com 2011-12-25 07:07 pm (UTC)(link)
>В итоге, трафик PPPoE/GRE, приходящий через все сетевые карты igb
У меня одна карта и две головы: одна локалка, другая мир.
В итоге получаю, что вторая голова грузит только один проц, т.к. там только PPTP трафик

# vmstat -i
interrupt total rate
irq14: ata0 1 0
irq15: ata1 641175 11
irq16: ehci0 86738 1
irq23: ehci1 115724 2
cpu0:timer 238395574 4124
irq256: igb0:que 0 30931063 535
irq257: igb0:que 1 47789662 826
irq258: igb0:que 2 43589062 754
irq259: igb0:que 3 23872069 412
irq260: igb0:link 2 0
irq261: igb1:que 0 60459306 1045
irq262: igb1:que 1 180605 3
irq263: igb1:que 2 207691 3
irq264: igb1:que 3 181743 3
irq265: igb1:link 2 0
irq266: re0 1760 0
cpu1:timer 208397763 3605
cpu3:timer 84468460 1461
cpu2:timer 95619459 1654
Total 834937859 14444

можно ли как-то это решить разбросав PPTP и на другие очереди?

[identity profile] kes777.livejournal.com 2011-12-25 07:32 pm (UTC)(link)
Сам нашел ответ на свой вопрос:
http://dadv.livejournal.com/137221.html?thread=338693#t338693

да, очень не хороший бок от Intel =(

[identity profile] blacklion.livejournal.com 2012-01-12 10:39 am (UTC)(link)
Я тут нарвался, что в свежей 10-ке (которая мне нужна из-за 802.11n) mpd клиентский (PPPoE Подключение к провайдеру) убивает машину с ULEи отлично работает на 4BSD. Хотя на 8-ке и старой 10-ке (времён форка ветки 9-ки) я жил на ULE без проблем…

[identity profile] dadv.livejournal.com 2012-01-12 11:15 am (UTC)(link)
Что значит "убивает"?

[identity profile] blacklion.livejournal.com 2012-01-12 11:21 am (UTC)(link)
Старая 10-ка с ULE и новая с 4BSD легко насыщают канал от провайдера (40Mbit, PPPoE) торрентами (сам клиент на другой машине), при этом загрузка процессора (500MHz Geode) — 60% из которых ~20% прерывания и ~40% — netisr. Можно зайти на машину, работает bind, работает dhcpd, запущенный top Показывает раз в секунду.

Новая десятка с ULE в таком режиме — 99.9% у ng_queue (которого вообще нет в списке, влезающем на экран, в первом случае), named даёт таймауты, dhcpd не даёт адресов, не зайти ни по ssh ни с Serial console (логин ешё ввести можно, дождаться приглашения на пароль — уже нет, пока не снимешь сетевой трафик), пред-запущенный top перерисовывает экра наз в 2-3 минуты…

Думали дело в стеке — когда стека не хватает NG переключается на ng_queue — увеличил вдвое — не помогло.

[identity profile] dadv.livejournal.com 2012-01-12 11:26 am (UTC)(link)
Дихотомией по времени поискать изменение пробовал?

[identity profile] blacklion.livejournal.com 2012-01-12 01:55 pm (UTC)(link)
Пробую. Засада в том, что mpd5 тоже надо переосбирать — новый не работает на старом и наоборот. И весь мир. Билд-бокс у меня — VBox на десктопе. В общем, 3 часа на итерацию, 550 ревизий между точно работающим и точно неработающим, 10 итераций...

[identity profile] dadv.livejournal.com 2012-01-12 01:59 pm (UTC)(link)
WITHOUT_XXX всякие (man src.conf) драматически уменьшают время сборки, если не жалеть один раз всё ненужное описать ими

[identity profile] blacklion.livejournal.com 2012-01-12 02:00 pm (UTC)(link)
У меня и так nanobsd, с WITHOUT_ на два экрана, но так как для пересборки порта надо пересобирать и сам билд-бокс... Решения того я не нашёл :(

[identity profile] dadv.livejournal.com 2012-01-12 02:05 pm (UTC)(link)
Так и билд-бокс можно обкорнать, хоть и не так сильно как nano. Например, модулей дофига и собираются они очень долго, при монолитном ядре (которое тоже обкорнать - гораздо быстрее собирается) можно WITHOUT_MODULES делать.

[identity profile] blacklion.livejournal.com 2012-01-12 02:06 pm (UTC)(link)
Ну да, это понятно всё, но, в целом, небыстро дело движется.

[identity profile] blacklion.livejournal.com 2012-01-12 03:08 pm (UTC)(link)
Ну вот максимально обрезанное (сам Nano):

39 минут — мир.
4 минуты — ядро и нужные модули, самый минимум.
4 минуты — установка мира и ядра.
2 минуты — пакеты и прочая кастомизация.
4 минуты — создание образа.

А потом ещё на скорости 8 мегабайт в секунду оно пишется на CF, 10 минут...

[identity profile] orao.livejournal.com 2012-11-21 08:54 am (UTC)(link)
Слушай, а Intel i350 карты ты уже пользовал? 8 очередей, тоесть, можно балансировать по восьми ядрам?

[identity profile] dadv.livejournal.com 2012-11-21 09:20 am (UTC)(link)
i350 не использовал, но 82576 с восемью очередями и балансированием работает у меня в анализаторе трафика (свичт туда зеркалирует IPoE-пакеты). Не думаю, что в i350 будет хуже - драйвер-то тот же igb.

[identity profile] kes777.livejournal.com 2012-11-21 11:09 am (UTC)(link)
Вы не могли бы подсказать стабильный релиз для связки:
FreeBSD+mpd5.5+freeradius

[identity profile] dadv.livejournal.com 2012-11-21 11:36 am (UTC)(link)
После того, как я выкинул глючный драйвер ipmi (4) из ядра (опрашиваю датчики по IP), у меня работает всё rock-stable с FreeBSD 8.3-STABLE.