Antecedentes:
La sobrecarga de llamadas del sistema es mucho mayor que la sobrecarga de llamadas de función (el rango de estimaciones es de 20-100x) principalmente debido al cambio de contexto del espacio del usuario al espacio del kernel y viceversa. Es común que las funciones en línea ahorren sobrecarga de llamadas a funciones y las llamadas a funciones son mucho más baratas que las llamadas al sistema. Es lógico que los desarrolladores deseen evitar parte de la sobrecarga de llamadas del sistema al ocuparse de la mayor cantidad posible de operaciones en el núcleo en una llamada al sistema.
Problema:
Esto ha creado una gran cantidad de (superfluos?) Llamadas al sistema como sendmmsg () , recvmmsg () , así como la chdir, abierto, lseek y / o combinaciones de enlaces simbólicos como: 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
etc ...
Ahora se ha agregado Linux, copy_file_range()
que aparentemente combina lecturas de lseek y syscalls de escritura. Es solo una cuestión de tiempo antes de que esto se convierta en fcopy_file_range (), lcopy_file_range (), copy_file_rangeat (), fcopy_file_rangeat () y lcopy_file_rangeat () ... pero dado que hay 2 archivos involucrados en lugar de X llamadas más, podría convertirse en X ^ 2 más. De acuerdo, Linus y los diversos desarrolladores de BSD no lo dejarían ir tan lejos, pero mi punto es que si hubiera una syscall por lotes, todos (¿la mayoría?) Podrían implementarse en el espacio del usuario y reducir la complejidad del kernel sin agregar mucho si hay alguna sobrecarga en el lado de la biblioteca.
Se han propuesto muchas soluciones complejas que incluyen alguna hebra especial de syscall para llamadas syscall sin bloqueo para llamadas syscalls de proceso por lotes; sin embargo, estos métodos agregan una complejidad significativa tanto al kernel como al espacio del usuario de la misma manera que libxcb vs. libX11 (las llamadas asincrónicas requieren mucha más configuración)
¿Solución?:
Un syscall genérico por lotes. Esto aliviaría el mayor costo (conmutadores de modo múltiple) sin las complejidades asociadas con tener un hilo de kernel especializado (aunque esa funcionalidad podría agregarse más adelante).
Básicamente, ya existe una buena base para un prototipo en la llamada al sistema socketcall (). Simplemente extiéndalo de tomar una matriz de argumentos para tomar una matriz de retornos, puntero a matrices de argumentos (que incluye el número de syscall), el número de syscalls y un argumento de banderas ... algo como:
batch(void *returns, void *args, long ncalls, long flags);
Una diferencia importante sería que los argumentos probablemente toda necesidad de ser punteros para simplicidad de manera que los resultados de las llamadas al sistema anteriores podrían ser utilizados por llamadas al sistema posteriores (por ejemplo, el descriptor de archivo de open()
para su uso en read()
/ write()
)
Algunas posibles ventajas:
- menos espacio de usuario -> espacio de kernel -> cambio de espacio de usuario
- posible compilador conmutador -fcombine-syscalls para tratar de procesar automáticamente
- Indicador opcional para operación asincrónica (devuelva fd para mirar inmediatamente)
- capacidad para implementar futuras funciones combinadas de syscall en el espacio de usuario
Pregunta:
¿Es factible implementar una syscall por lotes?
- ¿Me estoy perdiendo algunas trampas obvias?
- ¿Estoy sobreestimando los beneficios?
¿Me vale la pena molestarme en implementar un syscall por lotes (no trabajo en Intel, Google o Redhat)?
- He parcheado mi propio kernel antes, pero temo tratar con el LKML.
- La historia ha demostrado que incluso si algo es ampliamente útil para los usuarios "normales" (usuarios finales no corporativos sin acceso de escritura git), es posible que nunca se acepte en sentido ascendente (unionfs, aufs, cryptodev, tuxonice, etc.)
Referencias
batch
syscalls enbatch
syscalls, puede crear un árbol de llamadas arbitrariamente profundas de syscalls arbitrarias. Básicamente, puede poner toda su aplicación en una sola llamada al sistema.