Фон:
Затраты на системные вызовы намного больше, чем на вызовы функций (оценки варьируются от 20 до 100x), в основном из-за переключения контекста из пространства пользователя в пространство ядра и обратно. Обычно встроенные функции сохраняют накладные расходы на вызовы функций, а вызовы функций намного дешевле, чем системные вызовы. Разумеется, разработчики хотели бы избежать некоторых накладных расходов на системные вызовы, заботясь о как можно большем количестве операций в ядре за один системный вызов.
Проблема:
Это создало много (лишние?) Системные вызовы , как sendmmsg () , recvmmsg () , а также Chdir, открытый, lseek и / или символические ссылки сочетаний , как: openat
, mkdirat
, mknodat
, fchownat
, futimesat
, newfstatat
, unlinkat
, fchdir
, ftruncate
, fchmod
, renameat
, linkat
, symlinkat
, readlinkat
, fchmodat
, faccessat
, lsetxattr
, fsetxattr
, execveat
, lgetxattr
, llistxattr
, lremovexattr
, fremovexattr
, flistxattr
, fgetxattr
, pread
, и pwrite
т.д. ...
Теперь Linux добавил, copy_file_range()
что, по-видимому, объединяет системные вызовы read lseek и write. Это только вопрос времени, прежде чем это станет fcopy_file_range (), lcopy_file_range (), copy_file_rangeat (), fcopy_file_rangeat () и lcopy_file_rangeat () ... но, так как вместо X больше вызовов задействовано 2 файла, он может стать X ^ 2 Больше. Ладно, Линус и различные разработчики BSD не позволили бы ему зайти так далеко, но я хочу сказать, что, если бы был системный вызов в пакетном режиме, все (большинство?) Могли бы быть реализованы в пользовательском пространстве и уменьшить сложность ядра, не добавляя много если какие-либо накладные расходы на стороне libc.
Было предложено много сложных решений, которые включают в себя специальный поток системных вызовов для неблокирующих системных вызовов для пакетных системных вызовов; однако эти методы значительно усложняют как ядро, так и пользовательское пространство во многом так же, как libxcb и libX11 (асинхронные вызовы требуют гораздо большей настройки)
Решение?:
Общий пакетный системный вызов. Это позволило бы снизить наибольшую стоимость (переключение нескольких режимов) без сложностей, связанных с наличием специализированного потока ядра (хотя эта функциональность могла бы быть добавлена позже).
По сути, в syscall socketcall () уже есть хорошая основа для прототипа. Просто расширите его от получения массива аргументов до взятия массива возвратов, указателя на массивы аргументов (который включает в себя номер системного вызова), количества системных вызовов и аргумента flags ... что-то вроде:
batch(void *returns, void *args, long ncalls, long flags);
Одним из основных отличий будет то , что аргументы, вероятно , все нужно быть указатели для простоты так , что результаты предыдущих системных вызовов могут быть использованы в последующих системных вызовов (например , дескриптор файла из open()
для использования в read()
/ write()
)
Некоторые возможные преимущества:
- меньше пользовательского пространства -> пространство ядра -> переключение пользовательского пространства
- возможный ключ компилятора -fcombine-syscalls для автоматической пакетной обработки
- необязательный флаг для асинхронной операции (возврат fd для просмотра немедленно)
- возможность реализации будущих комбинированных функций системного вызова в пользовательском пространстве
Вопрос:
Возможно ли реализовать пакетный системный вызов?
- Я пропускаю некоторые очевидные ошибки?
- Я переоцениваю преимущества?
Стоит ли мне беспокоиться о реализации пакетного системного вызова (я не работаю в Intel, Google или Redhat)?
- Я уже исправил свое собственное ядро, но боюсь иметь дело с LKML.
- История показала, что даже если что-то широко полезно для «обычных» пользователей (не корпоративных конечных пользователей, не имеющих доступа к git-записи), оно никогда не может быть принято в апстриме (unionfs, aufs, cryptodev, tuxonice и т. Д.)
Ссылки:
batch
системных вызовов вbatch
системные вызовы, вы можете создать сколь угодно глубокое дерево вызовов произвольных системных вызовов. По сути, вы можете поместить все приложение в один системный вызов.