Почему в ядре Linux нет сети с нулевым копированием?

Я хотел бы знать причины, по которым ядро ​​Linux (или любая другая основная ОС) не имеет функции для работы в сети с нулевым копированием? Под нулевой копией я подразумеваю, что пакет/поток данных не копируется для передачи в приложение в пользовательском пространстве, а, например. использует распределитель типа пула памяти для разделения памяти между ядром и пользовательским пространством. Я придумал 3 теории самостоятельно:

а) Я предполагаю, что есть проблемы с безопасностью. Но неужели нет никакого способа безопасно разделить память между пользовательским пространством и ядром, когда они просто используются в качестве буфера?

б) Я предполагаю, что есть проблемы со стабильностью. Но разве мы не можем предположить, что тот, кто использует сеть с нулевым копированием и, например, нужно создать экземпляр и передать пул памяти, чтобы вызов ядра знал об управлении памятью? Достаточно осведомлены, чтобы избежать утечек?

c) Это просто еще не сделано/не нужно. Я не могу себе представить, чтобы никто не запрашивал эту функцию, поскольку все, кто использует небольшие размеры пакетов, обычно ограничены «медленной» реализацией TCP-стека, и есть сторонние инструменты, предлагаемые для сети с нулевым копированием для использования со специальными сетевые карты.

Не стесняйтесь публиковать любые предположения, но, пожалуйста, отметьте, предполагаете ли вы или имеете более глубокие знания о причинах сохранения качества StackOverflow :-)


person user1610743    schedule 03.03.2014    source источник
comment
Что ж, у Linux есть такая функциональность, проблема только в том, что а) некоторые вещи не тривиальны, чтобы сделать их правильно, но они реализовали что-то до того, как подумали об этих деталях, и б) документация, мягко говоря, плохая. в мере. Если вам интересно, загляните в splice, tee и vmsplice. Они позволяют копировать между сокетами, файлами и каналами (буферы ядра), дублировать каналы (счетчик ссылок на страницы) и копировать между пользователем и пространством ядра путем переназначения страниц. Так много для хорошей теории, на практике вы получаете страницы, которые вы можете не трогать и не знаете, когда освободить ... и бле.   -  person Damon    schedule 03.03.2014
comment
Проверьте источник для haproxy. Он использует splice и каналы для предотвращения копирования через пользовательское пространство (источник немного груб для прохождения из-за цикла событий и использования пула каналов). Я слышал, что автор haproxy работает над патчем ядра для прямого соединения сокетов, но не уверен, что это действительно будет быстрее.   -  person JimB    schedule 04.03.2014
comment
См. также RoCE.   -  person Nemo    schedule 24.10.2018


Ответы (1)


В настоящее время существует несколько вариантов организации сети с нулевым копированием:

Обратите внимание, что нулевое копирование с TCP может быть неудобным, потому что сегменты TCP несут заголовки и полезные данные, а приложения имеют дело только с полезными данными, поэтому полезные данные, но не заголовки, должны быть скопированы в непрерывный буфер для вашего приложения.

person Maxim Egorushkin    schedule 03.03.2014
comment
Заголовки сегментов могут быть веской причиной, по которой он еще не является стандартным. Тем не менее, я не возражал бы против того, может ли мое приложение их видеть или нет, и я не вижу причины для копии полезной нагрузки, поскольку это снижает производительность моего приложения. +1 - person user1610743; 03.03.2014
comment
@user1610743 user1610743 В C++ может быть готовый итератор, который пропускает заголовки фреймов и выполняет итерацию только по полезной нагрузке. - person Maxim Egorushkin; 24.11.2014
comment
@PeterCordes Обновлены ссылки. - person Maxim Egorushkin; 09.01.2020