Alter.Org.UA  
 << Back Home EN en   Donate Donate www/www1/www2

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 переменные)

Сделан unified diff, согласно стандартам разработки FreeBSD

netisr_smp.7x.20120614u.patch.gz
2012.06.14

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|2
net.inet.ip.intr_queue_maxlen=NNN
net.route.netisr_maxqlen=NNN
kern.polling.enable=0|1

Немного подробнее о каждом из них:

  • net.isr.direct - обрабатывать исходящие пакеты непосредственно при попытке отправки (в т.ч. прохождение ipfw на выходе). Т.е. не откладывать в очередь, которую в отдельном потоке разгребает netisr. Есть смысл включать, если количество ядер меньше или равно количеству физическох сетевых карточек. Влияет на скорость ОТПРАВКИ пакетов. Для серверов это хорошо, для роутеров - не очень. Если нагрузка на сетевые карты неравномерная, или когда есть хотя бы одно хронически недогруженое ядро - выключать.
    При включеном net.inet.ip.fastforwarding будет еще 1 спецэффект.
  • net.isr.direct_arp - (new) обрабатывать исходящие ARP пакеты непосредственно при попытке отправки. Есть смысл держать включенным в большинстве случаев (разумного варианта, когда стоит отправлять такие запросы в очередь я придумать не могу). Добавлено для того, чтобы обработкой ARP система могла заниматься с бОльшим приоритетом даже при net.isr.direct=0
  • net.isr.maxthreads - (new) собственно, количество потоков, разгребающих очередь пакетов. Есть смысл ставить меньшим количества ядер в системе. Нужно прикинуть, сколько ресурсов съедается на обработке прерываний от сетевух и не только, сколько в пике потребляет прочий софт (БД, 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'а я сделать все еще планирую).
    При использовании патча ipfw появляется возможность еще большей оптимизации при установке значания net.inet.ip.dummynet.io_fast=2.
  • net.inet.ip.intr_queue_maxlen, net.route.netisr_maxqlen - фактически - размеры входящей и исходящей очередей. При большой нагрузке в режиме маршрутизации есть смысл увеличивать эти значения. Непоместившийся пакет выбрасывается. Это условно спасет при кратковременных перегрузках (часть пакетов пролетит с большой задержкой) но совершенно не спасет при хроничеких.
  • kern.polling.enable - использование interrupt polling'а. Работает так: после обработки прерывания драйвер проверяет, не поступило ли еще одно прерывание за время обработки предыдущего. Если поступило - обрабатывает в том же контексте исполнения. Таким образом сокращаются потери на переключение задач. Но растет время отклика системы. Теоретически может статься так, что существенную часть времени система будет проводить в обработчиках прерываний, а пользовательские процессы будут в состоянии ожидания. Выглядит как силно заторможенная система. Роутинг при этом не особо страдает. Личная практика показывает, что есть смысл использовать только на однопроцессорных машинах без приложений (роутер в чистом виде).

Примеры

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 и не только ;)

См. также


Mail to alterX@alter.org.ua (remove X)  
Автор: Alter (Александр А. Телятников) Сервер: Apache+PHP под FBSD © 2002-2017