Міжнародна конференція розробників
і користувачів вільного програмного забезпечення

Пара слов о SO_BUSY_POLL

Евгений Рыбак, Минск, Belarus

LVEE 2015

Performance of Linux network stack was always kept in mind during any implementation. Increasing demand for cloud services, multimedia content, high performance computing forces to search new ways of optimization. SO_BUSY_POLL is one of the way to improve processing of incoming network messages without changing source code of the product.

Введение

Оптимизация скорости обработки входящих пакетов всегда была одной из главных задач сетевого стека. Рост облачных сервисов, объемов мультимедийного контента, высокопроизводительных систем (HPC) заставляет выискивать новые резервы для оптимизаций. SO_BUSY_POLL является еще одним способом улучшить производительность системы, практически не меняя исходный текст продукта.

Уровни стека TCP/IP

Как известно, стек TCP / IP состоит из уровней, каждый из которых решает четко поставленную задачу.

Физический уровень отвечает за передачу и прием электрических данных по сетевому кабелю, в соответствии с методами кодирования.

Канальный уровень отвечает за преобразование из электрического сигнала в цифровой кадр, аппаратную адресацию (MAC адрес)

Сетевой уровень отвечает за связывание отдельных подсетей, в целую сеть. Идентификация узла в сети с помощью IP адреса.

Транспортный уровень отвечает за идентификацию процесса, в рамказ узла, которому необходимо передать данные. Идентификация процесса с помощью номера порта.

Методы обработки входящих пакетов

Классически, есть два основных подхода для того, что бы узнать, что на сетевую карточку пришли новые пакеты:

  • Метод прерываний (IRQ)
  • Метод опроса (polling)

Каждый из методов имеет свои достоинства и недостатки: метод прерываний хорошо себя показал для небольшого объема траффика, когда прерывания генерируются не часто, не мешая процессору выполнять свои задачи. В случае большого и очень большого объема трафика, метод является не очень эффективным, именно в этом случае метод опроса устройства является наиболее подходящим. Busy Poll (новая опция SO_BUSY_POLL) является усовершенствованием классического метода опроса, который уменьшает задерку (Latency) и увеличивает пропускную способность (Throughput).

Обзор опции SO_BUSY_POLL

Начиная с версии ядра 3.11, ядро осуществляет поддержку опции сокета SO_BUSY_POLL.
В эко-системе SO_BUSY_POLL учавствуют следующие компоненты:

  • Ядро операционной системы
  • Драйвер сетевой карты
  • Настройки системы

Поддержка ядра операционной системы

Ядро должно быть собрано с опцией CONFIG_NET_RX_BUSY_POLL.

Драйвер сетевой карты

Драйвер сетевой карточки должен реализовать обработчик функции, который отвечает за busy polling.

Настройки системы

В сетевых настройках появились две новые опции: busy_read, busy_poll
Значением является количество микросекунд, в течении которого ядро будет опрашивать входящую очередь сетевой карточки (Ethernet RX queue)
Прочитать и записать значения можно следующим образом:

sysctl net.core.busy_read
sysctl net.core.busy_poll
sysctl net.core.busy_read=50
sysctl net.core.busy_poll=50

В этой секции, так же рассмотрим влияние опции SO_BUSY_POLL на разлчиные методы чтения TCP/UDP сокетов.

Отличие busy poll от NAPI poll

Для начала рассмотрим работу приложения с точки зрения NAPI poll

  1. Приложение создает сокет и пытается из него прочитать данные
  2. Данные отсутствуют, ожидаем момент, когда они появятся в буфере сокета
  3. Данные приходят на интерфейс
  4. Генерируется прерывание, данные передаются на уровень протоколов
  5. Данные передаются в буфер сокета
  6. Приложение может прочитать данные из сокета

Схема работы с включенной опцией SO_BUSY_POLL

  1. Приложение создает сокет и пытается из него прочитать данные.
  2. Если данных в буфере сокета нету, переходим к функции драйвера busy poll
  3. Данные приходят на интерфейс
  4. Генерируется прерывание, данные передаются на уровень протоколов
  5. Данные передаются в буфер сокета
  6. Приложение может прочитать данные из сокета

Одна из отличительных возможностей busy poll заключается в том, что если данные в буфере сокета отсутствуют, то нам не надо ждать прерывания от драйвера сетевой карточки, как в случае с NAPI poll. Busy poll инициирует «принудительную» передачу пакетов из входящей очереди драйвера в очередь сокета, тем самым исключая «лишнее» переключение контекста и прерывание.

Еще одним моментом, на который стоит обратить внимание, является то, что в случае обработчика NAPI poll, система передает количество пакетов, которое оно готово обработать в данный момент. Если количество пакетов в очереди драйвера больше, чем количество пакетов, которое система готова обработать в текущий момент, то обработчик NAPI poll будет еще раз поставлен в очередь вызовов; через некоторый промежуток времени обработчик будет вызван в очередной раз.

В случае с busy poll, обработчик busy polling будет вызываться в течении времени, которое будет указано в опции SO_BUSY_POLL или настройках busy_{read,poll}

Источники

  1. A way towards Lower Latency and Jitter, pdf
  2. Open Source Kernel Enhancements for Low Latency Socket, pdf
  3. net: low latency Ethernet device polling
  4. Understanding Linux Network Internals
  5. Linux Kernel Development
  6. Linux Kernel Sources 3.18.14

Abstract licensed under Creative Commons Attribution-ShareAlike 3.0 license

Назад