Linux 内核补丁提交(Upstream)完整指南

本文档是一份面向 AMD GPU 驱动开发者的内核补丁提交实操指南,涵盖从环境准备到 patch 发送、review 跟进的全部流程。适用于通过邮件列表向 Linux 社区提交 patch series 的场景。


目录


概述

Linux 内核采用邮件列表 + patch 的协作模式。开发者将代码变更格式化为 patch,通过 git send-email 发送到对应的邮件列表,由 maintainer 和社区成员进行 review,经过若干轮修改后被 maintainer 合入(merge)。

典型的 AMD GPU 驱动 patch 合入路径:

复制代码
开发者 patch
  → amd-gfx 邮件列表 review
    → amd-staging-drm-next 分支
      → drm-next
        → linux-next
          → Linus mainline

第一阶段:环境准备

1.1 安装 git send-email

git send-email 是发送 patch 的标准工具,大多数发行版需要单独安装:

bash 复制代码
# Debian / Ubuntu
sudo apt install git-email

# Fedora / RHEL
sudo dnf install git-email

# Arch Linux
sudo pacman -S git

验证安装:

bash 复制代码
git send-email --help

1.2 配置 SMTP

~/.gitconfig 中添加 SMTP 配置。以下为常见邮件服务的示例:

Office365 / Outlook(企业常用)

ini 复制代码
[sendemail]
    smtpserver = smtp.office365.com
    smtpserverport = 587
    smtpencryption = tls
    smtpuser = your.name@company.com
    from = Your Name <your.name@company.com>

Gmail

ini 复制代码
[sendemail]
    smtpserver = smtp.gmail.com
    smtpserverport = 587
    smtpencryption = tls
    smtpuser = yourname@gmail.com
    from = Your Name <yourname@gmail.com>

注意:

  • Gmail 需要开启"应用专用密码"(App Password),不能使用普通密码。
  • 部分企业邮箱需要 IT 部门开启 SMTP 访问或提供 App Password。
  • 首次发送时 git 会提示输入密码,可通过 git credential 缓存。

1.3 配置 git 用户信息

确保 git 用户信息与你的邮件列表注册信息一致:

bash 复制代码
git config --global user.name "Your Name"
git config --global user.email "your.name@company.com"

1.4 订阅相关邮件列表

在发送 patch 之前,务必先订阅目标邮件列表,否则你的邮件可能被 moderation 队列阻拦,且你无法收到 review 回复。

常用 DRM / AMD GPU 相关列表:

邮件列表 订阅地址
amd-gfx https://lists.freedesktop.org/mailman/listinfo/amd-gfx
dri-devel https://lists.freedesktop.org/mailman/listinfo/dri-devel
linux-kernel (LKML) http://vger.kernel.org/vger-lists.html#linux-kernel

提示: LKML 邮件量极大,建议不订阅或配置邮件过滤规则。通常只 Cc 即可,不需要主动阅读 LKML 上的所有邮件。


第二阶段:代码准备

2.1 选择正确的基线分支

你的 patch 必须基于正确的上游分支。选择错误的基线会导致 patch 无法应用。

bash 复制代码
# 添加上游 remote(如果还没有)
git remote add drm-misc https://gitlab.freedesktop.org/drm/misc/kernel.git
git remote add upstream https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git

# 获取最新代码
git fetch drm-misc
git fetch upstream

# 基于 drm-next 创建工作分支
git checkout -b my-feature drm-misc/drm-next

不同子系统的基线分支选择:

子系统 推荐基线
AMD GPU (amdgpu) amd-staging-drm-nextdrm-next
DRM core drm-misc-next
内存管理 (mm) mm-unstablelinux-next
通用内核 torvalds/master

2.2 Rebase 到最新基线

bash 复制代码
git rebase drm-misc/drm-next

解决所有冲突后确保编译通过。

2.3 整理 commit 历史

每个 commit 应该是一个 逻辑完整、可独立编译 的变更单元。使用 interactive rebase 整理:

bash 复制代码
git rebase -i <base-commit>

整理原则:

  • 一个 commit 做一件事 --- 不要在一个 commit 中混合功能添加和 bug 修复
  • 每个 commit 都能编译通过 --- bisect 友好
  • 合理的提交顺序 --- 基础设施先行,功能实现随后,最后接入(wire-up)
  • 不要有 fixup commit --- 应该 squash 到对应的 commit 中

