Sendfile в дескрипторе файла символьного устройства - PullRequest
0 голосов
/ 08 января 2019

У меня есть ПЛИС на SoC, которая непрерывно генерирует и передает огромное количество данных, которые извлекаются с помощью операций dma и помещаются в ОЗУ. Затем он должен быть отправлен в сеть через порт Ethernet с битрейтом, приближающимся к гигабит / с. Чтобы эффективно обрабатывать большие объемы передаваемых данных, я решил использовать системный вызов sendfile из пространства пользователя. Поскольку sendfile использует механизм сращивания, мой драйвер устройства поддерживает операции сращивания.

К сожалению, sendfile возвращает -EINVAL, когда дескриптор входного файла - это файл моего символьного устройства, поддерживаемый моим драйвером. После дальнейшего исследования кажется, что ядро ​​Linux отказывается от любого файла, отличного от обычного или блочного. Вот что говорит источник ядра Linux здесь :

/*
 * We require the input being a regular file, as we don't want to
 * randomly drop data for eg socket -> socket splicing. Use the
 * piped splicing for that!
 */
i_mode = file_inode(in)->i_mode;
if (unlikely(!S_ISREG(i_mode) && !S_ISBLK(i_mode)))
    return -EINVAL;

Справочная страница для sendfile (2), кажется, говорит то же самое:

Аргумент in_fd должен соответствовать файлу, который поддерживает mmap (2) -подобные операции (т. Е. Он не может быть сокетом).

Почему это? Я не очень хорошо понимаю техническую причину, которая запрещает этот случай, то есть использование sendfile в качестве дескриптора файла символьного устройства в качестве ввода.

...