Тюнинг 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".
no subject
Ты юзеров mpd дамминетом тоесть шейпишь, не ng_car?
no subject
no subject
no subject
no subject
no subject
тк у меня при включении оказывается что не шейпит вообще
no subject
При включении шейпит без проблем. Просто, пока поток не превышает указанной скорости, пакеты идут мимо очередей (то есть, не получают лишней задержки) и застаиваются в очередях только при превышении скорости.
ng_queue и 100% загрузки ядра
Спасибо за отличную статью!
Не нашел только описания проблемы с 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% загрузки ядра
no subject
Не встречался с ситуацией, когда 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 то трафик нормально ходит через вторую.
Но первая все равно в системе остается.
no subject
no subject
Причем эти ноды через какое-то время закрываются, но не все
no subject
no subject
Разве что эта фича.
7-STABLE к сожалению себя изжил. Очень спасает net.isr в 9ке с разделением по процессорам (с патчем для него, что был на наге)
no subject
no subject
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
no subject
no subject
У меня одна карта и две головы: одна локалка, другая мир.
В итоге получаю, что вторая голова грузит только один проц, т.к. там только 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 и на другие очереди?
no subject
http://dadv.livejournal.com/137221.html?thread=338693#t338693
да, очень не хороший бок от Intel =(
no subject
no subject
no subject
Новая десятка с ULE в таком режиме — 99.9% у ng_queue (которого вообще нет в списке, влезающем на экран, в первом случае), named даёт таймауты, dhcpd не даёт адресов, не зайти ни по ssh ни с Serial console (логин ешё ввести можно, дождаться приглашения на пароль — уже нет, пока не снимешь сетевой трафик), пред-запущенный top перерисовывает экра наз в 2-3 минуты…
Думали дело в стеке — когда стека не хватает NG переключается на ng_queue — увеличил вдвое — не помогло.
no subject
no subject
no subject
no subject
no subject
no subject
no subject
39 минут — мир.
4 минуты — ядро и нужные модули, самый минимум.
4 минуты — установка мира и ядра.
2 минуты — пакеты и прочая кастомизация.
4 минуты — создание образа.
А потом ещё на скорости 8 мегабайт в секунду оно пишется на CF, 10 минут...
no subject
no subject
no subject
FreeBSD+mpd5.5+freeradius
no subject