第三阶段:Commit Message 规范

3.1 格式要求

复制代码
subsystem: 简短描述 (不超过 72 字符)

详细描述,解释 what(做了什么)和 why(为什么要做),
而不是 how(怎么做的,代码本身会说明)。

如果有多个段落,用空行分隔。

可以使用列表:
  - 第一点
  - 第二点

Signed-off-by: Your Name <your.name@company.com>

3.2 标题行规则

  • 格式: 子系统前缀: 简短描述
  • 不超过 72 个字符
  • 首字母小写(前缀后的第一个单词)
  • 不以句号结尾
  • 使用祈使语气("add support" 而非 "added support")

AMD GPU 驱动常见前缀示例:

复制代码
drm/amdgpu:              # amdgpu 驱动通用
drm/amdgpu/vcn:          # VCN 子模块
drm/amdkfd:              # KFD 子模块
drm/amd/pm:              # 电源管理
drm/amd/display:         # 显示

3.3 描述正文

  • 解释 为什么 需要这个变更(动机、问题背景)
  • 描述 做了什么(高层设计思路)
  • 如果是 bug 修复,描述问题的根因和修复方式
  • 引用相关的讨论链接(如有)
  • 每行不超过 75 个字符

3.4 Signed-off-by (SOB)

每个 commit 必须Signed-off-by 标签,表示你同意 Developer Certificate of Origin (DCO):

复制代码
Signed-off-by: Your Name <your.name@company.com>

⚠️ 警告:SOB 邮箱必须与 Author 邮箱一致。 如果 git config user.emailYour.Name@company.com,则 SOB 也必须是同一个地址,大小写保持一致。

使用 git commit -s 可以自动添加 SOB。

3.5 其他常用标签

复制代码
# 此 patch 修复了某个 commit 引入的 bug
Fixes: <12位hash> ("原 commit 标题")

# 经过某人 review 同意
Reviewed-by: Reviewer Name <reviewer@email.com>

# 经过某人测试验证
Tested-by: Tester Name <tester@email.com>

# 致谢,例如某人提供了想法或早期代码
Suggested-by: Someone <someone@email.com>

# 抄送,将 patch 邮件抄送给特定的人
Cc: Someone <someone@email.com>

第四阶段:质量检查

4.1 运行 checkpatch.pl

这是 必须 执行的步骤。checkpatch 会检查代码风格、commit message 格式等:

