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