Menos é mais no Linux 6.19. O subsistema de gerenciamento de energia passou por um pequeno, porém simbólico, API refactoring na função pm_runtime_barrier(). A mudança, integrada em 6.19-rc1 a partir da árvore de power management de Rafael Wysocki, com patches de Brian Norris, mira diretamente o dia a dia de quem escreve drivers: tornar o uso de Runtime PM mais claro, menos racy e menos verboso. Para quem acompanha a evolução da API, esta é a atualização em torno de Linux 6.19 pm_runtime_barrier que realmente importa.
O que exatamente mudou em pm_runtime_barrier()
A alteração é simples na superfície, mas importante em termos de design de API:
- Antes:
int pm_runtime_barrier(struct device *dev); - Agora:
void pm_runtime_barrier(struct device *dev);
A documentação de Runtime PM foi atualizada para refletir essa nova assinatura: pm_runtime_barrier() continua sendo descrita como a função que verifica se há um pedido de resume pendente para o dispositivo, força esse resume de forma síncrona se necessário, cancela outras requisições de Runtime PM em fila e espera todas as operações em andamento terminarem. Em suma, ela atua como uma barrier de sincronização para o pipeline de Runtime PM de um struct device.
Em configurações sem suporte a PM (!CONFIG_PM), o stub em include/linux/pm_runtime.h também foi ajustado: em vez de retornar 0, agora é uma função void com corpo vazio, mantendo o comportamento de “no-op” esperado e evitando que builds sem PM quebrem ao compilar drivers atualizados.
O problema do valor de retorno racy
Historicamente, pm_runtime_barrier() retornava:
1se havia um pedido de resume pendente e o dispositivo precisava ser acordado,0caso contrário.
Na prática, isso se mostrou problemático por pelo menos três motivos:
- Pouco uso real
A maioria dos chamadores simplesmente ignorava o retorno. Nas poucas ocorrências onde o valor era testado, ele raramente influenciava uma decisão robusta de fluxo de controle. - Semântica confusa
A função é, conceitualmente, uma barrier de Runtime PM, não uma primitiva de consulta de estado. Misturar “sincronização” com “descobrir se houve resume” levava desenvolvedores a tratarpm_runtime_barrier()como se fosse um atalho para saber se o dispositivo está ativo, o que nunca foi um contrato formal da API. - Retorno intrinsecamente racy
Mesmo que o código checasse o retorno e assumisse “se foi 1, então o dispositivo está acordado agora”, essa suposição é frágil. Novas requisições de Runtime PM podem chegar imediatamente após a barreira; o estado de energia é dinâmico e pode mudar logo depois da chamada. Em outras palavras, o retorno nunca foi uma fonte estável de verdade sobre o estado do dispositivo, apenas um detalhe de implementação exposto demais.
Ao migrar para um void return type, o kernel reforça a intenção correta da função: pm_runtime_barrier() é usada para garantir que as operações de Runtime PM pendentes foram drenadas até aquele ponto, não para responder “o dispositivo está ativo?”.
Como usar pm_runtime_barrier() na prática
Para o desenvolvedor de driver, o novo contrato simplifica tanto o código quanto o modelo mental. Em vez de pensar em 0/1, basta tratar a função como uma barreira que “limpa a fila” de Runtime PM.
Alguns cenários típicos de uso:
- Antes de acessar registradores sensíveis após atividade assíncrona
Se o driver disparou operações de Runtime PM (por exemplo, por meio depm_runtime_get()ou caminhos que podem agendar resumes assíncronos), chamarpm_runtime_barrier(dev)garante que qualquer resume pendente terminou antes de mexer no hardware de forma crítica. - Nos caminhos de
.remove()ou.shutdown()
Quando o driver está desmontando o dispositivo, desativando clocks ou reguladores manualmente, é prudente garantir que não existe nenhum resume atrasado prestes a rodar contra um hardware já parcialmente desmontado. A barreira serve justamente para “esvaziar” essa fila. - Em caminhos de erro durante a inicialização
Se a inicialização do driver agenda operações de Runtime PM, mas falha e precisa abortar, chamar a barreira antes de liberar recursos evita que callbacks de PM rodem depois que o estado de software/hardware já foi revertido.
Na forma nova, o padrão típico fica mais direto:
/* Garantir que não há resume/suspend pendente antes de mexer no HW */
pm_runtime_barrier(dev);
/* A partir daqui, não há operações de Runtime PM em voo para este device */Não há mais variável temporária, nem checagem de “erro” que nunca foi realmente um erro.
Impacto em drivers existentes e árvores out-of-tree
Para quem mantém drivers no mainline, as mudanças já chegaram junto com os patches de limpeza que removem checagens de retorno desnecessárias. Para quem mantém árvores out-of-tree, o recado é:
- Atualizar assinatura e chamadas
Ajustar as declarações/headers locais para a nova assinaturavoid pm_runtime_barrier(struct device *dev);e remover qualquer atribuição do retorno a variáveis. - Eliminar checagens inúteis de retorno
Códigos como:int ret; ret = pm_runtime_barrier(dev); if (ret < 0) return ret;devem ser convertidos em uma simples chamada sem validação de retorno.pm_runtime_barrier()não representa uma operação que falha com códigos de erro. - Não recriar consultas de estado por conta própria
Tentar substituir a antiga checagem0/1por leituras diretas de campos internos dedev->powerou por combinações depm_runtime_status_*()para tentar derivar “se houve resume” é andar para trás. O patch justamente remove essa ambiguidade; se o driver precisa de uma decisão baseada no estado de energia, deve usar as primtivas próprias de consulta de estado, não a barreira.
Em resumo, a migração correta é: manter o uso da função como barrier de sincronização e abandonar qualquer lógica que trate o retorno como sinalizador de estado.
Testes, Coccinelle e limpeza da API como um todo
A mudança em pm_runtime_barrier() não veio sozinha. O ecossistema ao redor da API de Runtime PM foi ajustado para reforçar o novo contrato:
- KUnit / runtime-test
O teste de Runtime PM emdrivers/base/power/runtime-test.c, adicionado no ciclo anterior, foi atualizado para parar de depender do valor de retorno da função. Em vez de verificar0ou1, o teste passa a observar diretamente o comportamento do dispositivo (ativo, suspenso, transições bem-sucedidas) após a chamada da barreira. - Coccinelle / análise estática
O scriptscripts/coccinelle/api/pm_runtime.coccideixou de listarpm_runtime_barrier()entre as funções tratadas como retornando códigos relevantes. Isso evita que novos padrões orientem o desenvolvedor a armazenar e checar retornos inexistentes, e ajuda a “educar” o código para a nova forma de uso: chamar e seguir em frente. - Documentação atualizada
O arquivoDocumentation/power/runtime_pm.rstfoi limpo para remover a menção ao retorno1quando um resume era necessário e0caso contrário. A descrição agora reforça apenas a semântica de barreira: verificar pendências, retomar o dispositivo se preciso, cancelar requisições restantes e aguardar todas as operações em andamento.
Com testes, documentação e ferramentas alinhados, a mudança deixa de ser apenas uma alteração de assinatura e passa a ser uma pequena, porém sólida, evolução de design da API de Runtime PM.
Menos é mais no Runtime PM do Linux 6.19
No fim das contas, a refatoração de pm_runtime_barrier() em Linux 6.19 é um caso clássico de “menos é mais” aplicado à API de power management. Remover um valor de retorno pouco útil e racy:
- reduz ruído em drivers,
- elimina checagens de erro que nunca foram erro,
- reforça a leitura correta da função como uma barrier de sincronização de Runtime PM,
- e alinha documentação, testes e ferramentas de análise estática ao mesmo contrato.
Para quem vive mergulhado em código de driver, é exatamente o tipo de micro-ajuste que faz o código ficar mais legível e previsível sem exigir uma reescrita massiva.
