From: Daniel Pereira <danielmaraboo@gmail.com>
To: corbet@lwn.net
Cc: linux-doc@vger.kernel.org, Daniel Pereira <danielmaraboo@gmail.com>
Subject: [PATCH v2 5/7] docs: pt_BR: process: translate botching-up-ioctls guide
Date: Fri, 3 Jul 2026 14:05:45 -0300 [thread overview]
Message-ID: <20260703170552.174764-6-danielmaraboo@gmail.com> (raw)
In-Reply-To: <20260703170552.174764-1-danielmaraboo@gmail.com>
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain; charset=y, Size: 16649 bytes --]
Translate the 'botching-up-ioctls' documentation into Brazilian
Portuguese, ensuring precise technical alignment with the upstream
source guidelines.
The translation covers critical driver-private API design concepts,
including fixed-sized integers, structure padding, error path
validation rules, and handling asynchronous hardware timeouts.
Signed-off-by: Daniel Pereira <danielmaraboo@gmail.com>
---
Documentation/translations/pt_BR/index.rst | 1 +
.../pt_BR/process/botching-up-ioctls.rst | 256 ++++++++++++++++++
2 files changed, 257 insertions(+)
create mode 100644 Documentation/translations/pt_BR/process/botching-up-ioctls.rst
diff --git a/Documentation/translations/pt_BR/index.rst b/Documentation/translations/pt_BR/index.rst
index 08faaacf3..4a13b3d14 100644
--- a/Documentation/translations/pt_BR/index.rst
+++ b/Documentation/translations/pt_BR/index.rst
@@ -70,6 +70,7 @@ kernel e sobre como ver seu trabalho integrado.
Guia do Processo de Desenvolvimento <process/development-process>
Como aplicar patches <process/applying-patches>
Backporting e resolução de conflitos <process/backporting>
+ Como não Deixar as ioctls malfeitas <process/botching-up-ioctls>
Index de documentos do Kernel <process/kernel-docs>
Regras de licenciamento <process/license-rules>
Como começar <process/howto>
diff --git a/Documentation/translations/pt_BR/process/botching-up-ioctls.rst b/Documentation/translations/pt_BR/process/botching-up-ioctls.rst
new file mode 100644
index 000000000..193297619
--- /dev/null
+++ b/Documentation/translations/pt_BR/process/botching-up-ioctls.rst
@@ -0,0 +1,256 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+============================================
+(Como evitar) Deixar as ioctls malfeitas
+============================================
+
+De: https://blog.ffwll.ch/2013/11/botching-up-ioctls.html
+
+Por: Daniel Vetter, Copyright © 2013 Intel Corporation
+
+Uma percepção clara que os hackers de gráficos do kernel tiveram nos últimos
+anos é que tentar criar uma interface unificada para gerenciar as unidades de
+execução e a memória em GPUs completamente diferentes é um esforço inútil.
+Portanto, hoje em dia, cada driver tem seu próprio conjunto de ioctls para
+alocar memória e enviar trabalho para a GPU. O que é bom, já que não há mais a
+insanidade na forma de interfaces falsamente genéricas, mas que na verdade só
+são usadas uma vez. No entanto, a desvantagem clara é que há muito mais
+potencial para estragar as coisas.
+
+Para evitar repetir todos os mesmos erros novamente, escrevi algumas das lições
+aprendidas enquanto fazia um trabalho malfeito para o driver drm/i915. A maioria
+delas aborda apenas tecnicalidades e não os problemas macro (big-picture), como
+deveria ser exatamente a aparência da ioctl de envio de comando. Aprender essas
+lições é provavelmente algo que cada driver de GPU tem que fazer por conta
+própria.
+
+
+Pré-requisitos
+--------------
+
+Primeiro, os pré-requisitos. Sem estes você já falhou, porque precisará
+adicionar uma camada de compatibilidade de 32 bits (compat layer):
+
+ * Use apenas inteiros de tamanho fixo. Para evitar conflitos com typedefs no
+ espaço de usuário (userspace), o kernel possui tipos especiais como __u32 e
+ __s64. Use-os.
+
+ * Alinhe tudo ao tamanho natural e use preenchimento (padding) explícito.
+ Plataformas de 32 bits não alinham necessariamente valores de 64 bits a
+ limites (boundaries) de 64 bits, mas plataformas de 64 bits o fazem. Portanto,
+ sempre precisamos de padding para o tamanho natural para acertar isso.
+
+ * Preencha a struct inteira para um múltiplo de 64 bits se a estrutura contiver
+ tipos de 64 bits -- caso contrário, o tamanho da estrutura diferirá entre
+ 32 bits e 64 bits. Ter um tamanho de estrutura diferente prejudica ao passar
+ matrizes (arrays) de estruturas para o kernel, ou se o kernel verificar o
+ tamanho da estrutura, o que o core do drm, por exemplo, faz.
+
+ * Ponteiros são __u64, convertidos de/para um uintptr_t no lado do espaço de
+ usuário e de/para um void __user * no kernel. Tente de verdade não atrasar
+ essa conversão ou, pior ainda, manipular o __u64 bruto pelo seu código, pois
+ isso diminui a verificação que ferramentas como o sparse podem fornecer. A
+ macro u64_to_user_ptr pode ser usada no kernel para evitar avisos sobre
+ inteiros e ponteiros de tamanhos diferentes.
+
+
+Conceitos básicos
+-----------------
+
+Evitadas as alegrias de escrever uma camada de compatibilidade (compat layer),
+podemos dar uma olhada nos deslizes básicos. Negligenciar estes pontos tornará a
+compatibilidade retroativa e futura uma verdadeira dor de cabeça. E, como errar
+na primeira tentativa é garantido, você certamente terá uma segunda iteração ou,
+pelo menos, uma extensão para qualquer interface fornecida.
+
+ * Tenha uma maneira clara para o espaço de usuário descobrir se a sua nova
+ ioctl ou extensão de ioctl é suportada em um determinado kernel. Se você não
+ puder confiar que os kernels antigos rejeitarão as novas flags/modos ou
+ ioctls (já que fazer isso foi deixado de lado no passado), então você
+ precisará de uma flag de recurso (feature flag) do driver ou de um número de
+ revisão em algum lugar.
+
+ * Tenha um plano para estender as ioctls com novas flags ou novos campos no
+ final da estrutura. O core do drm verifica o tamanho passado para cada
+ chamada de ioctl e preenche com zero (zero-extends) quaisquer divergências
+ entre o kernel e o espaço de usuário. Isso ajuda, mas não é uma solução
+ completa, já que um espaço de usuário mais novo em um kernel mais antigo não
+ notará que os campos recém-adicionados no final estão sendo ignorados.
+ Portanto, isso ainda exige novas flags de recurso do driver.
+
+ * Verifique todos os campos e flags não utilizados, além de todo o preenchimento
+ (padding), para garantir que estejam em 0, e rejeite a ioctl se esse não for
+ o caso. Caso contrário, seu excelente plano para extensões futuras irá por
+ água abaixo, pois alguém enviará uma struct de ioctl com lixo de pilha
+ (stack garbage) aleatório nas partes ainda não utilizadas. O que, então,
+ consolida na ABI que esses campos nunca poderão ser usados para nada além de
+ lixo. Esta também é a razão pela qual você deve preencher explicitamente todas
+ as estruturas, mesmo que nunca as use em uma matriz (array) -- o padding que
+ o compilador possa inserir poderia conter lixo.
+
+ * Tenha casos de teste simples para tudo o que foi mencionado acima.
+
+
+Diversão com caminhos de erro (Error Paths)
+-------------------------------------------
+
+Hoje em dia, não temos mais nenhuma desculpa para que os drivers drm sejam pequenos
+exploits de root disfarçados. Isso significa que precisamos tanto de uma
+validação completa de entrada quanto de caminhos sólidos de tratamento de erros
+-- as GPUs eventualmente vão parar de funcionar (die) nos casos mais bizarros
+de qualquer maneira:
+
+ * A ioctl deve verificar se há estouros de matriz (array overflows). Ela também
+ precisa verificar estouros superiores/inferiores (over/underflows) e problemas
+ de limitação (clamping) de valores inteiros em geral. O exemplo usual são os
+ valores de posicionamento de sprite alimentados diretamente no hardware, onde
+ o hardware possui apenas 12 bits ou algo assim. Funciona perfeitamente até que
+ algum servidor de exibição bizarro não se preocupe em fazer o clamping por si
+ mesmo e o cursor dê a volta (wrap around) na tela.
+
+ * Tenha casos de teste simples para cada caso de falha de validação de entrada
+ na sua ioctl. Verifique se o código de erro corresponde às suas expectativas.
+ E, finalmente, certifique-se de testar apenas um único caminho de erro em
+ cada subteste, enviando dados que, de outra forma, seriam perfeitamente
+ válidos. Sem isso, uma verificação anterior já poderia rejeitar a ioctl e
+ ofuscar (shadow) o caminho de código que você realmente deseja testar,
+ ocultando bugs e regressões.
+
+ * Torne todas as suas ioctls reiniciáveis (restartable). Primeiro, o X (X11)
+ realmente ama sinais (signals) e, segundo, isso permitirá que você teste 90%
+ de todos os caminhos de tratamento de erro apenas interrompendo sua suíte de
+ testes principal constantemente com sinais. Graças ao amor do X por sinais,
+ você obterá uma excelente cobertura de base de todos os seus caminhos de erro
+ praticamente de graça para drivers de gráficos. Além disso, seja consistente
+ na forma como você lida com a reinicialização de ioctls -- por exemplo, o drm
+ possui um pequeno helper drmIoctl em sua biblioteca de espaço de usuário. O
+ driver i915 estragou isso com a ioctl set_tiling; agora estamos presos para
+ sempre com algumas semânticas arcanas tanto no kernel quanto no espaço de
+ usuário.
+
+ * Se você não puder tornar um determinado caminho de código reiniciável, torne
+ uma tarefa travada pelo menos finalizável (killable). As GPUs simplesmente
+ morrem, e seus usuários não vão gostar mais de você se você travar a máquina
+ inteira deles (por meio de um processo do X impossível de matar). Se a
+ recuperação de estado ainda for muito complicada, tenha um timeout ou uma
+ rede de segurança de verificação de travamento (hangcheck) como um esforço de
+ última hora (last-ditch) caso o hardware enlouqueça (gone bananas).
+
+ * Tenha casos de teste para os cenários mais complexos (corner cases) no seu
+ código de recuperação de erros -- é fácil demais criar um deadlock entre seu
+ código de hangcheck e os processos que estão aguardando (waiters).
+
+
+Tempo, Espera e a Perda de Prazos
+---------------------------------
+
+As GPUs fazem quase tudo de forma assíncrona, portanto, temos a necessidade de
+cronometrar operações e aguardar pelas que estão pendentes. Esse é um negócio
+realmente complicado; no momento, nenhuma das ioctls suportadas pelo drm/i915
+acerta isso completamente, o que significa que ainda há toneladas de lições para
+aprender aqui.
+
+ * Use CLOCK_MONOTONIC como seu tempo de referência, sempre. É o que o alsa, o
+ drm e o v4l usam por padrão hoje em dia. Mas informe ao espaço de usuário
+ quais carimbos de data/hora (timestamps) são derivados de domínios de relógio
+ diferentes, como o relógio principal do seu sistema (fornecido pelo kernel)
+ ou algum contador de hardware independente em outro lugar. Os relógios vão
+ divergir se você olhar de perto o suficiente, mas se as ferramentas de
+ medição de desempenho tiverem essa informação, elas poderão ao menos compensar.
+ Se o seu espaço de usuário puder obter os valores brutos de alguns relógios
+ (por exemplo, por meio de instruções de amostragem de contador de desempenho
+ no fluxo de comandos), considere expor esses também.
+
+ * Use __s64 para segundos mais __u64 para nanossegundos para especificar o
+ tempo. Não é a especificação de tempo mais conveniente, mas é praticamente o
+ padrão.
+
+ * Verifique se os valores de tempo de entrada estão normalizados e rejeite-os
+ caso contrário. Note que a struct nativa do kernel, ktime, possui um inteiro
+ sinalizado tanto para segundos quanto para nanossegundos, portanto, cuidado
+ aqui.
+
+ * Para timeouts, use tempos absolutos. Se você for um bom sujeito e tiver
+ tornado a sua ioctl reiniciável, os timeouts relativos tendem a ser muito
+ imprecisos (coarse) e podem estender indefinidamente o seu tempo de espera
+ devido ao arredondamento a cada reinicialização. Especialmente se o seu relógio
+ de referência for algo realmente lento, como o contador de quadros da tela
+ (display frame counter). Vestindo o chapéu de advogado de especificações, isso
+ não é um bug, já que os timeouts sempre podem ser estendidos -- mas os usuários
+ com certeza vão odiar você se as belas animações deles começarem a gaguejar
+ (stutter) devido a isso.
+
+ * Considere descartar quaisquer ioctls de espera síncrona com timeouts e apenas
+ entregue um evento assíncrono em um descritor de arquivo passível de poll
+ (pollable file descriptor). Isso se encaixa muito melhor no loop principal de
+ aplicações orientadas a eventos.
+
+ * Tenha casos de teste para cenários complexos (corner-cases), especialmente se
+ os valores de retorno para eventos já concluídos, esperas bem-sucedidas e
+ esperas que estouraram o tempo (timed-out) são todos sãos e adequados às suas
+ necessidades.
+
+
+Evitando o vazamento de recursos (Leaking Resources, Not)
+---------------------------------------------------------
+
+Um driver drm completo essencialmente implementa um pequeno SO, mas especializado
+para as plataformas de GPU fornecidas. Isso significa que um driver precisa
+expor toneladas de handles (identificadores) para diferentes objetos e outros
+recursos para o espaço de usuário. Fazer isso corretamente traz seu próprio
+pequeno conjunto de armadilhas:
+
+ * Sempre vincule o tempo de vida (lifetime) de seus recursos criados
+ dinamicamente ao tempo de vida de um descritor de arquivo (file descriptor -
+ fd). Considere usar um mapeamento 1:1 se o seu recurso precisar ser
+ compartilhado entre processos -- a passagem de fds sobre unix domain sockets
+ também simplifica o gerenciamento do tempo de vida para o espaço de usuário.
+
+ * Sempre tenha suporte a O_CLOEXEC.
+
+ * Certifique-se de que você tem isolamento suficiente entre os diferentes
+ clientes. Por padrão, escolha um namespace privado por fd, o que força
+ qualquer compartilhamento a ser feito de forma explícita. Só adote um
+ namespace mais global por dispositivo se os objetos forem verdadeiramente
+ únicos do dispositivo. Um contraexemplo nas interfaces de modeset do drm é
+ que os objetos de modeset por dispositivo, como conectores, compartilham um
+ namespace com objetos de framebuffer, que na maioria das vezes não são
+ compartilhados de forma alguma. Um namespace separado, privado por padrão,
+ para os framebuffers teria sido mais adequado.
+
+ * Pense sobre os requisitos de unicidade para os handles do espaço de usuário.
+ Por exemplo, para a maioria dos drivers drm, é um bug do espaço de usuário
+ enviar o mesmo objeto duas vezes na mesma ioctl de envio de comando. Mas,
+ se os objetos forem compartilháveis, o espaço de usuário precisa saber se
+ já viu um objeto importado de outro processo ou não. Eu ainda não tentei isso
+ sozinho devido à falta de uma nova classe de objetos, mas considere usar
+ números de inode em seus descritores de arquivo compartilhados como
+ identificadores únicos -- é assim que arquivos reais também são diferenciados.
+ Infelizmente, isso requer um sistema de arquivos virtual completo no kernel.
+
+
+Por último, mas não menos importante
+------------------------------------
+
+Nem todo problema precisa de uma nova ioctl:
+
+ * Pense bem se você realmente quer uma interface privada do driver. Claro que
+ é muito mais rápido aprovar uma interface privada do driver do que se envolver
+ em discussões longas por uma solução mais genérica. E, ocasionalmente, criar
+ uma interface privada para liderar um novo conceito é o que se exige. Mas,
+ no final, assim que a interface genérica surgir, você acabará mantendo duas
+ interfaces. Indefinidamente.
+
+ * Considere outras interfaces além de ioctls. Um atributo sysfs é muito melhor
+ para configurações por dispositivo ou para objetos filhos com tempos de vida
+ razoavelmente estáticos (como conectores de saída no drm com todos os seus
+ atributos de sobreposição de detecção). Ou talvez apenas a sua suíte de
+ testes precise dessa interface e, nesse caso, o debugfs, com seu aviso de
+ isenção de responsabilidade por não ter uma ABI estável, seria melhor.
+
+Finalmente, o objetivo principal é acertar na primeira tentativa, pois se o seu
+driver se provar popular e suas plataformas de hardware forem duradouras, você
+ficará preso a uma determinada ioctl essencialmente para sempre. Você pode
+tentar depreciar ioctls horríveis em iterações mais novas do seu hardware, mas
+geralmente leva anos para conseguir isso. E depois mais anos até que o último
+usuário capaz de reclamar sobre regressões desapareça também.
\ No newline at end of file
--
2.47.3
next prev parent reply other threads:[~2026-07-03 17:07 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-07-03 17:05 [PATCH v2 0/7] docs: pt_BR: process: translation updates and additions Daniel Pereira
2026-07-03 17:05 ` [PATCH v2 1/7] docs: pt_BR: process: Translate the patch followthrough guide Daniel Pereira
2026-07-03 17:05 ` [PATCH v2 2/7] docs: pt_BR: process: translate 7.AdvancedTopics and 8.Conclusion Daniel Pereira
2026-07-03 17:05 ` [PATCH v2 3/7] docs: pt_BR: Add translation for applying-patches and update index Daniel Pereira
2026-07-03 17:05 ` [PATCH v2 4/7] docs: pt_BR: translate backporting.rst documentation Daniel Pereira
2026-07-03 17:05 ` Daniel Pereira [this message]
2026-07-03 17:05 ` [PATCH v2 6/7] docs: pt_BR: process: translate contribution maturity model Daniel Pereira
2026-07-03 17:05 ` [PATCH v2 7/7] docs: pt_BR: translate process/adding-syscalls.rst Daniel Pereira
2026-07-10 19:29 ` [PATCH v2 0/7] docs: pt_BR: process: translation updates and additions Jonathan Corbet
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260703170552.174764-6-danielmaraboo@gmail.com \
--to=danielmaraboo@gmail.com \
--cc=corbet@lwn.net \
--cc=linux-doc@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.