Seu Linux travando em ARM64? Descobrimos o motivo — e a correção vem aí

Escrito por
Emanuel Negromonte
Emanuel Negromonte é Jornalista, Mestre em Tecnologia da Informação e atualmente cursa a segunda graduação em Engenharia de Software. Com 14 anos de experiência escrevendo sobre...

Travamento raro em ARM64 expõe por que imprimir logs no lugar errado derruba o sistema.

Tem hora que o Linux dá aquela travada “do nada” em ARM64 — e foi exatamente isso que uma bateria pesada de testes expôs. Durante stress tests com stress-ng, um bug raro virou hard lockup: a máquina congelava por completo. O que parecia um caso isolado acabou revelando uma lição importante sobre o que não fazer em caminhos críticos do kernel: chamar printk() no lugar errado.

O que estava acontecendo nos bastidores

O roteiro do problema é quase um dominó. O stress-ng chamava a interface de debugfs clear_warn_once, que zera a seção de memória responsável por mensagens do tipo pr_info_once() — aquelas que deveriam aparecer só uma vez. Com isso, toda nova rodada de teste “rearmava” o aviso. Se, por azar, isso coincidia com o teste pty06 do LTP usando o serial, a impressão de log acontecia no pior momento possível: no caminho de troca de tarefas do escalonador, onde rq_lock já estava segurado.

0MqgZbm0 image 1
Seu Linux travando em ARM64? Descobrimos o motivo — e a correção vem aí 3

E aí vem a queda: printk() precisa destravar o console (console_unlock()), que por sua vez acorda tarefas e tenta re-adquirir o mesmo lock do escalonador (via try_to_wake_up()ttwu_queue()rq_lock) — um A–A deadlock clássico. Resultado: hard lockup e queda geral. Em linguagem direta: um aviso de console, repetido por causa do reset de clear_warn_once, trombou com locks do escalonador e derrubou o sistema.

O patch inicial… e o diagnóstico de raiz

A primeira reação foi trocar o pr_info_once() por um controle local com atomic_cmpxchg() — uma forma de garantir que o aviso apareça de fato só uma vez, mesmo que clear_warn_once tente “resetar” tudo. Ajuda? Ajuda. Mas os mantenedores de ARM64 foram além: Catalin Marinas e Mark Rutland apontaram que o problema verdadeiro não é “quantas vezes” a gente imprime, e sim onde a gente imprime. printk() em caminho sensível do escalonador (debaixo de locks) é pedir para sofrer. A orientação deles foi cirúrgica: remover a impressão desse caminho (no caso, relacionado à mitigação da Spectre v4) e mover o log para um ponto seguro do boot — por exemplo, via um initcall junto de setup_system_capabilities().

Por que isso importa (e muito)

Esse é o tipo de Linux ARM64 bug que não aparece em toda máquina, todo dia — mas quando aparece, dói. E ensina. A moral da história é que printk() pode encadear wakeups, semáforos e outras interações que não combinam com locks do escalonador. Evitar logs em accessors de estado ou em caminhos que seguram rq_lock é higiene de código que paga dividendos em estabilidade e segurança (especialmente perto de mitigação de Spectre).

O que esperar nas próximas versões

A limpeza dessas impressões nos caminhos sensíveis deve chegar em breve ao mainlinepossivelmente a partir do 6.18 — junto de ajustes mais amplos para que mecanismos do tipo *_ONCE não voltem a ser rearmados de maneira perigosa por clear_warn_once. Se você mantém distros, kernels customizados ou infra de testes, vale acompanhar os próximos pulls da arquitetura ARM64 e dos subsistemas de scheduler e printk.

Compartilhe este artigo