O Linux 6.19 traz uma mudança discreta no código, mas enorme no impacto cotidiano de quem vive de contêineres, VMs, snaps e imagens de disco: uma grande melhoria na Linux loop device performance. Graças a um patch de Ming Lei (Red Hat), recém-integrado por Jens Axboe na árvore de bloco do kernel, o driver de loop device ganhou um “caminho rápido” baseado em IOCB_NOWAIT para I/O assíncrono.
Na prática, isso significa que aquele disco virtual montado em /dev/loopX pode ficar quase tão rápido quanto o NVMe ou virtio-scsi que está por baixo, com ganhos de até 5x em cargas de I/O sequencial pesadas.
O fim da fila de espera no loop device
Antes do Linux 6.19, o caminho de I/O do loop device era bem mais burocrático. Mesmo quando a aplicação usava I/O assíncrono (AIO), o driver fazia praticamente a mesma coisa para todo mundo:
- Recebia o pedido de leitura ou escrita do bloco.
- Transformava isso em uma estrutura de comando (
loop_cmd). - Colocava esse comando em uma workqueue, atendida por uma thread de worker do loop.
- Só então o worker acordava, pegava o comando da fila e chamava o
read_iter()ouwrite_iter()do arquivo de backing (por exemplo, um arquivo em ext4 em cima de NVMe).
Analogia do banco: é como um atendimento em que toda operação é obrigada a pegar senha, mesmo que o caixa esteja literalmente sem ninguém na frente. Cada I/O precisa de pelo menos um agendamento de thread extra, com trocas de contexto, locking e toda a sobrecarga de passar por uma workqueue. Em cargas intensas de I/O, especialmente com múltiplos jobs sequenciais, essa fila artificial virava o gargalo, não o hardware.
Como funciona o novo caminho rápido (fast path) com IOCB_NOWAIT
O novo patchset reorganiza o caminho de I/O do loop e introduz um fast path baseado em IOCB_NOWAIT. A ideia é simples: se o dispositivo de backing conseguir atender o pedido imediatamente, o loop device “fura a fila” e executa o I/O direto, sem passar pelo worker.
O fluxo agora é, em alto nível:
- O loop device recebe o request e prepara os buffers (novos helpers como
lo_cmd_nr_bvec(),lo_rw_aio_prep()elo_submit_rw_aio()cuidam da montagem doiov_iter). - Se o I/O é feito via AIO e o arquivo de backing suporta modo não bloqueante (FMODE_NOWAIT), o driver tenta o modo NOWAIT chamando
read_iter()/write_iter()diretamente, com a flag IOCB_NOWAIT setada. - Se o backend consegue atender sem bloquear, o I/O é completado ali mesmo, no contexto atual. Zero workqueue, zero troca de contexto extra. Esse é o caminho rápido.
- Se o backend não consegue (por exemplo, precisa bloquear por causa de paginação ou mapeamento de bloco), ele devolve
-EAGAIN, e o driver cai automaticamente para o caminho antigo: o comando é enfileirado na workqueue, como antes.
Para não forçar NOWAIT em situações perigosas, o patch é conservador:
- Backends que já são block devices (como NVMe exposto como arquivo) são considerados sempre seguros para NOWAIT.
- Leituras (
REQ_OP_READ) são vistas como aceitáveis desde que não haja contenção com escritas bloqueantes. - Um novo contador,
lo_nr_blocking_writes, mede quantas escritas assíncronas estão de fato bloqueando na workqueue. Se esse número é maior que zero, o driver evita mandar mais escritas em NOWAIT, reduzindo contenção de mapeamento no sistema de arquivos. - Esse contador ainda aparece em um novo atributo sysfs (
nr_blocking_writes), útil para depuração e tuning.
Se o caminho rápido não se aplica ou falha, o “caminho lento” clássico continua existindo, com a mesma semântica de antes. Nenhum programa quebra, só passa a existir uma via expressa quando o kernel sabe que consegue seguir sem bloqueio.
5x mais rápido: o impacto real na performance
Segundo os testes de Ming Lei, em uma VM com backend NVMe e virtio-scsi em modo multi-queue, a performance de disco via loop ficou “muito próxima” da performance do dispositivo de bloco de backing. Em testes independentes, Mikulas Patocka verificou que um cenário com 12 jobs de I/O sequencial (típico de benchmarks com fio) teve um ganho de cerca de 5x no throughput, especialmente quando combinado com ajustes prévios no suporte a multi-queue do loop.(lwn.net)
Na prática, isso significa:
- Menos CPU gasta em trocas de contexto e gerenciamento de threads de worker.
- Menor latência por I/O, porque a operação não precisa “rodar o carrossel” da workqueue quando o hardware está livre.
- Um gap de performance muito menor entre acessar um arquivo diretamente no NVMe e acessar o mesmo arquivo via
/dev/loopX.
Importante: isso não quer dizer que todo sistema ficará 5x mais rápido. O ganho é mais visível em cenários de I/O sequencial pesado em loop devices (imagens de disco, snapshots, contêineres e VMs) com backends modernos que suportam I/O não bloqueante. Cargas totalmente aleatórias ou limitadas por CPU, rede ou storage remoto podem ver ganhos menores.
O que muda para contêineres, VMs, snaps e Android
Se você é sysadmin ou SRE, esse patch é praticamente um “upgrade grátis” para qualquer stack que dependa de loop devices:
- Imagens de VM montadas via loop (por exemplo, discos raw em hosts de virtualização simples) ficam mais próximas da performance do storage real.
- Snaps e outras tecnologias baseadas em imagens montadas em loop tendem a sofrer menos quando sob carga intensa de leitura e escrita.
- Contêineres e appliances que usam arquivos de backing em loop (inclusive em cenários embarcados) se beneficiam em operações de upgrade, migração e reconstrução de imagens.
- Casos reportados em Android com problemas de performance envolvendo loop devices também devem ser impactados positivamente por essa abordagem, segundo os relatos apresentados na discussão do patch.
Para o usuário final, isso aparece como atualizações mais rápidas, menos “engasgos” em I/O pesado dentro de VMs e contêineres e um uso de CPU mais eficiente no host.
Quando essa melhoria chega até você
O patch “loop: improve loop aio perf by IOCB_NOWAIT” foi integrado por Jens Axboe na árvore for-6.19/block, o que significa que ele está programado para fazer parte do ciclo do Linux 6.19, salvo regressões de última hora.(lwn.net)
Você não precisa mudar scripts, opções de montagem ou aplicações. Basta rodar um kernel que contenha essa série de patches e:
- qualquer loop device configurado com I/O direto (LO_FLAGS_DIRECT_IO) e um backend compatível com NOWAIT começa a usar o novo fast path;
- o caminho antigo com workqueue continua existindo como fallback seguro, preservando compatibilidade.
Para quem compila o próprio kernel ou mantém distribuições, essa é uma forte candidata a backport para kernels focados em workloads de contêineres e virtualização, já que entrega uma melhoria clara de Linux loop device performance com risco controlado.
