SMP patch for NETISR, FreeBSD 7.x
by Alter (alterX@alter.org.ua (remove X))
Обработка пакетов в netisr теперь может быть распределена между несколькими ядрами.
Т.к. netisr практически не менялся, патч скрее всего подойдет и для более ранних версий ядра.
Управляется через sysctl:
net.isr.maxthreads=NNN
Также добавлена еще 1 специфическая настройка:
net.isr.direct_arp=[0|1]
Исправлена компиляция для однопроцессорных систем (были ссылки на SMP-specific переменные)
netisr_smp.7x.20110501.patch.gz
FreeBSD bugtrack ID: 156769
2011.05.02
1я версия патча
netisr_smp.7x.patch.gz
2010.01.01
Как это правильно готовить (пара слов об оптимизации)
Важные sysctl'ы:
net.isr.direct=0|1
net.isr.direct_arp=0|1
net.isr.maxthreads=NNN
net.inet.ip.fastforwarding=0|1
net.inet.ip.dummynet.io_fast=0|1
net.inet.ip.intr_queue_maxlen=NNN
net.route.netisr_maxqlen=NNN
Немного подробнее о каждом из них:
- net.isr.direct -
обрабатывать исходящие пакеты непосредственно при попытке отправки (в т.ч. прохождение ipfw на выходе).
Т.е. не откладывать в очередь, которую в отдельном потоке разгребает netisr.
Есть смысл включать, если количество ядер меньше или равно количеству сетевых карточек.
Влияет на скорость ОТПРАВКИ пакетов. Для серверов это хорошо, для роутеров - не очень.
Если нагрузка на сетевые карты неравномерная, или когда есть хотя бы одно
хронически недогруженое ядро - выключать.
При включеном net.inet.ip.fastforwarding будет еще 1 спецэффект.
- net.isr.direct_arp -
обрабатывать исходящие ARP пакеты непосредственно при попытке отправки.
Есть смысл держать включенным в большинстве случаев (разумного варианта, когда стоит
отправлять такие запросы в очередь я придумать не могу). Добавлено для того,
чтобы обработкой ARP система могла заниматься с бОльшим приоритетом даже при net.isr.direct=0
- net.isr.maxthreads -
собственно, количество потоков, разгребающих очередь пакетов.
Есть смысл ставить меньшим количества ядер в системе. Нужно прикинуть, сколько ресурсов
съедается на обработке прерываний от сетевух и не только, сколько в пике потребляет прочий софт
(БД, httpd, прочие демоны) и на оставшееся распределить роутинг. Если, к примеру, сетевухи
потребляют по 80% с 2х ядер и софт еще до 100% одного ядра, а всего ядер 4, то остается
140% гарантированного времени. Т.е. полтора ядра ;) Тут можно смело ставить роутинг в 2 потока.
Если нагрузки по софту кратковременные, а на роутинг с трудом хватает - можно даже попробовать 3.
- net.inet.ip.fastforwarding -
обрабатывать входящие пакеты непосредственно в момент приема (в т.ч. прохождение ipfw на входе,
до попадания в очередь netisr). Есть смысл включать, если количество ядер меньше или равно
количеству сетевых карточек, так же как и net.isr.direct. Влияет на скорость ПРИЕМА пакетов.
Обработка пакета происходит прямо в обработчике прерывания. Следует учесть, что не все сетевухи
и не все драйвера нормально умеют складировать новые пакеты в очередь, пока обрабатывается текущий.
При включеном net.inet.ip.fastforwarding будет еще 1 спецэффект - маршрутизация пакета и
прохождение ipfw (оба раза) будут происходить в том же обработчике прерывания. Фактически, на время
обработки входящего пакета сетевая карта будет заблокирована. Это неплохо смотрится при
преобладающем входящем трафике и на однопроцессорных машинах.
- net.inet.ip.dummynet.io_fast -
если трафик помещается в заданную полосу, не пропускать его через очередь и отдельный поток.
Если нет необходимости эмулировать задержки и потери в канале - очень сильно сохраняет ресурсы.
При использовании этой опции практически отпадает необходимость в распараллеливании dummynet,
хотя этот патчик (а также аналогичный патч для nat'а я сделать все еще планирую).
- net.inet.ip.intr_queue_maxlen, net.route.netisr_maxqlen -
фактически - размеры входящей и исходящей очередей. При большой нагрузке в режиме маршрутизации
есть смысл увеличивать эти значения. Непоместившийся пакет выбрасывается. Это условно спасет
при кратковременных перегрузках (часть покетов пролетит с большой задержкой) но совершенно не
спасет при хроничеких.
Примеры
2 ядра + 2 сетевые intel (em, драйвера правильные,
с разделением предобработки в обработчике прерывания и последующего процессинга отдельном потоке)
net.isr.direct=1
net.isr.direct_arp=1
net.isr.maxthreads=1
net.inet.ip.fastforwarding=0
net.inet.ip.dummynet.io_fast=1
8 ядрер + 2 сетевые broadcom (bge, какие-то неправильные ;)
net.isr.direct=0
net.isr.direct_arp=1
net.isr.maxthreads=5
net.inet.ip.fastforwarding=0
net.inet.ip.dummynet.io_fast=1
PS.
Все это - общие рекомендации. Универсального и единственно верного набора параметров нет.
Под каждую конкретную систему и набор задач нужно подстраиваться отдельно. Наиболее
ресурсоемкие задачи нужно выносить из обработчиков прерываний, либо использовать хитрые
сетевухи, которые заточены под обслуживание в несколько потоков, т.е. во ремя обработки
прерывания они могут сгенерировать еще одно (2, 3, ...) и они будут обслужны другим свободным ядром.
Про такое счастье я слышал, живьем не видел.
А кроме того еще есть смысл подумать об оптимизации правил ipfw ;)
См. также
alterX@alter.org.ua (remove X)
|