Может ли кто-нибудь объяснить, как две следующие технологии используются для уменьшения накладных расходов на прерывание при высокой сетевой нагрузке?
Я был бы признателен за ответ, который объясняет разницу ближе к исходному уровню ядра Linux? Также я хотел бы услышать, как заставить NIC переходить в режим объединения опроса / прерывания при нагрузке ~ 400 Мбит / с.
Дополнительная информация:
Проблема, похоже, в том, что драйверы bnx2 и e1000 игнорируют команду "ethtool -C adaptive-rx on". Вероятно, это связано с тем, что эти драйверы не поддерживают адаптивные прерывания. Хотя в справочном руководстве программиста Broadcom сказано, что эта функция должна поддерживаться аппаратным обеспечением BCM5709 NIC.
Поэтому я решил попробовать NAPI и уменьшить вес с 64 до 16 в вызове функции netif_napi_add (), чтобы заставить сетевой адаптер перейти в режим опроса при гораздо меньшей нагрузке, но, к сожалению, это не сработало. Я предполагаю, что NAPI не нуждается в какой-либо специальной аппаратной поддержке в NIC, это правильно?
Я использую сетевая карта BCM5709 (в ней используется драйвер bnx2). А ОС - это Ubuntu 10.04. Процессор - XEON 5620.
Главный принцип модерации прерываний - генерировать менее одного прерывания на каждый принятый кадр (или одно прерывание на завершение кадра передачи), что снижает накладные расходы ОС, возникающие при обслуживании прерываний. Контроллер BCM5709 поддерживает несколько аппаратных методов объединения прерываний, в том числе:
Проблема с использованием этих аппаратных методов заключается в том, что вам нужно выбрать их для оптимизации пропускной способности или задержки, у вас не может быть обоих. Создание одного прерывания для каждого принятого кадра (rx-frames = 1) минимизирует задержку, но делает это с высокой стоимостью с точки зрения накладных расходов на обслуживание прерывания. Установка большего значения (скажем, rx-frames = 10) уменьшает количество циклов процессора, потребляемых за счет генерации только одного прерывания для каждых десяти полученных кадров, но вы также столкнетесь с более высокой задержкой для первых кадров в этой группе из десяти.
Реализация NAPI пытается использовать тот факт, что трафик поступает группами, так что вы сразу генерируете прерывание на первом полученном кадре, а затем сразу переключаетесь в режим опроса (то есть отключаете прерывания), потому что больше трафика будет близко позади. После того, как вы запросили определенное количество кадров (16 или 64 в вашем вопросе) или некоторый временной интервал, драйвер повторно включит прерывания и начнет снова.
Если у вас предсказуемая рабочая нагрузка, то для любого из вышеперечисленных (NAPI, rx-frames, rx-usecs) можно выбрать фиксированные значения, что дает вам правильный компромисс, но большинство рабочих нагрузок различаются, и вы в конечном итоге приносите некоторые жертвы. Именно здесь в игру вступают adaptive-rx / adaptive-tx. Идея заключается в том, что драйвер постоянно отслеживает рабочую нагрузку (количество получаемых кадров в секунду, размер кадра и т. Д.) И настраивает схему объединения аппаратных прерываний для оптимизации задержки в ситуациях с низким трафиком или оптимизации пропускной способности в ситуациях с высоким трафиком. Это классная теория, но ее сложно реализовать на практике. Лишь несколько драйверов реализуют это (см. http://fxr.watson.org/fxr/search?v=linux-2.6&string=use_adaptive_rx_coalesce), а драйверов bnx2 / e1000 нет в этом списке.
Для хорошего описания того, как должно работать каждое объединяющее поле ethtool, взгляните на определения для структуры ethtool_coalesce по следующему адресу:
http://fxr.watson.org/fxr/source/include/linux/ethtool.h?v=linux-2.6#L111
Для вашей конкретной ситуации (пропускная способность ~ 400 Мбит / с) я бы предложил настроить значения rx-frames и rx-usecs для наилучших настроек для вашей рабочей нагрузки. Посмотрите на накладные расходы ISR, а также на чувствительность вашего приложения (httpd? И т. Д.) К задержке.
Дэйв