BookinglyTech News
Software

IO_uring ataca el coste del bloqueo: Axboe traslada la identidad del hilo

El responsable de IO_uring publica una serie RFC que evita el desvío a io-wq de las peticiones que no bloquean, pagando el offload solo cuando de verdad hace falta.

2 min de lecturaPhoronix0 vistas

Jens Axboe, responsable del subsistema de bloques de Linux y desarrollador principal de IO_uring, ha publicado una serie de parches RFC que cambia cómo el framework trata las peticiones que el kernel no sabe resolver sin bloquear. Él mismo las ha llamado "crazy" en X y ha acompañado el envío con gráficas de lo que llama "tasty results". La idea: dejar de pagar por adelantado el desvío a io-wq y cobrarlo solo cuando la operación realmente se bloquea.

El desvío que se paga siempre

IO_uring lanza las peticiones en línea con IO_URING_F_NONBLOCK y las manda a io-wq cuando eso no es posible. Hay un montón de opcodes para los que no existe camino no bloqueante en el kernel: fsync, statx, openat, toda la familia *at, xattr, fadvise, splice y compañía. Esos se desvían sin condiciones, y cada desvío cuesta un despertar de hilo, un cambio de contexto y un viaje de vuelta por task_work por cada petición.

El framework no puede arriesgarse. Aunque la operación no vaya a bloquearse casi nunca, no tiene forma de saberlo de antemano: un fdatasync que no bloquea, un statx que acierta en la dcache o un openat para O_TMPFILE se habrían completado en línea sin problema, pero IO_uring no puede apostar por ello.

Mover la identidad del que envía

Los parches invierten el criterio: emiten esas peticiones en línea en modo bloqueante y solo pagan el offload si la petición acaba bloqueándose. El escollo era que, para entonces, quien la envió está metido en el kernel con la petición en su propia pila, así que el trabajo ya no se puede mover a otro hilo.

Lo que sí se puede mover es la identidad. Si la tarea que envía se bloquea, un worker de io-wq libre asume su identidad visible desde el espacio de usuario —tid, estado de señales, credenciales, atributos de planificación, cgroup, estado de registros—, termina la llamada a io_uring_enter() y vuelve al espacio de usuario como si fuera el emisor. La tarea original acaba la petición como worker de io-wq y se reincorpora al pool. El mismo tid regresa de la syscall, solo que sobre otro task_struct.

Axboe recuerda que hubo intentos parecidos hace unos veinte años. Por ahora esto es una serie RFC, no código mergeado, y no hay cifras publicadas de las mejoras: solo las gráficas que ha enseñado el desarrollador. La ganancia dependerá de cuánto peso tenga ese desvío en cada carga de trabajo, así que en cargas con muchos fsync o statx debería notarse más que en otras. Queda por ver si el trabajo cuaja y llega a mainline en el ciclo de Linux v7.4, que es lo que él mismo apunta.