Pull to refresh

Сделаем код чище: Рекомендации по подготовке изменений в ядро Linux

Reading time 4 min
Views 14K
Продолжая тему улучшения кода ядра Linux хочу дать несколько рекомендаций, основанных как на жизненном опыте, так и на существующей документации.

Первые попытки могут и не увенчаться успехом, ниже некоторые рекомендации, чтобы снизить вероятность такого исхода. Коротко отмечу основные области возникновения проблем во время подготовки и отправки изменений:
  • Устаревшие, консервативные и специальные подсистемы ядра
  • Стиль кода и оформление изменений
  • Новизна изменения
  • Нюансы процесса

Дополнительно коротко расскажу про существующие механизмы проверки.

Подсистемы ядра


Среди всего множества подсистем ядра выделим следующие:
  1. arch/<архитектура>
  2. drivers/scsi
  3. fs/ (основная часть)
  4. drivers/isdn, drivers/ide и им подобные
  5. drivers/staging

Первая — архитектурный код. Часто содержит устаревшие архитектуры или код, который требует тщательного изучения и понимания. Изменять там что-то имеет смысл только если у вас действительно есть железка, на которой можно протестировать, и реальная проблема, с которой вы боретесь.

Вторая, SCSI, — пожалуй, самая консервативная подсистема в ядре, хотя туда и можно протащить изменения, но это самый жёсткий путь.

Третья — основная часть поддержки файловых систем. Одна из очень специфичных и чувствительных подсистем в ядре. Мейнтейнер Al Viro за словом в карман не полезет, и если вы попытаетесь сделать что-то не подумавши, то тут уж не обижайтесь — ответ получите не из приятных.

Четвёртая категория — изжившие подсистемы, поэтому туда принимаются только глобальные правки при смене внутреннего API.

Пятая подсистема для Вас! Не зря же я упоминал про staging ранее. В этой подсистеме драйверы проходят инкубационный период, то есть с одной стороны необходимость наличия драйвера вызвана рынком (есть устройства, нужна поддержка), но с другой — качество кода недостаточно для включения в одну из существующих подсистем. Отличное место для пробы пера. Greg KH очень лояльный мейнтейнер, только обязательно проверяйте изменения перед отправкой, иначе расстроите его.


Стиль и оформление


Существуют очень хорошие материалы в документации по стилю кода и оформлению изменений, а именно CodingStyle и SubmittingPatches. Настоятельно рекомендую ознакомится с ними перед началом каких-либо действий.

Новизна изменения


Перед тем как делать изменения поищите, может быть кто-то уже сделал это же самое? Не имеет смысла дублировать работу. Так, например, пользователь blueboar2 оформил изменение, а оказалось, что существует более раннее, чуть ли не годичной давности. А если присмотреться, то можно найти и гораздо старее.

Нюансы процесса


Не унывайте, если на ваше изменение нет реакции.

Во-первых надо учитывать, что мейнтенер может быть занят или отсутствовать.

Во-вторых, обычное время выдержки изменений на публике неделя или больше. Таким образом мейнтейнер даёт возможность высказаться другим участникам сообщества по поводу предлагаемого изменения.

В-третьих, существует примерно раз в квартал пару недель тишины. Это так называемое merge window, иными словами окно, когда мейнтейнеры подсистем шлют накопившиеся за предыдущий цикл изменения главному, то есть Linus'у. Окно начинается ровно с момента выхода очередной стабильной версии, в скором будущем v4.0. Также необходимо учитывать, что многие мейнтейнеры перестают принимать новый код уже после -rc5 (v4.0-rc5 ожидается в понедельник 23 марта), так как им самим надо разобраться со своими деревьями.


Механизмы проверки


Ниже я опишу несколько способов и инструментов для проверки изменения.

Для начала убедитесь, что ваше изменение как минимум компилируется. К примеру, если ваша правка была для drivers/staging/unisys/virtpci/virtpci.c, то через drivers/staging/unisys/virtpci/Makefile можно легко понять, какая конфигурационная опция отвечает за включение драйвера:

obj-$(CONFIG_UNISYS_VIRTPCI)    += virtpci.o

То есть нам надо найти как включить эту опцию. Поскольку мы знаем, что правка находится в staging, в подкаталоге unisys, в Kconfig которого определено меню UNISYSPAR, поэтому включить надо сразу несколько опций
CONFIG_STAGING=y
CONFIG_UNISYSPAR=y
CONFIG_UNISYS_VIRTPCI=m

Можно также пойти и по пути make menuconfig, догадавшись по описаниям что вы хотите включить.

В некоторых случаях, если сборка происходит на другой архитектуре, можно либо сделать это в виртуальной машине (KVM/Qemu), либо (в редких случаях) попытаться добавить в Kconfig зависимость на COMPILE_TEST, как, например, вот для такого драйвера:

--- a/drivers/ata/Kconfig
+++ b/drivers/ata/Kconfig
@@ -269,7 +269,7 @@ config ATA_PIIX

 config SATA_DWC
 	tristate "DesignWare Cores SATA support"
-	depends on 460EX
+	depends on 460EX || COMPILE_TEST
 	help
 	  This option enables support for the on-chip SATA controller of the
 	  AppliedMicro processor 460EX.

И добавить в кофигурацию ядра:
CONFIG_COMPILE_TEST=y

Совершенно не стоит отправлять такие патчи, не убедившись, что они собираются на всех архитектурах и не вносят огромное число предупреждений, не то разгневанный Linus придёт к вам в почтовый ящик.

Как же потестировать сборку? Вот тут мы переходим к следующим прекрасным переменным окружения при сборке, а именно W=1 C=1. Первая из них поднимает уровень предупреждений компилятора, вторая же, при установленном пакете sparse запускает статический анализатор кода. Следовательно, объединяя с -j8, получим:

$ make C=1 W=1 -j8

Перед сборкой полезным будет запуск:

$ make includecheck

Он осуществит поиск дублирующихся включений одних и тех же *.h файлов.

Теперь на руках у вас собранный модуль. Вы оформили изменения в виде *.patch файла с помощью git format-patch. Неплохо бы проверить стилистику кода. Запустим checkpatch.pl:
$ scripts/checkpatch.pl 00*
total: 0 errors, 0 warnings, 43 lines checked

0001-dmaengine-hsu-remove-redundant-pieces-of-code.patch has no obvious style problems and is ready for submission.

Лишний раз перед отправкой убедитесь, что вы оформили всё так, как требуется. Теперь смело запускайте git send-email.

Напоследок, для простейших изменений есть специальный адрес: trivial@kernel.org. Почитайте ещё такую статью по типу howto: Submitting (Trivial) Linux Kernel Patches.
Tags:
Hubs:
+37
Comments 1
Comments Comments 1

Articles