Лучший способ передачи больших данных из ядра в пользовательское пространство

Мне нужно передавать несколько мегабайт данных в секунду из модуля ядра Linux в пользовательское пространство, и я не хочу пропустить ни одного сообщения из модуля, если я его прочитаю. Как лучше всего это сделать?

Для этого существует несколько возможных решений: Named-Pipes, Proc-File и Block-Device. Но я не уверен, какое из них выбрать и какое из них обещает наилучшую производительность, поскольку я новичок в ядре.

На данный момент я использую кольцевой буфер (со спин-блокировками) в модуле ядра для хранения сообщений, и если считывается файл Proc, я помещаю данные из кольцевого буфера в файл Proc; на стороне пользователя у меня есть программа, которая многократно запускает cat /proc/procfile и показывает результат. Проблема с этими решениями заключается в том, что вместо получения

СООБЩЕНИЕ 1 СООБЩЕНИЕ 2 СООБЩЕНИЕ 3

на выходе вижу (иногда раз в несколько тысяч сообщений)

СООБЩЕНИЕ 1 СООБЩЕНИЕ3


person markus    schedule 07.12.2010    source источник


Ответы (4)


Всегда можно реализовать то, что я называю «системным вызовом для бедняков»: создать символьное устройство, а затем создать собственный ioctl с любой семантикой, которую вы хотите.

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

При осторожном использовании атомарных переменных и спин-блокировок вы сможете гарантировать быстрый и безопасный доступ к данным даже в нескольких потоках, если это необходимо.

person Eric Seppanen    schedule 08.12.2010

Вероятно, вы захотите использовать интерфейс реле, ранее известный как relayfs.

См. Documentation/filesystems/relay.txt.

Оттуда:

Интерфейс ретрансляции предоставляет приложениям ядра средства для эффективной регистрации и передачи больших объемов данных из ядра в пространство пользователя через определяемые пользователем «каналы ретрансляции».

person mpe    schedule 08.12.2010

Я считаю, что символьное устройство будет для вас хорошим решением .

person Oleksandr Kravchuk    schedule 07.12.2010

Можно использовать многие методы. Однако Netlink не является одним из них, потому что это ненадежный транспорт (например, UDP). Символьное устройство кажется подходящим, хотя вы также можете использовать сокет TCP (см. nfsd).

person user502515    schedule 08.12.2010