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 可搜索到
相关推荐
FoldWinCard7 小时前
D5 Linux 网络及端口命令
linux·运维·服务器
零涂毕业设计9 小时前
毕业设计模块开发-OLED显示屏(IIC协议0.96寸)STM32 ESP32 FPGA Linux驱动免费分享
linux·stm32·单片机·嵌入式·esp32·fpga·oled
tedcloud1239 小时前
OmniRoute怎么部署?开源AI模型路由平台Linux部署教程
linux·服务器·人工智能·开源·音视频
霸道流氓气质9 小时前
KMS 密钥管理服务(Key Management Service)原理与实践
linux·服务器·数据库
SakitamaX9 小时前
LVS(Linux Virtual Server)概念详解
linux·运维·lvs
小张同学a.9 小时前
Linux系统管理
linux·运维
阿龙的工作记录10 小时前
深入理解Linux设备驱动模型
linux·嵌入式硬件·工作记录
代码村新手10 小时前
Linux的基本指令
linux·运维·服务器
hkj880811 小时前
Ubuntu 切换java版本
java·linux·ubuntu
撩得Android一次心动12 小时前
Linux编程笔记3【个人用】
linux·笔记