Сделаем код чище: Рекомендации по подготовке изменений в ядро Linux
Продолжая тему улучшения кода ядра Linux хочу дать несколько рекомендаций, основанных как на жизненном опыте, так и на существующей документации.Первые попытки могут и не увенчаться успехом, ниже некоторые рекомендации, чтобы снизить вероятность такого исхода. Коротко отмечу основные области возникновения проблем во время подготовки и отправки изменений:
Устаревшие, консервативные и специальные подсистемы ядра Стиль кода и оформление изменений Новизна изменения Нюансы процесса Дополнительно коротко расскажу про существующие механизмы проверки.
Подсистемы ядраСреди всего множества подсистем ядра выделим следующие:
arch/<архитектура> drivers/scsi fs/ (основная часть) drivers/isdn, drivers/ide и им подобные 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=yCONFIG_UNISYSPAR=yCONFIG_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.