向 Linux 内核社区提交补丁的流程

制作补丁

  1. 下载代码, 如 linux-next 仓

    1git clone https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git
    
  2. 编辑文件,git diff 查看修改的内容。

  3. 添加文件到工作区:

    1git add <file>
    
  4. 生成 commit(-s 添加 Signed-off-by):

    1git commit -s
    

编写 Commit Message 的注意事项

  1. 补丁的标题要合适,可以使用 git log 参考已有补丁的标题;标题要反映补丁实际修改,避免太抽象或空乏。

  2. Commit Message 要写清楚问题,根因分析,以及解决方法;主要关注为什么这么做,而不仅仅是做了什么。在问题描述中可以加入错误日志。写作风格可参考该文档 所述:

    Describe your changes in imperative mood, e.g. “make xyzzy do frotz” instead of “[This patch] makes xyzzy do frotz” or “[I] changed xyzzy to do frotz”, as if you are giving orders to the codebase to change its behaviour.

    也就是写作时使用祈使语气,像是在对一台机器下命令那样。

  3. 如果是 Bugfix 补丁,要添加 Fixes tag,通过 git log 找到引入问题的补丁后使用以下命令生成 Fixes tag:

    1git log <commit_id> -1 --abbrev-commit --abbrev=12 --format='Fixes: %h ("%s")'
    

    例如:Fixes: aa1fa28fc73e ("io_uring: add support for recvmsg()")

  4. 如果问题在 stable 版本也存在,需要添加 Cc tag:

    1Cc: stable@vger.kernel.org
    

    若可以进一步确定是某一版本以上涉及:

    1Cc: stable@vger.kernel.org # v5.5+
    

生成补丁文件

单个补丁

1git format-patch -1 [commit_id] --subject-prefix="PATCH -next"
  • clean up 或者新特性,需要加 –next 标识;
  • linux-next 仓的补丁,需要添加 -next 标识;
  • net-next 仓补丁需要加 net-next
  • net 仓加 net
  • Wireless 仓不需要加任何标识。

补丁系列

若问题是通过一个系列补丁解决的,补丁发出时,需要制作补丁系列:

1git format-patch -3 [commit_id] --subject-prefix="PATCH -next" --cover-letter 

这会生成一系列文件,如:

10000-cover-letter.patch
20001-sh-fault-modernize-printing-of-kernel-messages.patch
30002-sh-drop-__pXd_offset-macros-that-duplicate-pXd_index.patch
40003-sh-add-support-for-folded-p4d-page-tables.patch

编辑 0000-cover-letter.patch 中下图标识的这两处。标题可以描述整个系列的工作,Commit Message 可以详细介绍整个补丁系列解决的问题和方法。

Cover Letter

最终效果示例:

Kernel Patch Example 1

提交补丁

  1. 检查补丁格式问题:

    1./scripts/checkpatch.pl your.patch
    

    修复脚本检查到的补丁格式问题, 使用 git commit --amend 修改提交记录后重新生成补丁。

  2. 获取相关 Maintainer 邮件地址:

    1./scripts/get_maintainer.pl your.patch
    

    补丁系列可以一起(去掉 0000 补丁):

    1./scripts/get_maintainer.pl *.patch
    
    • 有些 Maintainer 较少的模块,可以使用 git log <file> 来查看最近修改过该文件的相关作者一起抄送。
    • Bugfix 补丁要抄送引入问题的补丁的作者。
  3. 配置好 git-email 1后发送补丁,注意先看看是否有人已经发过了

    1git send-email --to hverkuil@xs4all.nl --to mchehab@kernel.org --to gregkh@linuxfoundation.org --to tglx@linutronix.de --cc linux-media@vger.kernel.org --cc devel@driverdev.osuosl.org --cc linux-kernel@vger.kernel.org linux/*.patch
    

    可以一次将整个系列的补丁放在一个目录下一起发送。

社区交流

社区邮件列表 中选择自己感兴趣的订阅,如:

方法参考:http://vger.kernel.org/majordomo-info.html

  1. 补丁提交到社区后,就可以在邮件列表中收到。若补丁发出后一至两周或者更长时间没有回复,可回复“ping”提醒一下,注意不要频繁 ping。
  2. 有人 review 或者 ack,补丁不需要继续操作,等 Maintainer 合入即可。

补丁新版本制作

  1. 收集之前得到的 Reviewed-by 和 Acked-by,在新版本中附上。

  2. 在补丁标题处添加“v2”标识补丁的版本(用 --subject-prefix)。

  3. 在补丁的 --- 短线下添加新版本补丁的 changelog。增添在此处的 log 在最终合入时不会出现在补丁的 commit message 中,适合在社区交流时使用。

    Kernel Patch Example 2

    若是补丁系列,需要将 changelog 加在 cover-letter 中:

    Kernel Patch Example 3

    Kernel Patch Example 3.1

  4. 重新发送补丁。若在上一版的交流中有新加入讨论的人,发送时需将他们加入抄送。同时添加 --in-reply-to=<Message ID>,或者不加 --in-reply-to 也可以:

    1git send-email --to benh@kernel.crashing.org --to paulus@samba.org --to mpe@ellerman.id.au --cc linuxppc-dev@lists.ozlabs.org --cc linux-kernel@vger.kernel.org --in-reply-to=20210514200453.1542978-1-arnd@kernel.org your.patch
    

    Message ID 可以在邮件原文中获取(雷鸟 中右键邮件→"View Source"):

    Kernel Patch Example 4

补丁合入

一般 Maintainer 会回复合入,也可能有部分模块没有提示。可通过更新本地的 linux-next 仓查看合入记录,或者到 Patchwork 上查看补丁状态。

参考内容


  1. 具体的 git-email 配置方法超出了本文的范围,请参考其他文章。 ↩︎


记一次 Android Native 层的 Debug 过程
ELF 调试器示例代码