docs/sp_SP: Add translation of process/4.Coding.rst
Translate Documentation/process/4.Coding.rst into Spanish. Co-developed-by: Avadhut Naik <avadhut.naik@amd.com> Signed-off-by: Avadhut Naik <avadhut.naik@amd.com> Signed-off-by: Carlos Bilbao <carlos.bilbao.osdev@gmail.com> Signed-off-by: Jonathan Corbet <corbet@lwn.net> Link: https://lore.kernel.org/r/20241129155851.1023884-3-carlos.bilbao.osdev@gmail.com
This commit is contained in:
committed by
Jonathan Corbet
parent
42b5e1e213
commit
ad7f6532b8
@@ -1,11 +1,470 @@
|
||||
.. include:: ../disclaimer-sp.rst
|
||||
|
||||
:Original: Documentation/process/4.Coding.rst
|
||||
:Translator: Carlos Bilbao <carlos.bilbao.osdev@gmail.com> and Avadhut Naik <avadhut.naik@amd.com>
|
||||
|
||||
.. _sp_development_coding:
|
||||
|
||||
Conseguir el código correcto
|
||||
============================
|
||||
|
||||
.. warning::
|
||||
TODO aún no traducido
|
||||
Si bien hay mucho que decir a favor de un proceso de diseño sólido y
|
||||
orientado a la comunidad, la prueba de cualquier proyecto de desarrollo del
|
||||
kernel está en el código resultante. Es el código lo que será examinado por
|
||||
otros desarrolladores y lo que será incluido (o no) en el árbol principal.
|
||||
Por lo tanto, es la calidad de este código lo que determinará el éxito
|
||||
final del proyecto.
|
||||
|
||||
Esta sección examinará el proceso de programación. Comenzaremos observando
|
||||
algunas de las maneras en que los desarrolladores del kernel pueden cometer
|
||||
errores. Luego, el enfoque se dirigirá hacia hacer las cosas bien y las
|
||||
herramientas que pueden ayudar en dicha búsqueda.
|
||||
|
||||
Problemas
|
||||
---------
|
||||
|
||||
Estilo de programación
|
||||
**********************
|
||||
|
||||
El kernel ha tenido durante mucho tiempo un estilo de programación
|
||||
estándar, descrito en la documentación del kernel en
|
||||
`Documentation/process/coding-style.rst`. Durante gran parte de ese tiempo,
|
||||
las políticas descritas en ese archivo se tomaban como, en el mejor de los
|
||||
casos, orientativas. Como resultado, hay una cantidad considerable de
|
||||
código en el kernel que no cumple con las pautas de estilo de programación.
|
||||
La presencia de ese código lleva a dos peligros independientes para los
|
||||
desarrolladores del kernel.
|
||||
|
||||
El primero de estos es creer que los estándares de programación del kernel
|
||||
no importan y no se aplican. La realidad es que agregar nuevo código al
|
||||
kernel es muy difícil si ese código no está escrito de acuerdo con el
|
||||
estándar; muchos desarrolladores solicitarán que el código sea reformateado
|
||||
antes de revisarlo. Una base de código tan grande como el kernel requiere
|
||||
cierta uniformidad para que los desarrolladores puedan comprender
|
||||
rápidamente cualquier parte de él. Así que ya no hay lugar para el código
|
||||
con formato extraño.
|
||||
|
||||
Ocasionalmente, el estilo de programación del kernel entrará en conflicto
|
||||
con el estilo obligatorio de un empleador. En tales casos, el estilo del
|
||||
kernel tendrá que prevalecer antes de que el código pueda ser fusionado.
|
||||
Incluir código en el kernel significa renunciar a cierto grado de control
|
||||
de varias maneras, incluida la forma en que se formatea el código.
|
||||
|
||||
La otra trampa es asumir que el código que ya está en el kernel necesita
|
||||
urgentemente correcciones de estilo de programación. Los desarrolladores
|
||||
pueden comenzar a generar parches de reformateo como una forma de
|
||||
familiarizarse con el proceso o como una forma de incluir su nombre en los
|
||||
registros de cambios del kernel, o ambos. Pero las correcciones puramente
|
||||
de estilo de programación son vistas como ruido por la comunidad de
|
||||
desarrollo; tienden a recibir una recepción adversa. Por lo tanto, este
|
||||
tipo de parche es mejor evitarlo. Es natural corregir el estilo de una
|
||||
parte del código mientras se trabaja en él por otras razones, pero los
|
||||
cambios de estilo de programación no deben hacerse por sí mismos.
|
||||
|
||||
El documento de estilo de programación tampoco debe leerse como una ley
|
||||
absoluta que nunca puede transgredirse. Si hay una buena razón para ir en
|
||||
contra del estilo (una línea que se vuelve mucho menos legible si se divide
|
||||
para ajustarse al límite de 80 columnas, por ejemplo), perfecto.
|
||||
|
||||
Tenga en cuenta que también puedes usar la herramienta `clang-format` para
|
||||
ayudarle con estas reglas, para reformatear rápidamente partes de su código
|
||||
automáticamente y para revisar archivos completos a fin de detectar errores
|
||||
de estilo de programación, errores tipográficos y posibles mejoras. También
|
||||
es útil para ordenar `#includes`, alinear variables/macros, reformatear
|
||||
texto y otras tareas similares. Consulte el archivo
|
||||
`Documentation/dev-tools/clang-format.rst` para más detalles.
|
||||
|
||||
Algunas configuraciones básicas del editor, como la indentación y los
|
||||
finales de línea, se configurarán automáticamente si utilizas un editor
|
||||
compatible con EditorConfig. Consulte el sitio web oficial de EditorConfig
|
||||
para obtener más información: https://editorconfig.org/
|
||||
|
||||
Capas de abstracción
|
||||
********************
|
||||
|
||||
Los profesores de ciencias de la computación enseñan a los estudiantes a
|
||||
hacer un uso extensivo de capas de abstracción en nombre de la
|
||||
flexibilidad y el ocultamiento de la información. Sin duda, el kernel hace
|
||||
un uso extensivo de la abstracción; ningún proyecto que involucre varios
|
||||
millones de líneas de código podría sobrevivir de otra manera. Pero la
|
||||
experiencia ha demostrado que una abstracción excesiva o prematura puede
|
||||
ser tan perjudicial como la optimización prematura. La abstracción debe
|
||||
usarse en la medida necesaria y ya.
|
||||
|
||||
A un nivel simple, considere una función que tiene un argumento que siempre
|
||||
se pasa como cero por todos los que la invocan. Uno podría mantener ese
|
||||
argumento por si alguien eventualmente necesita usar la flexibilidad
|
||||
adicional que proporciona. Sin embargo, para entonces, es probable que el
|
||||
código que implementa este argumento adicional se haya roto de alguna
|
||||
manera sutil que nunca se notó, porque nunca se ha utilizado. O, cuando
|
||||
surge la necesidad de flexibilidad adicional, no lo hace de una manera que
|
||||
coincida con la expectativa temprana del programador. Los desarrolladores
|
||||
del kernel rutinariamente enviarán parches para eliminar argumentos no
|
||||
utilizados; en general, no deberían añadirse en primer lugar.
|
||||
|
||||
Las capas de abstracción que ocultan el acceso al hardware, a menudo para
|
||||
permitir que la mayor parte de un controlador se utilice con varios
|
||||
sistemas operativos, son especialmente mal vistas. Dichas capas oscurecen
|
||||
el código y pueden imponer una penalización en el rendimiento; no
|
||||
pertenecen al kernel de Linux.
|
||||
|
||||
Por otro lado, si se encuentra copiando cantidades significativas de código
|
||||
de otro subsistema del kernel, es hora de preguntar si, de hecho, tendría
|
||||
sentido extraer parte de ese código en una biblioteca separada o
|
||||
implementar esa funcionalidad a un nivel superior. No tiene sentido
|
||||
replicar el mismo código en todo el kernel.
|
||||
|
||||
Uso de #ifdef y del preprocesador en general
|
||||
********************************************
|
||||
|
||||
El preprocesador de C tiene una tentación poderosa para algunos
|
||||
programadores de C, quienes lo ven como una forma de programar
|
||||
eficientemente una gran cantidad de flexibilidad en un archivo fuente. Pero
|
||||
el preprocesador no es C, y el uso intensivo de él da como resultado un
|
||||
código mucho más difícil de leer para otros y más difícil de verificar por
|
||||
el compilador para su corrección. El uso intensivo del preprocesador es
|
||||
asi siempre un signo de un código que necesita algo de limpieza.
|
||||
|
||||
La compilación condicional con `#ifdef` es, de hecho, una característica
|
||||
poderosa, y se usa dentro del kernel. Pero hay poco deseo de ver código que
|
||||
sté salpicado liberalmente con bloques `#ifdef`. Como regla general, el uso
|
||||
de `#ifdef` debe limitarse a los archivos de encabezado siempre que sea
|
||||
posible. El código condicionalmente compilado puede confinarse a funciones
|
||||
que, si el código no va a estar presente, simplemente se convierten en
|
||||
vacías. El compilador luego optimizará silenciosamente la llamada a la
|
||||
función vacía. El resultado es un código mucho más limpio y fácil de
|
||||
seguir.
|
||||
|
||||
Las macros del preprocesador de C presentan varios peligros, incluida la
|
||||
posible evaluación múltiple de expresiones con efectos secundarios y la
|
||||
falta de seguridad de tipos. Si te sientes tentado a definir una macro,
|
||||
considera crear una función en línea en su lugar. El código resultante será
|
||||
el mismo, pero las funciones en línea son más fáciles de leer, no evalúan
|
||||
sus argumentos varias veces y permiten que el compilador realice
|
||||
comprobaciones de tipo en los argumentos y el valor de retorno.
|
||||
|
||||
Funciones en línea
|
||||
******************
|
||||
|
||||
Las funciones en línea presentan su propio peligro, sin embargo. Los
|
||||
programadores pueden enamorarse de la eficiencia percibida al evitar una
|
||||
llamada a función y llenar un archivo fuente con funciones en línea. Esas
|
||||
funciones, sin embargo, pueden en realidad reducir el rendimiento. Dado que
|
||||
su código se replica en cada sitio de llamada, terminan hinchando el tamaño
|
||||
del kernel compilado. Eso, a su vez, crea presión en las cachés de memoria
|
||||
del procesador, lo que puede ralentizar la ejecución de manera drástica
|
||||
Las funciones en línea, como regla, deben ser bastante pequeñas y
|
||||
relativamente raras. El costo de una llamada a función, después de todo, no
|
||||
es tan alto; la creación de un gran número de funciones en línea es un
|
||||
ejemplo clásico de optimización prematura.
|
||||
|
||||
En general, los programadores del kernel ignoran los efectos de caché bajo
|
||||
su propio riesgo. El clásico intercambio de tiempo/espacio que se enseña en
|
||||
las clases de estructuras de datos iniciales a menudo no se aplica al
|
||||
hardware contemporáneo. El espacio *es* tiempo, en el sentido de que un
|
||||
programa más grande se ejecutará más lentamente que uno más compacto.
|
||||
|
||||
Los compiladores más recientes toman un papel cada vez más activo al
|
||||
decidir si una función dada debe realmente ser en línea o no. Por lo tanto,
|
||||
la colocación liberal de palabras clave "inline" puede no solo ser
|
||||
excesiva; también podría ser irrelevante.
|
||||
|
||||
Bloqueo
|
||||
*******
|
||||
|
||||
En mayo de 2006, la pila de red "Devicescape" fue, con gran fanfarria,
|
||||
lanzada bajo la licencia GPL y puesta a disposición para su inclusión en el
|
||||
kernel principal. Esta donación fue una noticia bienvenida; el soporte para
|
||||
redes inalámbricas en Linux se consideraba, en el mejor de los casos,
|
||||
deficiente, y la pila de Devicescape ofrecía la promesa de solucionar esa
|
||||
situación. Sin embargo, este código no fue incluido en el kernel principal
|
||||
hasta junio de 2007 (versión 2.6.22). ¿Qué sucedió?
|
||||
|
||||
Este código mostró varios signos de haber sido desarrollado a puertas
|
||||
cerradas en una empresa. Pero un problema importante en particular fue que
|
||||
no estaba diseñado para funcionar en sistemas multiprocesador. Antes de que
|
||||
esta pila de red (ahora llamada mac80211) pudiera fusionarse, se tuvo que
|
||||
implementar un esquema de bloqueo en ella.
|
||||
|
||||
Hubo un tiempo en que se podía desarrollar código para el kernel de Linux
|
||||
sin pensar en los problemas de concurrencia que presentan los sistemas
|
||||
multiprocesador. Ahora, sin embargo, este documento se está escribiendo en
|
||||
una computadora portátil con dos núcleos. Incluso en sistemas de un solo
|
||||
procesador, el trabajo que se está realizando para mejorar la capacidad de
|
||||
respuesta aumentará el nivel de concurrencia dentro del kernel. Los días en
|
||||
que se podía escribir código para el kernel sin pensar en el bloqueo han
|
||||
quedado atrás.
|
||||
|
||||
Cualquier recurso (estructuras de datos, registros de hardware, etc.) que
|
||||
pueda ser accedido concurrentemente por más de un hilo debe estar protegido
|
||||
por un bloqueo. El nuevo código debe escribirse teniendo en cuenta este
|
||||
requisito; implementar el bloqueo después de que el código ya ha sido
|
||||
desarrollado es una tarea mucho más difícil. Los desarrolladores del kernel
|
||||
deben tomarse el tiempo para comprender bien los primitivos de bloqueo
|
||||
disponibles para elegir la herramienta adecuada para el trabajo. El código
|
||||
que muestre una falta de atención a la concurrencia tendrá un camino
|
||||
difícil para ser incluido en el kernel principal.
|
||||
|
||||
Regresiones
|
||||
***********
|
||||
|
||||
Un último peligro que vale la pena mencionar es el siguiente: puede ser
|
||||
tentador realizar un cambio (que puede traer grandes mejoras) que cause un
|
||||
problema para los usuarios existentes. Este tipo de cambio se llama una
|
||||
"regresión", y las regresiones se han vuelto muy mal recibidas en el kernel
|
||||
principal. Con pocas excepciones, los cambios que causan regresiones serán
|
||||
revertidos si la regresión no se puede solucionar de manera oportuna. Es
|
||||
mucho mejor evitar la regresión desde el principio.
|
||||
|
||||
A menudo se argumenta que una regresión puede justificarse si hace que las
|
||||
cosas funcionen para más personas de las que crea problemas. ¿Por qué no
|
||||
hacer un cambio si trae nueva funcionalidad a diez sistemas por cada uno
|
||||
que rompe? La mejor respuesta a esta pregunta fue expresada por Linus en
|
||||
julio de 2007 (traducido):
|
||||
|
||||
::
|
||||
|
||||
Entonces, no arreglamos errores introduciendo nuevos problemas. Eso
|
||||
lleva a la locura, y nadie sabe si realmente se avanza. ¿Es dos pasos
|
||||
adelante, uno atrás, o un paso adelante y dos atrás?
|
||||
|
||||
(https://lwn.net/Articles/243460/).
|
||||
|
||||
Un tipo de regresión especialmente mal recibido es cualquier tipo de cambio
|
||||
en la ABI del espacio de usuario. Una vez que se ha exportado una interfaz
|
||||
al espacio de usuario, debe ser soportada indefinidamente. Este hecho hace
|
||||
que la creación de interfaces para el espacio de usuario sea
|
||||
particularmente desafiante: dado que no pueden cambiarse de manera
|
||||
incompatible, deben hacerse bien desde el principio. Por esta razón,
|
||||
siempre se requiere una gran cantidad de reflexión, documentación clara y
|
||||
una amplia revisión para las interfaces del espacio de usuario.
|
||||
|
||||
Herramientas de verificación de código
|
||||
**************************************
|
||||
|
||||
Por ahora, al menos, escribir código libre de errores sigue siendo un ideal
|
||||
que pocos de nosotros podemos alcanzar. Sin embargo, lo que podemos esperar
|
||||
hacer es detectar y corregir tantos de esos errores como sea posible antes
|
||||
de que nuestro código se integre en el kernel principal. Con ese fin, los
|
||||
desarrolladores del kernel han reunido una impresionante variedad de
|
||||
herramientas que pueden detectar una amplia variedad de problemas oscuros
|
||||
de manera automatizada. Cualquier problema detectado por el ordenador es
|
||||
un problema que no afectará a un usuario más adelante, por lo que es lógico
|
||||
que las herramientas automatizadas se utilicen siempre que sea posible.
|
||||
|
||||
El primer paso es simplemente prestar atención a las advertencias
|
||||
producidas por el compilador. Las versiones contemporáneas de gcc pueden
|
||||
detectar (y advertir sobre) una gran cantidad de errores potenciales. Con
|
||||
bastante frecuencia, estas advertencias apuntan a problemas reales. El
|
||||
código enviado para revisión no debería, por regla general, producir
|
||||
ninguna advertencia del compilador. Al silenciar las advertencias, tenga
|
||||
cuidado de comprender la causa real e intente evitar "correcciones" que
|
||||
hagan desaparecer la advertencia sin abordar su causa.
|
||||
|
||||
Tenga en cuenta que no todas las advertencias del compilador están
|
||||
habilitadas de forma predeterminada. Compile el kernel con
|
||||
"make KCFLAGS=-W" para obtener el conjunto completo.
|
||||
|
||||
El kernel proporciona varias opciones de configuración que activan
|
||||
funciones de depuración; la mayoría de estas se encuentran en el submenú
|
||||
"kernel hacking". Varias de estas opciones deben estar activadas para
|
||||
cualquier kernel utilizado para desarrollo o pruebas. En particular,
|
||||
debería activar:
|
||||
|
||||
- FRAME_WARN para obtener advertencias sobre marcos de pila más grandes
|
||||
que una cantidad determinada. La salida generada puede ser extensa, pero
|
||||
no es necesario preocuparse por las advertencias de otras partes del
|
||||
kernel.
|
||||
|
||||
- DEBUG_OBJECTS agregará código para rastrear la vida útil de varios
|
||||
objetos creados por el kernel y advertir cuando se realicen cosas fuera
|
||||
de orden. Si está agregando un subsistema que crea (y exporta) objetos
|
||||
complejos propios, considere agregar soporte para la infraestructura de
|
||||
depuración de objetos.
|
||||
|
||||
- DEBUG_SLAB puede encontrar una variedad de errores en la asignación y
|
||||
uso de memoria; debe usarse en la mayoría de los kernels de desarrollo.
|
||||
|
||||
- DEBUG_SPINLOCK, DEBUG_ATOMIC_SLEEP y DEBUG_MUTEXES encontrarán una serie
|
||||
de errores comunes de bloqueo.
|
||||
|
||||
Hay bastantes otras opciones de depuración, algunas de las cuales se
|
||||
discutirán más adelante. Algunas de ellas tienen un impacto significativo
|
||||
en el rendimiento y no deben usarse todo el tiempo. Pero dedicar tiempo a
|
||||
aprender las opciones disponibles probablemente será recompensado muchas
|
||||
veces en poco tiempo.
|
||||
|
||||
Una de las herramientas de depuración más pesadas es el verificador de
|
||||
bloqueos, o "lockdep". Esta herramienta rastreará la adquisición y
|
||||
liberación de cada bloqueo (spinlock o mutex) en el sistema, el orden en
|
||||
que se adquieren los bloqueos en relación entre sí, el entorno actual de
|
||||
interrupción, y más. Luego, puede asegurarse de que los bloqueos siempre se
|
||||
adquieran en el mismo orden, que las mismas suposiciones de interrupción se
|
||||
apliquen en todas las situaciones, y así sucesivamente. En otras palabras,
|
||||
lockdep puede encontrar varios escenarios en los que el sistema podría, en
|
||||
raras ocasiones, bloquearse. Este tipo de problema puede ser doloroso
|
||||
(tanto para desarrolladores como para usuarios) en un sistema desplegado;
|
||||
lockdep permite encontrarlos de manera automatizada con anticipación. El
|
||||
código con cualquier tipo de bloqueo no trivial debe ejecutarse con lockdep
|
||||
habilitado antes de ser enviado para su inclusión.
|
||||
|
||||
Como programador diligente del kernel, sin duda alguna, verificará el
|
||||
estado de retorno de cualquier operación (como una asignación de memoria)
|
||||
que pueda fallar. Sin embargo, el hecho es que las rutas de recuperación de
|
||||
fallos resultantes probablemente no hayan sido probadas en absoluto. El
|
||||
código no probado tiende a ser código roto; podría tener mucha más
|
||||
confianza en su código si todas esas rutas de manejo de errores se hubieran
|
||||
ejercitado algunas veces.
|
||||
|
||||
El kernel proporciona un marco de inyección de fallos que puede hacer
|
||||
precisamente eso, especialmente donde están involucradas las asignaciones
|
||||
de memoria. Con la inyección de fallos habilitada, un porcentaje
|
||||
configurable de las asignaciones de memoria fallarán; estas fallas pueden
|
||||
restringirse a un rango específico de código. Ejecutar con la inyección de
|
||||
fallos habilitada permite al programador ver cómo responde el código cuando
|
||||
las cosas van mal. Consulte
|
||||
Documentation/fault-injection/fault-injection.rst para obtener más
|
||||
información sobre cómo utilizar esta funcionalidad.
|
||||
|
||||
Otros tipos de errores se pueden encontrar con la herramienta de análisis
|
||||
estático "sparse". Con sparse, el programador puede recibir advertencias
|
||||
sobre confusiones entre direcciones del espacio de usuario y del kernel,
|
||||
mezcla de cantidades big-endian y little-endian, el paso de valores enteros
|
||||
donde se espera un conjunto de banderas de bits, y así sucesivamente.
|
||||
Sparse debe instalarse por separado (puede encontrarse en
|
||||
https://sparse.wiki.kernel.org/index.php/Main_Page si su distribución no lo
|
||||
empaqueta); luego, puede ejecutarse en el código agregando "C=1" a su
|
||||
comando make.
|
||||
|
||||
La herramienta "Coccinelle" (http://coccinelle.lip6.fr/) puede encontrar
|
||||
una amplia variedad de posibles problemas de codificación; también puede
|
||||
proponer correcciones para esos problemas. Bastantes "parches semánticos"
|
||||
para el kernel se han empaquetado en el directorio scripts/coccinelle;
|
||||
ejecutar "make coccicheck" ejecutará esos parches semánticos e informará
|
||||
sobre cualquier problema encontrado. Consulte:
|
||||
ref:`Documentation/dev-tools/coccinelle.rst <devtools_coccinelle>` para
|
||||
obtener más información.
|
||||
|
||||
Otros tipos de errores de portabilidad se encuentran mejor compilando su
|
||||
código para otras arquitecturas. Si no tiene un sistema S/390 o una placa
|
||||
de desarrollo Blackfin a mano, aún puede realizar el paso de compilación.
|
||||
Un gran conjunto de compiladores cruzados para sistemas x86 se puede
|
||||
encontrar en
|
||||
|
||||
https://www.kernel.org/pub/tools/crosstool/
|
||||
|
||||
Muchos sistemas de compilación disponibles comercialmente también se pueden
|
||||
utilizar para compilar código de kernel para una amplia gama de
|
||||
arquitecturas.
|
||||
|
||||
Los desarrolladores del kernel son afortunados: tienen acceso a una
|
||||
variedad de herramientas de verificación de código de la que los
|
||||
desarrolladores de la mayoría de los otros sistemas pueden estar celosos.
|
||||
Pero todas esas herramientas no servirán de nada si no las usa. El
|
||||
resultado final de ignorar estas herramientas es simple: alguien más puede
|
||||
notificarle de un problema en su código a través de un "oportuno"
|
||||
comentario en la lista de correo o, peor aún, el código problemático podría
|
||||
ser eliminado. Es mucho más fácil usar estas herramientas en primer lugar.
|
||||
|
||||
Documentación
|
||||
*************
|
||||
|
||||
La documentación a menudo ha sido más la excepción que la regla en el
|
||||
desarrollo del kernel. Aun así, una documentación adecuada ayudará a
|
||||
facilitar la integración de nuevo código en el kernel, hará la vida más
|
||||
fácil a otros desarrolladores, y será útil para sus usuarios. En muchos
|
||||
casos, la inclusión de documentación se ha vuelto esencialmente
|
||||
obligatoria.
|
||||
|
||||
La primera pieza de documentación para cualquier parche es su changelog
|
||||
asociado. Las entradas de registro deben describir el problema que se está
|
||||
esolviendo, la forma de la solución, las personas que trabajaron en el
|
||||
parche, cualquier efecto relevante en el rendimiento, y cualquier otra cosa
|
||||
que pueda ser necesaria para entender el parche. Asegúrese de que el
|
||||
changelog diga *por qué* el parche vale la pena ser aplicado; un
|
||||
sorprendente número de desarrolladores no proporciona esa información.
|
||||
|
||||
Cualquier código que agregue una nueva interfaz para el espacio de usuario,
|
||||
incluidos los nuevos archivos de sysfs o /proc, debe incluir documentación
|
||||
de esa interfaz que permita a los desarrolladores del espacio de usuario
|
||||
saber con qué están trabajando. Consulte `Documentation/ABI/README` para
|
||||
una descripción de cómo debe formatearse esta documentación y qué
|
||||
información debe proporcionarse.
|
||||
|
||||
El archivo
|
||||
:ref:`Documentation/admin-guide/kernel-parameters.rst <kernelparameters>`
|
||||
describe todos los parámetros de arranque del kernel. Cualquier parche que
|
||||
agregue nuevos parámetros debe agregar las entradas correspondientes a este
|
||||
archivo.
|
||||
|
||||
Cualquier nueva opción de configuración debe ir acompañada de un texto de
|
||||
ayuda que explique claramente las opciones y cuándo el usuario podría
|
||||
querer seleccionarlas.
|
||||
|
||||
La información de la API interna para muchos subsistemas está documentada
|
||||
mediante comentarios especialmente formateados; estos comentarios pueden
|
||||
extraerse y formatearse de diversas maneras mediante el script
|
||||
"kernel-doc". Si está trabajando dentro de un subsistema que tiene
|
||||
comentarios de kerneldoc, debe mantenerlos y agregarlos según corresponda
|
||||
para las funciones disponibles externamente. Incluso en áreas que no han
|
||||
sido tan documentadas, no hay ningún inconveniente en agregar comentarios
|
||||
de kerneldoc para el futuro; de hecho, esta puede ser una actividad útil
|
||||
para desarrolladores de kernel principiantes. El formato de estos
|
||||
comentarios, junto con alguna información sobre cómo crear plantillas de
|
||||
kerneldoc, se puede encontrar en
|
||||
:ref:`Documentation/doc-guide/ <doc_guide>`.
|
||||
|
||||
Cualquiera que lea una cantidad significativa de código existente del
|
||||
kernel notará que, a menudo, los comentarios son notables por su ausencia.
|
||||
Una vez más, las expectativas para el nuevo código son más altas que en el
|
||||
pasado; integrar código sin comentarios será más difícil. Dicho esto, hay
|
||||
poco deseo de tener código excesivamente comentado. El código en sí debe
|
||||
ser legible, con comentarios que expliquen los aspectos más sutiles.
|
||||
|
||||
Ciertas cosas siempre deben comentarse. El uso de barreras de memoria debe
|
||||
ir acompañado de una línea que explique por qué la barrera es necesaria.
|
||||
Las reglas de bloqueo para las estructuras de datos generalmente necesitan
|
||||
explicarse en algún lugar. Las estructuras de datos importantes en general
|
||||
necesitan documentación completa. Las dependencias no obvias entre
|
||||
fragmentos de código separados deben señalarse. Cualquier cosa que pueda
|
||||
tentar a un maintainer de código a hacer una "limpieza" incorrecta necesita
|
||||
un comentario que explique por qué se hace de esa manera. Y así
|
||||
sucesivamente.
|
||||
|
||||
Cambios en la API interna
|
||||
*************************
|
||||
|
||||
La interfaz binaria proporcionada por el kernel al espacio de usuario no se
|
||||
puede romper, excepto en las circunstancias más graves. Las interfaces de
|
||||
programación internas del kernel, en cambio, son altamente fluidas y pueden
|
||||
cambiarse cuando surge la necesidad. Si usted se encuentra teniendo que
|
||||
hacer un rodeo alrededor de una API del kernel, o simplemente no utilizando
|
||||
una funcionalidad específica porque no cumple con sus necesidades, eso
|
||||
puede ser una señal de que la API necesita cambiar. Como desarrollador del
|
||||
kernel, usted está autorizado a hacer esos cambios.
|
||||
|
||||
Hay, por supuesto, algunas condiciones. Los cambios en la API se pueden
|
||||
hacer, pero necesitan estar bien justificados. Entonces, cualquier parche
|
||||
que realice un cambio en la API interna debe ir acompañado de una
|
||||
descripción de cuál es el cambio y por qué es necesario. Este tipo de
|
||||
cambio también debe desglosarse en un parche separado, en lugar de estar
|
||||
enterrado dentro de un parche más grande.
|
||||
|
||||
La otra condición es que un desarrollador que cambia una API interna
|
||||
generalmente está encargado de la tarea de corregir cualquier código dentro
|
||||
del árbol del kernel que se vea afectado por el cambio. Para una función
|
||||
ampliamente utilizada, este deber puede llevar a literalmente cientos o
|
||||
miles de cambios, muchos de los cuales probablemente entren en conflicto
|
||||
con el trabajo que otros desarrolladores están realizando. No hace falta
|
||||
decir que esto puede ser un trabajo grande, por lo que es mejor asegurarse
|
||||
de que la justificación sea sólida. Tenga en cuenta que la herramienta
|
||||
Coccinelle puede ayudar con los cambios de API a gran escala.
|
||||
|
||||
Cuando se realice un cambio incompatible en la API, siempre que sea
|
||||
posible, se debe asegurar que el código que no ha sido actualizado sea
|
||||
detectado por el compilador. Esto le ayudará a estar seguro de que ha
|
||||
encontrado todos los usos en el árbol de esa interfaz. También alertará a
|
||||
los desarrolladores de código fuera del árbol de que hay un cambio al que
|
||||
necesitan responder. Apoyar el código fuera del árbol no es algo de lo que
|
||||
los desarrolladores del kernel deban preocuparse, pero tampoco tenemos que
|
||||
dificultarles la vida más de lo necesario.
|
||||
|
||||
@@ -26,3 +26,4 @@ para entenderla.
|
||||
1.Intro
|
||||
2.Process
|
||||
3.Early-stage
|
||||
4.Coding
|
||||
|
||||
Reference in New Issue
Block a user