bash 复制代码
# 检查最近 N 个 commit
git format-patch -N -o /tmp/patches/
scripts/checkpatch.pl /tmp/patches/*.patch

# 或者直接检查 git commit
scripts/checkpatch.pl --git HEAD~N..HEAD

修复所有 ERROR 。对于 WARNING,大部分也应修复;如果确实无法避免,需要在 cover letter 中说明理由。

常见的 checkpatch 问题:

  • 行超过 80/100 字符
  • 缺少空行
  • 注释格式不对
  • commit message 标题超过 72 字符
  • 尾部多余空白

4.2 编译检查

确保每个 commit 都能独立编译通过:

bash 复制代码
# 基本编译
make M=drivers/gpu/drm/amd/amdgpu

# 启用 sparse 静态分析
make C=1 M=drivers/gpu/drm/amd/amdgpu

# 完整内核编译(如果改动涉及头文件)
make -j$(nproc)

# 启用更多警告
make W=1 M=drivers/gpu/drm/amd/amdgpu

4.3 运行测试

根据你的变更运行相关测试:

  • IGT GPU Tools : igt_runner 测试套件
  • KFD 测试 : kfdtest
  • 内核自测试 : make kselftest

在 cover letter 中描述你的测试方法和结果。

4.4 检查文档

如果你的变更涉及 UAPI(用户空间接口)、新的 sysfs/debugfs 节点、或新的 ioctl,需要同步更新文档:

bash 复制代码
# 构建文档检查
make htmldocs

# 检查是否有文档警告
make htmldocs 2>&1 | grep -i warning

第五阶段:生成 Patch Series

5.1 使用 git format-patch

bash 复制代码
# 生成 patch series,含 cover letter
git format-patch -N --cover-letter -o /tmp/patches/

# 参数说明:
#   -N             最近 N 个 commit
#   --cover-letter 生成 cover letter(0000-cover-letter.patch)
#   -o DIR         输出目录
#   --base=auto    自动记录基线信息(推荐)

# 完整示例
git format-patch -5 --cover-letter --base=auto -o /tmp/patches/ \
    --subject-prefix="PATCH"

5.2 Subject Prefix 约定

前缀 含义
[PATCH] 首次提交
[PATCH v2] 第二版(响应 review 修改后)
[PATCH RFC] 征求意见稿,不期望直接合入
[PATCH RESEND] 重新发送(无修改)
[PATCH 0/N] Cover letter(N 个 patch 的系列)

通过 --subject-prefix 指定:

bash 复制代码
# RFC patch
git format-patch --subject-prefix="RFC PATCH" ...

# 第二版
git format-patch --subject-prefix="PATCH v2" ...

5.3 撰写 Cover Letter

Cover letter 是整个 patch series 的总览,是 reviewer 首先阅读的内容。编辑生成的 0000-cover-letter.patch

复制代码
Subject: [PATCH 0/N] subsystem: 整个 series 的简短描述

这个 patch series 实现了 XXX 功能。

=== 背景与动机 ===
描述为什么需要这组变更,解决什么问题。

=== 设计概述 ===
高层描述整体设计方案。

=== 依赖关系 ===
如果依赖其他尚未合入的 patch series,在此说明:
- 依赖: [PATCH vN] "series title" by Author
  https://lore.kernel.org/链接

=== 测试 ===
描述测试方法:
- 硬件平台: GPU 型号
- 测试用例: IGT / kfdtest / 自定义测试
- 测试结果

=== 变更历史(v2 及以后版本需要)===
v2:
  - 修复了 XXX 问题 (Reviewer 的建议)
  - 重构了 YYY 函数
v1:
  - https://lore.kernel.org/初次提交链接

Your Name (N):
  subsystem: patch 1 标题
  subsystem: patch 2 标题
  ...

 file1.c | 100 ++++++++++++
 file2.h |  20 ++
 N files changed, X insertions(+), Y deletions(-)

5.4 确认收件人

使用 get_maintainer.pl 自动确定收件人:

bash 复制代码
scripts/get_maintainer.pl /tmp/patches/*.patch

输出会列出所有相关的 maintainer 和邮件列表。一般规则:

  • To: Subsystem maintainer(s) + 主要邮件列表
  • Cc: 更上层的 maintainer + 更广泛的邮件列表 + 相关开发者

提示: get_maintainer.pl 的输出可以直接作为 git send-email 的参数:

bash 复制代码
scripts/get_maintainer.pl --separator=, /tmp/patches/*.patch

第六阶段:发送 Patch

6.1 先发送测试邮件

强烈建议 先发给自己测试:

bash 复制代码
git send-email --to=yourself@email.com /tmp/patches/*.patch

检查收到的邮件:

  • 格式是否正确(纯文本,非 HTML)
  • patch 能否通过 git am 应用
  • 编码没有乱码
  • 线程关系正确(cover letter 为父,各 patch 为回复)

6.2 正式发送

bash 复制代码
git send-email \
    --to="Maintainer1 <maintainer1@email.com>" \
    --to="Maintainer2 <maintainer2@email.com>" \
    --to="subsystem-list@lists.freedesktop.org" \
    --cc="dri-devel@lists.freedesktop.org" \
    --cc="linux-kernel@vger.kernel.org" \
    /tmp/patches/*.patch

git send-email 会逐个发送并提示确认。

6.3 验证发送成功

发送后,在以下平台验证你的 patch 已出现:


第七阶段:Review 与迭代

7.1 响应 review 意见

  • 及时回复 --- 收到 review 后尽快回复,即使是说"感谢,我会在 v2 中修复"
  • 逐条回应 --- 对每条 review 意见给出回复
  • 保持礼貌 --- 即使不同意,也要说明理由,不要忽略
  • 底部回复 (bottom-post) --- Linux 社区使用底部回复风格,不要顶部回复

回复示例:

复制代码
> Review comment about your code
>
> Suggestion to change XXX

Good point. I'll fix this in v2. The new approach will be ...

7.2 提交 v2(修订版)

根据 review 修改代码后:

bash 复制代码
# 修改 commit(rebase -i, amend 等)
git rebase -i <base>

# 生成 v2 patch
git format-patch -N --cover-letter --base=auto \
    --subject-prefix="PATCH v2" -o /tmp/patches-v2/

# 在 cover letter 中添加变更历史
# 发送
git send-email ... /tmp/patches-v2/*.patch

注意: v2 发送时,收件人列表保持与 v1 相同,并加上在 v1 中给出 review 意见的人。

7.3 添加 Reviewed-by / Acked-by

如果 reviewer 给出了 Reviewed-byAcked-by 标签,在 v2 中将其添加到对应 commit 的 SOB 区域:

复制代码
Signed-off-by: Your Name <your@email.com>
Reviewed-by: Reviewer Name <reviewer@email.com>

7.4 等待与催促

  • 正常等待 --- 1-2 周是正常的 review 周期
  • 催促 (ping) --- 超过 2 周没有回复,可以回复自己的 patch 邮件 ping 一下
  • RESEND --- 如果怀疑邮件丢失,可以用 [PATCH RESEND] 重发
  • 合入确认 --- patch 被接受后,maintainer 会回复或在 patchwork 标记状态

附录

A. 常用命令速查

bash 复制代码
# 生成 patch
git format-patch -N --cover-letter --base=auto -o /tmp/patches/

# 检查代码风格
scripts/checkpatch.pl /tmp/patches/*.patch

# 查找 maintainer
scripts/get_maintainer.pl /tmp/patches/*.patch

# 发送 patch
git send-email --to=... --cc=... /tmp/patches/*.patch

# 应用收到的 patch(reviewer 测试用)
git am /path/to/patch.mbox

# 检查 commit message
git log --oneline -N

B. 重要参考文档

文档 链接
内核官方补丁提交指南 https://www.kernel.org/doc/html/latest/process/submitting-patches.html
内核编码风格 https://www.kernel.org/doc/html/latest/process/coding-style.html
邮件客户端配置指南 https://www.kernel.org/doc/html/latest/process/email-clients.html
内核邮件列表存档与搜索 https://lore.kernel.org/
DRM 子系统 patch 跟踪 https://patchwork.freedesktop.org/

C. Checklist(提交前检查清单)

环境准备
  • git send-email 已安装
  • SMTP 已配置且测试通过
  • 已订阅目标邮件列表
代码质量
  • 基于正确的上游分支(drm-next / amd-staging-drm-next
  • 每个 commit 逻辑独立、可编译
  • checkpatch.pl 无 ERROR
  • 编译通过(含 sparse 检查)
  • 相关测试通过
Commit Message
  • 标题 ≤72 字符,格式正确
  • 正文描述 what 和 why
  • Signed-off-by 邮箱与 Author 一致
  • Fixes 标签(如果是 bug 修复)
提交材料
  • Cover letter 已撰写(背景、设计、测试、变更历史)
  • get_maintainer.pl 确认收件人
  • 测试邮件发送成功
  • 正式 patch 已发送
  • lore.kernel.org 可搜索到
相关推荐
三道渊2 小时前
Linux进程通信与信号处理全解析
linux·服务器·网络
Java后端的Ai之路2 小时前
sudo 命令详解:Linux 权限管理的“万能钥匙“
linux·运维·服务器·sudo
努力努力再努力wz2 小时前
【C++高阶系列】告别内查找局限:基于磁盘 I/O 视角的 B 树深度剖析与 C++ 泛型实现!(附B树实现源码)
java·linux·开发语言·数据结构·c++·b树·算法
艾莉丝努力练剑2 小时前
【QT】Qt常用控件与布局管理深度解析:从原理到实践的架构思考
linux·运维·服务器·开发语言·网络·qt·架构
格林威2 小时前
Linux系统工业相机:Linux udev 规则绑定相机设备
linux·运维·开发语言·人工智能·数码相机·计算机视觉·工业相机
IMPYLH2 小时前
Linux 的 mv 命令
linux·运维·服务器·bash
weixin_423533992 小时前
虚拟机-ubuntu突然连不上网,网络图标消失
linux·运维·ubuntu
zzzsde2 小时前
【Linux】进程间通信(3)system V信号量
linux·运维·服务器
峥无2 小时前
Linux 调试效率革命:CGDB
linux·运维·服务器