Что происходит после того, как пакет получен?

Я читал о том, что происходит после того, как пакеты получены NICs, и чем больше я читал, тем больше я смущен.

Во-первых, я считал, что традиционно, после того, как пакет получен NIC, он копируется в блок памяти в пространстве ядра, затем к пространству пользователя для любого приложения, которое затем работает над пакетными данными. Затем я читал о DMA, где NIC непосредственно копирует пакет в память, обходя ЦП. Так NIC-> память ядра-> поток памяти Пространства пользователя, все еще допустимый? Кроме того, большая часть NIC (например, Myricom) используют DMA для улучшения уровней захвата пакетов?

Во-вторых, RSS (Получают Масштабирование Стороны), работа так же и в Windows и в системах Linux? Я могу только найти подробные объяснения о том, как RSS работает в статьях MSDN, где они говорят о том, как RSS (и MSI-X) работает над Windows Server 2008. Но то же понятие RSS и MSI-X должно все еще примениться к системам Linux, правильно?

Спасибо.

С уважением, Рэйни

10
задан Rayne 30 March 2010 в 03:14
поделиться

2 ответа

взгляните на этот документ, http://www.ece.virginia.edu/cheetah/documents/papers/TCPlinux.pdf он может помочь прояснить некоторые вопросы управления памятью

0
ответ дан 3 December 2019 в 23:12
поделиться

Каким будет этот процесс, в основном зависит от автора драйвера и оборудования, но для драйверов, которые я просмотрел или написал, и оборудования, с которым я работал, это Обычно это работает:

  1. При инициализации драйвера он выделяет некоторое количество буферов и передает их сетевой карте.
  2. Когда сетевой адаптер получает пакет, он извлекает следующий адрес из своего списка буферов, DMA помещает данные прямо в него и уведомляет драйвер через прерывание.
  3. Драйвер получает прерывание и может либо передать буфер ядру, либо он выделит новый буфер ядра и скопирует данные. «Сеть с нулевым копированием» является первым и, очевидно, требует поддержки со стороны операционной системы. (подробнее об этом ниже)
  4. Драйвер должен либо выделить новый буфер (в случае нулевого копирования), либо он будет повторно использовать буфер. В любом случае буфер возвращается сетевой карте для будущих пакетов.

Сеть с нулевым копированием в ядре не так уж и плоха. Нулевое копирование вплоть до уровня пользователя намного сложнее. Userland получает данные, но сетевые пакеты состоят из заголовка и данных. По крайней мере, для истинного нулевого копирования на всем пути к пользовательской среде требуется поддержка вашего сетевого адаптера, чтобы он мог передавать пакеты DMA в отдельные буферы заголовков / данных. Заголовки перерабатываются после того, как ядро ​​направляет пакет к месту назначения и проверяет контрольную сумму (для TCP, либо аппаратно, если сетевая карта поддерживает его, либо программно, если нет; обратите внимание, что если ядро ​​должно вычислить контрольную сумму само, оно бы может также копировать данные: просмотр данных вызывает промахи в кеше, а копирование в другое место может быть бесплатно с настроенным кодом).

Даже если предположить, что все звездочки выровнены, данные фактически не находятся в вашем пользовательском буфере, когда они принимаются системой. Пока приложение не запросит данные, ядро ​​не знает, где они окажутся. Рассмотрим случай многопроцессного демона, такого как Apache.Есть много дочерних процессов, которые слушают один и тот же сокет. Вы также можете установить соединение fork () , и оба процесса смогут recv () входящие данные.

Пакеты TCP в Интернете обычно содержат 1460 байтов полезной нагрузки (MTU 1500 = 20 байтов заголовка IP + 20 байтов заголовка TCP + 1460 байтов данных). 1460 - это не степень двойки, и она не будет соответствовать размеру страницы ни в одной из найденных вами систем. Это создает проблемы для повторной сборки потока данных. Помните, что TCP ориентирован на потоки. Нет различия между записью отправителя, и две записи по 1000 байт, ожидающие получения, будут полностью использованы при чтении 2000 байт.

В дальнейшем рассмотрим пользовательские буферы. Они выделяются приложением. Для того, чтобы его можно было полностью использовать для нулевого копирования, буфер должен быть выровнен по страницам и не должен разделять эту страницу памяти с чем-либо еще. Во время recv () ядро ​​теоретически могло бы переназначить старую страницу на страницу, содержащую данные, и «перевернуть» ее на место, но это осложняется проблемой повторной сборки, описанной выше, поскольку последующие пакеты будут отправляться по отдельности. страниц. Ядро может ограничить возвращаемые данные полезной нагрузкой каждого пакета, но это будет означать множество дополнительных системных вызовов, переназначение страниц и, вероятно, более низкую пропускную способность в целом.

Я на самом деле только поверхностно касаюсь этой темы. В начале 2000-х я работал в нескольких компаниях, пытаясь распространить концепцию нулевого копирования на пользовательскую среду.Мы даже реализовали стек TCP в пользовательском пространстве и полностью обошли ядро ​​для приложений, использующих стек, но это принесло свой собственный набор проблем и никогда не было производственным качеством. Это очень сложная проблема.

14
ответ дан 3 December 2019 в 23:12
поделиться
Другие вопросы по тегам:

Похожие вопросы: