xref: /linux/Documentation/translations/pt_BR/process/4.Coding.rst (revision 72fdff1416e280e2baaa3cca69574defb998437e)
1.. SPDX-License-Identifier: GPL-2.0
2
3Escrever o código corretamente
4==============================
5
6Embora haja muito o que se dizer sobre um processo de design sólido e orientado
7à comunidade, a prova de qualquer projeto de desenvolvimento de kernel está no
8código resultante. É o código que será examinado por outros desenvolvedores e
9mesclado (ou não) na árvore principal (*mainline*). Portanto, é a qualidade
10deste código que determinará o sucesso final do projeto.
11
12Esta seção examinará o processo de codificação. Começaremos analisando uma série
13de maneiras pelas quais os desenvolvedores de kernel podem errar. Em seguida, o
14foco mudará para como fazer as coisas do jeito certo e as ferramentas que podem
15ajudar nessa busca.
16
17
18Armadilhas
19----------
20
21Estilo de Codificação
22*********************
23
24O kernel há muito possui um estilo de codificação padrão, descrito em
25:ref:`Documentation/process/coding-style.rst <codingstyle>`. Por grande parte
26desse tempo, as políticas descritas naquele arquivo eram consideradas, no
27máximo, como recomendações. Como resultado, há uma quantidade substancial
28de código no kernel que não cumpre as diretrizes de estilo de codificação.
29A presença desse código leva a dois riscos independentes para os
30desenvolvedores do kernel.
31
32O primeiro deles é acreditar que os padrões de codificação do kernel não importam
33e não são exigidos. A verdade é que adicionar novo código ao kernel é muito
34difícil se esse código não estiver escrito de acordo com o padrão; muitos
35desenvolvedores solicitarão que o código seja reformatado antes mesmo de
36revisá-lo. Uma base de código tão grande quanto a do kernel exige certa
37uniformidade para tornar possível que os desenvolvedores entendam rapidamente
38qualquer parte dela. Portanto, não há mais espaço para códigos com formatações
39estranhas.
40
41Ocasionalmente, o estilo de codificação do kernel entrará em conflito com o
42estilo exigido por um empregador. Nesses casos, o estilo do kernel terá que
43vencer para que o código possa ser mesclado. Colocar código no kernel significa
44abrir mão de um certo grau de controle de várias maneiras — incluindo o controle
45sobre como o código é formatado.
46
47A outra armadilha é presumir que o código já presente no kernel necessita
48urgentemente de correções de estilo de codificação. Os desenvolvedores podem
49começar a gerar patches de reformatação como uma forma de ganhar familiaridade
50com o processo, ou como um meio de incluir seus nomes nos logs de alterações
51(*changelogs*) do kernel  ou ambos. No entanto, patches puramente de estilo de
52codificação são vistos como ruído pela comunidade de desenvolvimento; eles tendem
53a receber uma recepção fria. Portanto, é melhor evitar esse tipo de patch. É
54natural corrigir o estilo de um trecho de código ao trabalhar nele por outros
55motivos, mas mudanças de estilo de codificação não devem ser feitas apenas por
56fazer.
57
58O documento de estilo de codificação também não deve ser lido como uma lei
59absoluta que nunca pode ser transgredida. Se houver um bom motivo para ir contra
60o estilo (uma linha que se torna muito menos legível se for dividida para caber
61no limite de 80 colunas, por exemplo), simplesmente faça isso.
62
63Note que você também pode usar a ferramenta ``clang-format`` para ajudá-lo com
64essas regras, para reformatar rapidamente partes do seu código de forma automática
65e para revisar arquivos completos a fim de identificar erros de estilo de
66codificação, erros de digitação e possíveis melhorias. Ela também é útil para
67ordenar ``#includes``, alinhar variáveis/macros, reajustar o fluxo de textos e
68outras tarefas semelhantes. Veja o arquivo
69:ref:`Documentation/dev-tools/clang-format.rst <clangformat>` para mais detalhes.
70
71Algumas configurações básicas do editor, como indentação e fins de linha,
72serão definidas automaticamente se você estiver usando um editor compatível
73com o EditorConfig. Consulte o site oficial do EditorConfig para obter mais
74informações: https://editorconfig.org/
75
76Camadas de Abstração
77********************
78
79Os professores de Ciência da Computação ensinam os alunos a fazerem uso
80extensivo de camadas de abstração em nome da flexibilidade e da ocultação de
81informações. Certamente o kernel faz uso extensivo de abstração; nenhum
82projeto que envolva vários milhões de linhas de código poderia fazer o
83contrário e sobreviver. No entanto, a experiência tem mostrado que a
84abstração excessiva ou prematura pode ser tão prejudicial quanto a otimização
85prematura. A abstração deve ser usada até o nível necessário e não além.
86
87Em um nível simples, considere uma função que possui um argumento que é
88sempre passado como zero por todos os chamadores. Alguém poderia manter esse
89argumento caso alguém eventualmente precise usar a flexibilidade extra que ele
90oferece. A essa altura, no entanto, as chances são grandes de que o código que
91implementa esse argumento extra tenha sido quebrado de alguma forma sutil que
92nunca foi percebida — porque ele nunca foi usado. Ou, quando surge a
93necessidade de flexibilidade extra, ela não ocorre de uma forma que corresponda
94à expectativa inicial do programador. Os desenvolvedores do kernel enviam
95patches rotineiramente para remover argumentos não utilizados; eles não devem,
96em geral, ser adicionados em primeiro lugar.
97
98Camadas de abstração que ocultam o acesso ao hardware — frequentemente para
99permitir que a maior parte de um driver seja usada com múltiplos sistemas
100operacionais — são especialmente malvistas. Essas camadas obscurecem o código
101e podem impor uma penalidade de desempenho; elas não pertencem ao kernel
102Linux.
103
104Por outro lado, se você se pegar copiando quantidades significativas de código
105de outro subsistema do kernel, é hora de perguntar se faria sentido, de fato,
106extrair parte desse código em uma biblioteca separada ou implementar essa
107funcionalidade em um nível superior. Não há valor em duplicar o mesmo código
108por todo o kernel.
109
110
111Uso de #ifdef e do pré-processador em geral
112*******************************************
113
114O pré-processador C parece apresentar uma forte tentação para alguns
115programadores C, que o veem como uma forma de codificar eficientemente uma grande
116quantidade de flexibilidade em um arquivo-fonte. No entanto, o pré-processador
117não é C, e o uso pesado dele resulta em um código muito mais difícil de ser lido
118por outros e mais difícil para o compilador verificar a correção. O uso pesado
119do pré-processador é quase sempre um sinal de código que precisa de algum
120trabalho de limpeza.
121
122A compilação condicional com #ifdef é, de fato, um recurso poderoso, e é
123utilizada dentro do kernel. Mas há pouco desejo de ver um código que seja
124salpicado liberalmente com blocos #ifdef. Como regra geral, o uso de #ifdef
125deve ser confinado a arquivos de cabeçalho (headers) sempre que possível. O
126código compilado condicionalmente pode ser confinado a funções que, se o código
127não estiver presente, simplesmente se tornam vazias. O compilador irá então,
128silenciosamente, otimizar e remover a chamada para a função vazia. O resultado
129é um código muito mais limpo e fácil de acompanhar.
130
131As macros do pré-processador C apresentam uma série de riscos, incluindo a
132possível avaliação múltipla de expressões com efeitos colaterais e a falta de
133segurança de tipos. Se você se sentir tentado a definir uma macro, considere a
134criação de uma função inline em seu lugar. O código resultante será o mesmo,
135mas as funções inline são mais fáceis de ler, não avaliam seus argumentos
136múltiplas vezes e permitem que o compilador realize a checagem de tipos nos
137argumentos e no valor de retorno.
138
139
140Funções Inline
141**************
142
143No entanto, as funções inline apresentam um perigo próprio. Os programadores
144podem ficar encantados com a eficiência percebida inerente a evitar uma chamada
145de função e encher um arquivo de código-fonte com funções inline. Essas
146funções, contudo, podem na verdade reduzir o desempenho. Como seu código é
147replicado em cada local de chamada, elas acabam inflando o tamanho do kernel
148compilado. Isso, por sua vez, cria pressão nos caches de memória do
149processador, o que pode desacelerar a execução drasticamente. As funções
150inline, como regra, devem ser bastante pequenas e relativamente raras. O custo
151de uma chamada de função, afinal de contas, não é tão alto; a criação de um
152grande número de funções inline é um exemplo clássico de otimização prematura.
153
154Em geral, os programadores de kernel ignoram os efeitos de cache por sua própria
155conta e risco. O clássico compromisso entre tempo e espaço (tradeoff) ensinado
156nas aulas introdutórias de estruturas de dados frequentemente não se aplica ao
157hardware contemporâneo. Espaço *é* tempo, no sentido de que um programa maior
158será executado mais lentamente do que um que seja mais compacto.
159
160Compiladores mais recentes desempenham um papel cada vez mais ativo em decidir
161se uma determinada função deve ou não ser realmente inline. Portanto, a inserção
162liberal da palavra-chave "inline" pode não apenas ser excessiva; ela também pode
163ser irrelevante.
164
165
166Mecanismo de Trava
167******************
168
169Em maio de 2006, a pilha de rede "Devicescape" foi, com grande alarde, lançada
170sob a GPL e disponibilizada para inclusão no kernel mainline. Essa doação foi uma
171notícia bem-vinda; o suporte para redes sem fio no Linux era considerado abaixo do
172padrão, na melhor das hipóteses, e a pilha da Devicescape oferecia a promessa de
173corrigir essa situação. No entanto, esse código só entrou de fato no mainline em
174junho de 2007 (2.6.22). O que aconteceu?
175
176Esse código mostrava vários sinais de ter sido desenvolvido a portas fechadas em
177ambiente corporativo. Mas um grande problema em particular era que ele não havia
178sido projetado para funcionar em sistemas multiprocessados. Antes que essa pilha
179de rede (agora chamada de mac80211) pudesse ser integrada, um esquema de locking
180(bloqueio) precisou ser adaptado a ela.
181
182Era uma vez uma época em que o código do kernel Linux podia ser desenvolvido sem
183pensar nos problemas de concorrência apresentados por sistemas multiprocessados.
184Hoje, no entanto, este documento está sendo escrito em um laptop dual-core.
185Mesmo em sistemas com um único processador, o trabalho feito para melhorar a
186capacidade de resposta aumentará o nível de concorrência dentro do kernel. Os
187dias em que o código do kernel podia ser escrito sem pensar em locking ficaram
188há muito tempo no passado.
189
190Qualquer recurso (estruturas de dados, registradores de hardware, etc.) que
191possa ser acessado concorrentemente por mais de uma linha de execução deve ser
192protegido por uma trava (lock). O novo código deve ser escrito com esse
193requisito em mente; adaptar o locking após o fato é uma tarefa consideravelmente
194mais difícil. Os desenvolvedores do kernel devem dedicar um tempo para
195compreender as primitivas de locking disponíveis bem o suficiente para escolher
196a ferramenta certa para o trabalho. Códigos que mostrem falta de atenção à
197concorrência terão um caminho difícil para entrar no mainline.
198
199
200Regressions
201***********
202
203Um perigo final que vale a pena mencionar é este: pode ser tentador fazer uma
204alteração (que pode trazer grandes melhorias) que faça algo quebrar para os
205usuários existentes. Esse tipo de alteração é chamado de "regressão", e as
206regressões tornaram-se totalmente indesejadas no kernel mainline. Com poucas
207exceções, as alterações que causarem regressões serão revertidas se a regressão
208não puder ser corrigida em tempo hábil. É muito melhor evitar a regressão em
209primeiro lugar.
210
211Muitas vezes argumenta-se que uma regressão pode ser justificada se ela fizer as
212coisas funcionarem para mais pessoas do que os problemas que ela cria. Por que
213não fazer uma alteração se ela trouxer uma nova funcionalidade para dez sistemas
214para cada um que ela quebrar? A melhor resposta para essa pergunta foi expressa
215por Linus em julho de 2007:
216
217::
218
219  Portanto, nós não corrigimos bugs introduzindo novos problemas. Esse caminho
220  leva à loucura, e ninguém nunca sabe se você está realmente fazendo algum
221  progresso real. São dois passos para frente, um passo para trás, ou um passo
222  para frente e dois passos para trás?
223
224(https://lwn.net/Articles/243460/).
225
226Um tipo de regressão especialmente indesejado é qualquer tipo de alteração na
227ABI do espaço do usuário (user-space ABI). Uma vez que uma interface tenha sido
228exportada para o espaço do usuário, ela deve receber suporte indefinidamente.
229Esse fato torna a criação de interfaces de espaço do usuário particularmente
230desafiadora: já que elas não podem ser alteradas de maneiras incompatíveis, elas
231devem ser feitas corretamente na primeira vez. Por essa razão, exige-se sempre
232muita reflexão, documentação clara e uma ampla revisão para as interfaces do
233espaço do usuário.
234
235
236Ferramentas de verificação de código
237------------------------------------
238
239Por enquanto, pelo menos, a escrita de código livre de erros continua sendo um
240ideal que poucos de nós conseguem alcançar. O que podemos esperar fazer, no
241entanto, é capturar e corrigir o máximo possível desses erros antes que nosso
242código entre no kernel mainline. Para esse fim, os desenvolvedores do kernel
243reuniram um conjunto impressionante de ferramentas que podem capturar uma ampla
244variedade de problemas obscuros de forma automatizada. Qualquer problema
245capturado pelo computador é um problema que não afligirá um usuário mais tarde,
246portanto, é lógico que as ferramentas automatizadas devem ser usadas sempre que
247possível.
248
249O primeiro passo é simplesmente prestar atenção aos avisos (warnings) produzidos
250com o compilador. As versões contemporâneas do gcc podem detectar (e alertar
251sobre) um grande número de erros potenciais. Com bastante frequência, esses
252avisos apontam para problemas reais. O código enviado para revisão deve, como
253regra, não produzir nenhum aviso do compilador. Ao silenciar os avisos, tome o
254cuidado de entender a real causa e tente evitar "correções" que façam o aviso
255desaparecer sem resolver a sua origem.
256
257Note que nem todos os avisos do compilador ficam ativados por padrão. Compile o
258kernel com "make KCFLAGS=-W" para obter o conjunto completo.
259
260O kernel fornece várias opções de configuração que ativam recursos de
261depuração; a maioria delas é encontrada no submanu "kernel hacking". Várias
262dessas opções devem ser ativadas para qualquer kernel usado para fins de
263desenvolvimento ou teste. Em particular, você deve ativar:
264
265 - FRAME_WARN para obter avisos sobre quadros de pilha (stack frames) maiores
266   que um determinado valor. A saída gerada pode ser volumosa, mas não é
267   necessário se preocupar com os avisos de outras partes do kernel.
268
269 - DEBUG_OBJECTS adicionará código para rastrear o tempo de vida de vários
270   objetos criados pelo kernel e alertará quando as ações forem feitas fora de
271   ordem. Se você estiver adicionando um subsistema que cria (e exporta) seus
272   próprios objetos complexos, considere adicionar suporte à infraestrutura de
273   depuração de objetos.
274
275 - DEBUG_SLAB pode encontrar uma variedade de erros de alocação e uso de
276   memória; ele deve ser usado na maioria dos kernels de desenvolvimento.
277
278 - DEBUG_SPINLOCK, DEBUG_ATOMIC_SLEEP e DEBUG_MUTEXES encontrarão uma série de
279   erros comuns de locking (bloqueio).
280
281Existem várias outras opções de depuração, algumas das quais serão discutidas
282abaixo. Algumas delas têm um impacto significativo no desempenho e não devem ser
283usadas o tempo todo. Mas um tempo gasto aprendendo as opções disponíveis
284provavelmente se pagará muitas vezes em pouco tempo.
285
286Uma das ferramentas de depuração mais pesadas é o verificador de locking, ou
287"lockdep". Esta ferramenta rastreará a aquisição e a liberação de cada trava
288(spinlock ou mutex) no sistema, a ordem em que as travas são adquiridas umas em
289relação às outras, o ambiente de interrupção atual e muito mais. Ela pode,
290então, garantir que as travas sejam sempre adquiridas na mesma ordem, que as
291mesmas suposições de interrupção se apliquem em todas as situações e assim por
292diante. Em outras palavras, o lockdep pode encontrar uma série de cenários nos
293quais o sistema poderia, em raras ocasiões, entrar em deadlock. Esse tipo de
294problema pode ser doloroso (tanto para desenvolvedores quanto para usuários) em
295um sistema implantado; o lockdep permite que eles sejam encontrados de maneira
296automatizada e antecipada. Códigos com qualquer tipo de locking não trivial
297devem ser executados com o lockdep ativado antes de serem enviados para inclusão.
298
299Como um programador de kernel diligente, você irá, sem dúvida, verificar o
300status de retorno de qualquer operação (como uma alocação de memória) que possa
301falhar. O fato, porém, é que os caminhos de recuperação de falha resultantes
302estão, provavelmente, completamente não testados. Código não testado tende a ser
303código quebrado; você poderia estar muito mais confiante em seu código se todos
304esses caminhos de tratamento de erros tivessem sido exercitados algumas vezes.
305
306O kernel fornece um framework de injeção de falhas (fault injection) que pode
307fazer exatamente isso, especialmente onde alocações de memória estão
308envolvidas. Com a injeção de falhas ativada, uma porcentagem configurável das
309alocações de memória será forçada a falhar; essas falhas podem ser restritas a
310um intervalo específico de código. Executar o código com a injeção de falhas
311ativada permite ao programador ver como o código responde quando as coisas vão
312mal. Veja Documentation/fault-injection/fault-injection.rst para mais
313informações sobre como usar esse recurso.
314
315Outros tipos de erros podem ser encontrados com a ferramenta de análise estática
316"sparse". Com o sparse, o programador pode ser alertado sobre confusões entre
317endereços do espaço do usuário e do espaço do kernel, mistura de quantidades
318big-endian e small-endian, a passagem de valores inteiros onde um conjunto de
319sinalizadores de bits (bit flags) é esperado, e assim por diante. O sparse deve
320ser instalado separadamente (ele pode ser encontrado em
321https://sparse.wiki.kernel.org/index.php/Main_Page se a sua distribuição não o
322incluir como pacote); ele pode então ser executado no código adicionando "C=1"
323ao seu comando make.
324
325A ferramenta "Coccinelle" (http://coccinelle.lip6.fr/) é capaz de encontrar uma
326ampla variedade de potenciais problemas de codificação; ela também pode propor
327correções para esses problemas. Uma quantidade considerável de "patches
328semânticos" para o kernel foi empacotada sob o diretório scripts/coccinelle;
329executar "make coccicheck" passará por esses patches semânticos e relatará
330quaisquer problemas encontrados. Veja
331:ref:`Documentation/dev-tools/coccinelle.rst <devtools_coccinelle>`
332para mais informações.
333
334Outros tipos de erros de portabilidade são encontrados mais facilmente ao
335compilar seu código para outras arquiteturas. Se você por acaso não tiver um
336sistema S/390 ou uma placa de desenvolvimento Blackfin à mão, ainda assim poderá
337realizar a etapa de compilação. Um grande conjunto de compiladores cruzados
338(cross-compilers) para sistemas x86 pode ser encontrado em:
339
340  https://www.kernel.org/pub/tools/crosstool/
341
342Um tempo gasto instalando e usando esses compiladores ajudará a evitar
343constrangimentos mais tarde.
344
345
346Documentação
347-------------
348
349A documentação frequentemente tem sido mais a exceção do que a regra no
350desenvolvimento do kernel. Mesmo assim, uma documentação adequada ajudará a
351facilitar a integração de novos códigos ao kernel, tornará a vida mais fácil para
352outros desenvolvedores e será útil para os seus usuários. Em muitos casos, a
353adição de documentação tornou-se essencialmente obrigatória.
354
355A primeira parte da documentação de qualquer patch é o seu log de alterações
356(changelog) associado. As entradas do log devem descrever o problema que está
357sendo resolvido, a forma da solução, as pessoas que trabalharam no patch,
358quaisquer efeitos relevantes no desempenho e qualquer outra coisa que possa ser
359necessária para entender o patch. Certifique-se de que o changelog diga o
360*porquê* de o patch valer a pena ser aplicado; um número surpreendente de
361desenvolvedores falha em fornecer essa informação.
362
363Qualquer código que adicione uma nova interface de espaço do usuário — incluindo
364novos arquivos sysfs ou /proc — deve incluir a documentação dessa interface, de
365modo a permitir que os desenvolvedores do espaço do usuário saibam com o que
366estão trabalhando. Veja Documentation/ABI/README para uma descrição de como essa
367documentação deve ser formatada e quais informações precisam ser fornecidas.
368
369O arquivo :ref:`Documentation/admin-guide/kernel-parameters.rst
370<kernelparameters>` descreve todos os parâmetros de boot do kernel. Qualquer
371patch que adicione novos parâmetros deve adicionar as entradas apropriadas a
372este arquivo.
373
374Quaisquer novas opções de configuração devem ser acompanhadas por um texto de
375ajuda que explique claramente as opções e quando o usuário pode querer
376selecioná-las.
377
378As informações de API interna de muitos subsistemas são documentadas por meio de
379comentários com formatação especial; esses comentários podem ser extraídos e
380formatados de várias maneiras pelo script "kernel-doc". Se você estiver
381trabalhando em um subsistema que possui comentários kerneldoc, você deve
382mantê-los e adicioná-los, conforme apropriado, para funções disponíveis
383externamente. Mesmo em áreas que não tenham sido documentadas dessa forma, não há
384mal nenhum em adicionar comentários kerneldoc para o futuro; de fato, esta pode
385ser uma atividade útil para desenvolvedores iniciantes de kernel. O formato
386desses comentários, junto com algumas informações sobre como criar modelos de
387kerneldoc, pode ser encontrado em :ref:`Documentation/doc-guide/ <doc_guide>`.
388
389Qualquer pessoa que leia uma quantidade significativa de código existente do
390kernel notará que, frequentemente, os comentários chamam a atenção por sua
391ausência. Mais uma vez, as expectativas para códigos novos são mais altas do que
392eram no passado; integrar código sem comentários será mais difícil. Dito isso,
393há pouco interesse em códigos comentados de forma prolixa. O código deve, por si
394só, ser legível, com os comentários explicando os aspectos mais sutis.
395
396Certas coisas devem sempre ser comentadas. O uso de barreiras de memória
397(memory barriers) deve ser acompanhado por uma linha explicando por que a
398barreira é necessária. As regras de locking (bloqueio) para estruturas de dados
399geralmente precisam ser explicadas em algum lugar. Grandes estruturas de dados
400precisam de uma documentação abrangente em geral. Dependências não óbvias entre
401trechos distintos de código devem ser apontadas. Qualquer coisa que possa tentar
402um "faxineiro de código" (code janitor) a fazer uma "limpeza" incorreta precisa
403de um comentário dizendo por que foi feita daquela maneira. E assim por diante.
404
405
406Alterações de API interna
407-------------------------
408
409A interface binária fornecida pelo kernel para o espaço do usuário não pode ser
410quebrada, exceto sob as circunstâncias mais graves. Por outro lado, as
411interfaces de programação internas do kernel são altamente fluidas e podem ser
412alteradas quando surgir a necessidade. Se você se encontrar tendo que criar uma
413gambiarra para contornar uma API do kernel, ou simplesmente deixando de usar uma
414funcionalidade específica porque ela não atende às suas necessidades, isso pode
415ser um sinal de que a API precisa mudar. Como desenvolvedor de kernel, você tem
416o poder de fazer tais alterações.
417
418Existem, é claro, algumas pegadinhas. Alterações de API podem ser feitas, mas
419precisam ser bem justificadas. Portanto, qualquer patch que faça uma alteração de
420API interna deve ser acompanhado por uma descrição do que é a mudança e do porquê
421ela é necessária. Esse tipo de alteração também deve ser separado em um patch
422independente, em vez de ser enterrado dentro de um patch maior.
423
424A outra pegadinha é que o desenvolvedor que altera uma API interna é geralmente
425encarregado da tarefa de corrigir qualquer código dentro da árvore do kernel que
426tenha sido quebrado pela mudança. Para uma função amplamente utilizada, esse
427dever pode levar a literalmente centenas ou milhares de alterações — muitas das
428quais provavelmente entrarão em conflito com o trabalho que está sendo feito por
429outros desenvolvedores. Desnecessário dizer que isso pode ser um grande
430trabalho, então é melhor ter certeza de que a justificativa é sólida. Note que
431a ferramenta Coccinelle pode ajudar com alterações de API de amplo alcance.
432
433Ao fazer uma alteração incompatível de API, deve-se, sempre que possível,
434garantir que o código que não foi atualizado seja capturado pelo compilador.
435Isso ajudará você a ter certeza de que encontrou todos os usos dessa interface
436dentro da árvore (in-tree). Isso também alertará os desenvolvedores de códigos
437fora da árvore (out-of-tree) de que há uma mudança à qual eles precisam
438responder. Dar suporte a código fora da árvore não é algo com que os
439desenvolvedores do kernel precisem se preocupar, mas também não temos que
440tornar a vida dos desenvolvedores fora da árvore mais difícil do que precisa ser.
441