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