커널 패치 제출 (Kernel Patch Submission)
커널 소스 코드 변경 사항을 커뮤니티에 제출하는 전체 과정을 다룹니다. 코딩 스타일 준수부터 git format-patch, git send-email, 리뷰 대응, 머지 과정까지 실무에 필요한 모든 단계를 설명합니다.
핵심 요약
- git format-patch — 커밋을 이메일 형식의 패치 파일(.patch)로 변환하는 명령입니다.
- git send-email — 생성된 패치를 SMTP로 메일링 리스트에 전송합니다.
- checkpatch.pl — 커널 코딩 스타일 준수 여부를 자동으로 검사하는 스크립트입니다.
- get_maintainer.pl — 패치를 보낼 메인테이너와 메일링 리스트를 찾아주는 스크립트입니다.
- Signed-off-by — 개발자가 DCO(Developer Certificate of Origin)에 동의함을 나타내는 필수 태그입니다.
단계별 이해
- 코드 작성 — 커널 코딩 스타일(K&R, 탭 8칸, 80열)을 준수하며 버그 수정이나 기능 개선 코드를 작성합니다.
checkpatch.pl로 스타일을 검증합니다. - 커밋 생성 — 변경 사항을 논리적 단위로 분리하여 커밋합니다. 커밋 메시지에
Signed-off-by태그를 포함합니다.git commit -s로 자동 추가할 수 있습니다. - 패치 생성 및 전송 —
git format-patch로 패치 파일을 만들고,get_maintainer.pl로 수신자를 찾은 뒤git send-email로 전송합니다.전송 전 자신에게 먼저 보내서 형식을 확인하는 것이 좋습니다.
- 리뷰 대응 — 메일링 리스트의 피드백에 인라인으로 응답하고, 필요 시 수정 버전(v2, v3...)을 재전송합니다.
리뷰어의
Reviewed-by,Acked-by태그를 수집합니다.
커뮤니티 문화와 기본 원칙
리눅스 커널은 세계 최대의 협업 소프트웨어 프로젝트입니다. 수천 명의 개발자가 이메일 기반 워크플로로 협업하며, 명확한 규칙과 에티켓이 원활한 협업의 기반이 됩니다.
오픈소스 에티켓
- 이메일 기반 — 커널 개발은 GitHub PR이 아닌 메일링 리스트(LKML 등)를 통해 이루어집니다. 모든 논의는 공개 아카이브에 영구 보존됩니다.
- 플레인 텍스트 — HTML 메일, 첨부 파일(인라인 패치만 허용), 탑 포스팅(top-posting)을 피합니다. 인라인 응답(inline reply)이 표준입니다.
- 소규모 패치 — 하나의 패치는 하나의 논리적 변경만 담아야 합니다. 대규모 변경은 패치 시리즈로 분할합니다.
- 인내와 존중 — 리뷰에 시간이 걸릴 수 있습니다(1~2주). 정중하게 핑(ping)하되, 재촉하지 않습니다.
DCO (Developer Certificate of Origin)
DCO는 패치 제출자가 해당 코드의 기여 권한을 가지고 있음을 증명하는 선언입니다.
모든 커널 패치에는 Signed-off-by 태그가 필수입니다.
/* DCO 원문 요약 (https://developercertificate.org/) */
(a) 기여 내용이 나에 의해 전부 또는 일부 작성되었으며,
해당 파일에 명시된 오픈소스 라이선스로 제출할 권리가 있다.
(b) 기여가 기존 오픈소스 작업에 기반하며,
동일하거나 호환 라이선스로 제출할 수 있다.
(c) (a), (b), (c) 중 하나에 해당하는 사람이 직접 제공한 것이다.
(d) 이 프로젝트와 기여가 공개됨을 이해하며,
기록이 영구 보관되고 재배포될 수 있음을 이해한다.
주요 태그 (Signed-off-by, Reviewed-by 등)
커밋 메시지 하단에 포함되는 주요 태그들입니다:
| 태그 | 의미 | 누가 추가하나? |
|---|---|---|
Signed-off-by: |
DCO 동의, 패치 전달 경로 기록 | 작성자, 중간 메인테이너 (필수) |
Reviewed-by: |
코드를 검토하고 문제가 없음을 확인 | 리뷰어 |
Acked-by: |
해당 서브시스템에 포함되어도 좋다는 승인 | 서브시스템 메인테이너 |
Tested-by: |
실제 환경에서 테스트를 수행하고 동작을 확인 | 테스터 |
Reported-by: |
버그를 보고한 사람 | 패치 작성자가 기재 |
Suggested-by: |
해결 방법을 제안한 사람 | 패치 작성자가 기재 |
Fixes: |
이 패치가 수정하는 원인 커밋 참조 | 패치 작성자 |
Cc: |
이 패치에 관심 있을 사람에게 사본 전송 | 패치 작성자 |
Link: |
관련 논의/버그 리포트 URL | 메인테이너가 적용 시 추가 |
# 태그 사용 예시 (커밋 메시지 하단)
Fixes: a1b2c3d4e5f6 ("mm: fix use-after-free in page_alloc")
Reported-by: Jane Doe <jane@example.com>
Signed-off-by: John Developer <john@example.com>
Reviewed-by: Senior Maintainer <senior@kernel.org>
코딩 스타일
스타일 개요 (K&R, 탭 8칸, 80열)
커널 코딩 스타일은 Documentation/process/coding-style.rst에 정의되어 있습니다.
핵심 규칙은 다음과 같습니다:
- 들여쓰기: 탭(Tab) 문자, 너비 8칸. 스페이스로 들여쓰기하지 않습니다.
- 줄 길이: 80열 권장. 100열 초과 시
checkpatch.pl이 경고합니다. - 중괄호: K&R 스타일. 함수만 예외적으로 여는 중괄호를 다음 줄에 배치합니다.
- 네이밍: snake_case 사용. 헝가리안 표기법이나 CamelCase를 사용하지 않습니다.
- 함수 길이: 한 화면(24줄)에 들어올 정도로 짧게 유지합니다.
- 주석: C89 스타일(
/* ... */) 사용. C99 한 줄 주석(//)은 사용하지 않습니다.
/* K&R 스타일 예시 — 올바른 커널 코딩 스타일 */
static int example_function(struct device *dev, unsigned long flags)
{
struct example_data *data;
int ret;
data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
if (!data)
return -ENOMEM;
ret = do_something(data, flags);
if (ret) {
dev_err(dev, "failed to do something: %d\\n", ret);
goto err_free;
}
return 0;
err_free:
devm_kfree(dev, data);
return ret;
}
goto는 에러 처리 경로에서 적극적으로 사용됩니다.
중첩된 if-else보다 goto를 통한 집중적 에러 처리(centralized error handling)가 선호됩니다.
checkpatch.pl 활용
scripts/checkpatch.pl은 패치나 소스 파일이 코딩 스타일을 준수하는지 검사합니다.
패치 제출 전 반드시 실행해야 합니다.
# 패치 파일 검사
$ ./scripts/checkpatch.pl 0001-fix-memory-leak.patch
# 소스 파일 직접 검사
$ ./scripts/checkpatch.pl --file drivers/example/example.c
# 스테이지된 변경 검사
$ git diff --cached | ./scripts/checkpatch.pl -
# 마지막 3개 커밋 검사
$ ./scripts/checkpatch.pl -g HEAD~3..HEAD
checkpatch.pl은 ERROR(반드시 수정), WARNING(가급적 수정), CHECK(검토 필요) 세 단계로 문제를 보고합니다.
ERROR는 모두 수정해야 하며, WARNING도 합리적 사유 없이는 무시하지 않습니다.
checkpatch.pl이 모든 것을 잡지는 못합니다. 스타일 검사를 통과해도 논리적 오류나 설계 문제는 리뷰어가 지적할 수 있습니다.
반대로, 정당한 이유가 있다면 일부 WARNING은 무시할 수 있습니다(커밋 메시지에 사유를 명시).
Git 워크플로
저장소 클론 및 설정
# Linus 트리 클론 (전체 히스토리)
$ git clone https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
$ cd linux
# 또는 관련 서브시스템 트리 사용 (더 빠른 반영)
$ git remote add net-next \
https://git.kernel.org/pub/scm/linux/kernel/git/netdev/net-next.git
$ git fetch net-next
# 사용자 정보 설정 (Signed-off-by에 사용됨)
$ git config user.name "Your Name"
$ git config user.email "your.email@example.com"
# 유용한 Git 설정
$ git config diff.renames true
$ git config diff.algorithm patience
$ git config core.abbrev 12
토픽 브랜치 작성
# 최신 메인라인 기준으로 토픽 브랜치 생성
$ git checkout -b fix/memory-leak-page-alloc origin/master
# 또는 서브시스템 트리 기준
$ git checkout -b feature/new-driver net-next/main
# 코드 수정 후 커밋
$ git add mm/page_alloc.c
$ git commit -s # -s 옵션: Signed-off-by 자동 추가
베이스 선택: 패치의 베이스는 해당 서브시스템의 최신 개발 브랜치여야 합니다.
예를 들어 네트워크 패치는 net-next/main, 메모리 패치는 akpm/mm-unstable을 기준으로 합니다.
잘못된 베이스는 충돌을 야기하고 리뷰를 지연시킵니다.
커밋 메시지 규약
커밋 메시지는 정해진 형식을 따라야 합니다:
subsystem: brief summary in imperative mood (max ~75 chars)
More detailed explanation of what the patch does, why it is needed,
and how it works. Wrap at 72-75 characters per line.
For bug fixes, describe the problem first, then the solution.
Reference kernel versions or commits if applicable.
# Fixes 태그 (버그 수정 시)
Fixes: a1b2c3d4e5f6 ("subsystem: commit that introduced the bug")
Reported-by: Bug Reporter <reporter@example.com>
Closes: https://bugzilla.kernel.org/show_bug.cgi?id=XXXXX
Signed-off-by: Your Name <your.email@example.com>
커밋 메시지 작성 규칙:
- 제목 줄:
서브시스템: 변경 요약형식. 영문 소문자로 시작, 마침표 없음, 명령형(imperative mood) 사용 - 빈 줄: 제목과 본문 사이에 반드시 빈 줄 삽입
- 본문: "무엇을" 변경했는지보다 "왜" 변경했는지에 초점. 72~75자에서 줄 바꿈
- 태그: 본문 뒤 빈 줄 없이 연속 배치
# Fixes 태그 생성 도우미
$ git log --oneline --abbrev=12 -1 a1b2c3d4e5f6
# 출력: a1b2c3d4e5f6 subsystem: commit that introduced the bug
# Fixes 태그 형식
Fixes: a1b2c3d4e5f6 ("subsystem: commit that introduced the bug")
패치 생성 (git format-patch)
단일 패치
# 마지막 커밋을 패치 파일로 변환
$ git format-patch -1
# 출력: 0001-subsystem-brief-summary.patch
# 특정 커밋 지정
$ git format-patch -1 abc123
# base-commit 정보 포함 (권장)
$ git format-patch -1 --base=auto
패치 시리즈
# master 이후의 모든 커밋을 패치 시리즈로 생성
$ git format-patch origin/master --base=auto
# 출력 디렉토리 지정
$ git format-patch origin/master -o patches/
# 특정 범위
$ git format-patch v6.8..HEAD
패치 시리즈의 각 패치는 독립적으로 컴파일 가능해야 하며, bisect-safe해야 합니다. 즉, 시리즈 중간의 어떤 커밋에서도 빌드 오류나 런타임 오류가 발생하면 안 됩니다.
커버 레터
# 커버 레터 포함 시리즈 생성
$ git format-patch origin/master --cover-letter --base=auto
# 0000-cover-letter.patch 파일이 생성됨
# 편집하여 시리즈 전체 설명 작성:
# - 전체 변경의 목적과 동기
# - 각 패치의 역할 요약
# - 테스트 환경/결과
# - 이전 버전과의 차이 (v2+인 경우)
2개 이상의 패치로 구성된 시리즈에는 커버 레터가 사실상 필수입니다. 메인테이너와 리뷰어가 전체 맥락을 이해하는 데 핵심 역할을 합니다.
버전 관리 (v2, v3)
# v2 패치 시리즈 생성
$ git format-patch origin/master -v 2 --cover-letter --base=auto
# 출력: v2-0000-cover-letter.patch, v2-0001-..., v2-0002-...
리뷰 피드백을 반영한 수정 버전을 보낼 때 버전 번호를 올립니다. 커버 레터에 이전 버전 대비 변경 사항(changelog)을 명시합니다:
# 커버 레터 하단에 추가
Changes since v1:
- Fixed memory leak reported by reviewer (patch 2/3)
- Added missing NULL check (patch 1/3)
- Rebased onto latest net-next
패치 전송 (git send-email)
SMTP 설정
# ~/.gitconfig SMTP 설정 예시 (Gmail)
[sendemail]
smtpserver = smtp.gmail.com
smtpserverport = 587
smtpencryption = tls
smtpuser = your.email@gmail.com
confirm = auto
suppresscc = self
# 앱 비밀번호 사용 (Gmail 2FA 사용 시)
# Google 계정 → 보안 → 앱 비밀번호에서 생성
git send-email을 사용하세요.
메인테이너 찾기 (get_maintainer.pl)
# 패치 파일로 메인테이너 검색
$ ./scripts/get_maintainer.pl 0001-mm-fix-memory-leak.patch
Andrew Morton <akpm@linux-foundation.org> (maintainer:MEMORY MANAGEMENT)
linux-mm@kvack.org (open list:MEMORY MANAGEMENT)
linux-kernel@vger.kernel.org (open list)
# 소스 파일로 메인테이너 검색
$ ./scripts/get_maintainer.pl -f mm/page_alloc.c
# 패치 시리즈 전체로 검색
$ ./scripts/get_maintainer.pl patches/*.patch
전송 명령
# 먼저 자신에게 테스트 전송
$ git send-email --to=yourself@example.com 0001-*.patch
# 단일 패치 전송
$ git send-email \
--to=maintainer@kernel.org \
--cc=linux-subsystem@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
0001-subsystem-fix-something.patch
# 패치 시리즈 전송 (커버 레터 포함)
$ git send-email \
--to=maintainer@kernel.org \
--cc=linux-subsystem@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cover-letter \
patches/
# get_maintainer.pl 출력을 직접 활용
$ git send-email \
$(./scripts/get_maintainer.pl --separator=, --nogit --nogit-fallback \
--norolestats 0001-*.patch | \
sed 's/^/--cc=/') \
0001-*.patch
메일링 리스트 에티켓
- 인라인 응답 — 리뷰 코멘트에 대해 해당 줄 아래에 응답합니다 (탑 포스팅 금지).
- 72자 줄바꿈 — 이메일 본문도 72자에서 줄바꿈합니다.
- 스레드 헤더 유지 — 전체 스레드가 연결되도록
In-Reply-To/References헤더를 올바르게 유지합니다. - 핑(ping) 타이밍 — 1~2주 후 응답이 없으면 정중히 핑합니다. 머지 윈도우 기간에는 더 기다립니다.
- v2 전송 — 수정본은 새 버전 시리즈로 전송하고, 커버 레터에 이전 버전 링크를 포함해 비교가 가능하도록 합니다.
MAINTAINERS 파일
커널 소스 루트의 MAINTAINERS 파일은 각 서브시스템의 메인테이너, 리뷰어, 메일링 리스트, 소스 파일 경로를 정의합니다.
get_maintainer.pl이 이 파일을 파싱하여 결과를 제공합니다.
파일 구조
# MAINTAINERS 파일 엔트리 형식
MEMORY MANAGEMENT
M: Andrew Morton <akpm@linux-foundation.org>
R: David Hildenbrand <david@redhat.com>
L: linux-mm@kvack.org
S: Maintained
W: http://www.linux-mm.org
T: git git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm
F: include/linux/mm.h
F: include/linux/gfp.h
F: mm/
X: mm/kasan/
| 필드 | 의미 |
|---|---|
M: | 메인테이너 (패치 적용 권한) |
R: | 지정 리뷰어 |
L: | 메일링 리스트 |
S: | 유지보수 상태 |
W: | 웹 페이지 |
T: | SCM 트리 (git URL) |
F: | 관련 파일/디렉토리 패턴 |
X: | 제외 파일 패턴 |
N: | 파일명 정규식 |
K: | 콘텐츠 정규식 (소스 코드 키워드) |
유지보수 상태 (S: 필드)
| 상태값 | 의미 |
|---|---|
Supported | 활발히 유지보수, 버그 수정/기능 추가 모두 수용 |
Maintained | 메인테이너가 관리 중, 패치 수용 |
Odd Fixes | 간헐적 수정만 수용 |
Orphan | 메인테이너 없음, 패치는 LKML로 |
Obsolete | 더 이상 사용되지 않는 코드 |
서브시스템 계층 구조
대형 서브시스템은 여러 단계의 메인테이너 계층을 가집니다.
예를 들어 네트워킹은 netdev 메인테이너 아래에 각 프로토콜/드라이버별 메인테이너가 있습니다.
패치는 가장 구체적인(하위) 메인테이너에게 먼저 보내고, 상위 메인테이너와 메일링 리스트를 CC합니다.
리뷰 프로세스
리뷰 응답
리뷰어가 패치에 대해 코멘트를 달면, 인라인 형식으로 응답합니다:
# 리뷰어의 코멘트에 대한 응답 예시
> On Wed, Jan 15, 2025 at 10:30 AM, Reviewer wrote:
> > + data = kmalloc(sizeof(*data), GFP_KERNEL);
> > + if (!data)
> > + return -ENOMEM;
>
> Should this use devm_kzalloc() instead? This is a device driver
> and the memory should be tied to the device lifecycle.
Good point. Changed to devm_kzalloc() in v2. Also switched to
kzalloc variant to zero-initialize the struct.
> > + ret = configure_device(data);
>
> nit: Missing error handling for configure_device() return value.
Fixed. Added proper error path with devm_kfree() in v2.
리뷰 태그 수집
리뷰어가 Reviewed-by:, Acked-by:, Tested-by:를 메일로 보내면,
다음 버전의 커밋 메시지에 해당 태그를 추가합니다. 변경되지 않은 패치에 대한 태그만 유지하고,
내용이 크게 변경된 패치의 태그는 제거합니다.
패치 재전송 (Respin)
리뷰 피드백을 반영한 후 새 버전을 보내는 절차:
- 피드백을 코드에 반영하고 커밋을 갱신합니다 (
git rebase -i로 기존 커밋 수정). git format-patch -v N으로 새 버전 패치를 생성합니다.- 커버 레터에 변경 이력(changelog)을 추가합니다.
- 이전 버전의 리뷰 태그를 적절히 반영합니다.
- 새 스레드로 전송합니다 (이전 버전에 reply하지 않음).
# 개별 패치의 changelog (--- 아래, diffstat 위에 작성)
---
Changes since v1:
- Use devm_kzalloc() instead of kmalloc() (Reviewer's suggestion)
- Add error handling for configure_device()
drivers/example/example.c | 15 +++++++++------
1 file changed, 9 insertions(+), 6 deletions(-)
--- 아래 텍스트: 패치의 --- 구분선과 diffstat 사이에 작성한 텍스트는
git am으로 적용할 때 자동으로 제거됩니다. 따라서 changelog나 임시 메모를 여기에 작성합니다.
머지 과정
커널 패치가 메인라인에 도달하기까지의 경로를 이해하면, 전체 개발 사이클에서 자신의 패치가 어느 단계에 있는지 파악할 수 있습니다.
서브시스템 트리
각 서브시스템 메인테이너는 자신만의 Git 트리를 관리합니다. 리뷰를 통과한 패치는 해당 서브시스템 트리에 먼저 적용됩니다.
| 서브시스템 | 트리 | 메인테이너 |
|---|---|---|
| 메모리 관리 | mm (Andrew Morton) |
Andrew Morton |
| 네트워킹 | net-next / net |
Jakub Kicinski 등 |
| 블록 I/O | block |
Jens Axboe |
| 파일시스템 (VFS) | vfs |
Christian Brauner |
| 스케줄러 | tip (sched/core) |
Ingo Molnar 등 |
| 드라이버 코어 | driver-core |
Greg KH |
linux-next 통합 테스트
linux-next는 Stephen Rothwell이 관리하는 통합 테스트 트리입니다.
모든 서브시스템 트리의 다음 머지 윈도우 예정 패치를 매일 병합하여 충돌과 빌드 문제를 사전에 발견합니다.
- 매일 리빌드: 약 300개 이상의 서브시스템 트리를 병합합니다.
- 충돌 보고: 충돌 발생 시 관련 메인테이너에게 통보됩니다.
- 0-day bot: Intel의 자동화 봇이 빌드/테스트 결과를 메일링 리스트에 보고합니다.
머지 윈도우와 RC 릴리즈
리눅스 커널은 약 9~10주 주기로 새 버전을 릴리즈합니다. 이 중 첫 2주가 머지 윈도우(Merge Window)로, 이 기간에만 새로운 기능이 Linus 트리에 병합됩니다.
- 머지 윈도우 (~2주): 서브시스템 메인테이너가 Linus에게 pull request를 보내 새 기능을 병합합니다.
- rc1: 머지 윈도우 종료. 이후 새 기능은 받지 않으며, 버그 수정과 회귀(regression) 수정만 허용됩니다.
- rc2~rc7: 매주 릴리즈 캔디데이트(RC)가 나옵니다. 점차 안정화됩니다.
- Release: 충분히 안정되면 최종 릴리즈됩니다. 이후 즉시 다음 머지 윈도우가 열립니다.
도구와 리소스
b4 도구
b4는 커널 패치 워크플로를 자동화하는 도구입니다. 패치 시리즈 다운로드, 적용, 제출을 간소화합니다.
# 설치
$ pip install b4
# 메일링 리스트에서 패치 시리즈 다운로드
$ b4 am <message-id>
# 패치 시리즈를 mbox로 저장
$ b4 am -o patches.mbx <message-id>
# 패치 제출 워크플로 (send-email 대체)
$ b4 prep --auto-to-cc # get_maintainer.pl 자동 실행
$ b4 send # 패치 전송
# 리뷰 태그 자동 수집
$ b4 trailers -u # 커밋에 태그 자동 추가
lore.kernel.org
lore.kernel.org는 커널 메일링 리스트의 공식 아카이브입니다.
모든 패치와 논의가 영구 보존되며, Message-ID로 직접 접근할 수 있습니다.
- 검색:
lore.kernel.org/all/?q=keyword로 전체 아카이브 검색 - 리스트별:
lore.kernel.org/linux-mm/,lore.kernel.org/netdev/등 - 패치 링크: 커버 레터나 v2 패치에서 이전 버전 URL을 제공할 때 사용
Patchwork
Patchwork는 패치의 상태를 추적하는 웹 시스템입니다. 메인테이너가 패치를 적용(Accepted), 거절(Rejected), 보류(Deferred) 상태로 관리합니다.
- patchwork.kernel.org: 주요 서브시스템의 패치 상태 확인
- pwclient: 명령줄에서 패치 다운로드/적용
Bugzilla & 회귀 추적
- bugzilla.kernel.org: 커널 버그 보고 시스템
- regzbot: 커널 회귀(regression)를 추적하는 봇.
Closes:태그로 연결 - syzbot: Google의 자동 퍼징 봇. 발견된 버그에 대한 재현 프로그램과 보고서 제공
Stable 백포트
중요한 버그 수정이나 보안 패치는 메인라인에 적용된 후 stable 커널(LTS 포함)에도 백포트됩니다. Greg Kroah-Hartman과 Sasha Levin이 stable 트리를 관리합니다.
# 방법 1: 커밋 메시지에 태그 추가 (가장 간단)
Cc: stable@vger.kernel.org
# 방법 2: 특정 버전 이후에만 백포트
Cc: stable@vger.kernel.org # v5.15+
# 방법 3: Fixes 태그가 있으면 자동으로 stable 후보
# AUTOSEL 프로세스가 Fixes 태그를 분석하여 자동 선별
Stable 백포트 규칙:
- 반드시 메인라인에 먼저 적용된 패치여야 합니다.
- 가능한 한 작고, 리스크가 낮은 명확한 버그 수정이어야 합니다.
- 새 기능이나 아키텍처 변경은 백포트되지 않습니다.
- 테스트를 거친 패치여야 합니다.
완전한 실습 예제
드라이버의 메모리 누수를 수정하는 패치를 제출하는 전체 과정입니다:
## 1단계: 저장소 준비
$ git clone https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
$ cd linux
$ git config user.name "Kim Developer"
$ git config user.email "kim@example.com"
## 2단계: 토픽 브랜치 생성
$ git checkout -b fix/memleak-example-driver origin/master
## 3단계: 코드 수정
$ vim drivers/example/core.c
# ... 메모리 누수 수정 ...
## 4단계: checkpatch 실행
$ git diff | ./scripts/checkpatch.pl -
total: 0 errors, 0 warnings, 12 lines checked
## 5단계: 커밋
$ git add drivers/example/core.c
$ git commit -s
# 편집기에서 커밋 메시지 작성:
# example: fix memory leak in probe error path
#
# When example_configure() fails, the allocated data structure
# is not freed, leading to a memory leak on every failed probe
# attempt.
#
# Add the missing kfree() call in the error path.
#
# Fixes: a1b2c3d4e5f6 ("example: add new driver")
# Cc: stable@vger.kernel.org
# Signed-off-by: Kim Developer <kim@example.com>
## 6단계: 패치 생성
$ git format-patch -1 --base=auto
# 출력: 0001-example-fix-memory-leak-in-probe-error-path.patch
## 7단계: 최종 checkpatch 확인
$ ./scripts/checkpatch.pl 0001-example-fix-memory-leak-in-probe-error-path.patch
## 8단계: 메인테이너 찾기
$ ./scripts/get_maintainer.pl 0001-example-fix-memory-leak-in-probe-error-path.patch
## 9단계: 테스트 전송 (자신에게)
$ git send-email --to=kim@example.com \
0001-example-fix-memory-leak-in-probe-error-path.patch
## 10단계: 실제 전송
$ git send-email \
--to=maintainer@kernel.org \
--cc=linux-example@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=stable@vger.kernel.org \
0001-example-fix-memory-leak-in-probe-error-path.patch
패치 제출 체크리스트
패치를 전송하기 전 다음 항목을 확인하세요:
| 단계 | 확인 항목 | 명령/도구 |
|---|---|---|
| 코딩 스타일 | checkpatch.pl ERROR 0개 | ./scripts/checkpatch.pl *.patch |
| 빌드 확인 | allmodconfig 빌드 성공 | make allmodconfig && make -j$(nproc) |
| 빌드 경고 | W=1 빌드 시 새 경고 없음 | make W=1 |
| sparse 검사 | 정적 분석 통과 | make C=1 |
| 커밋 메시지 | 서브시스템 접두사, 명령형, 72자 줄바꿈 | git log --oneline |
| Signed-off-by | 모든 커밋에 포함 | git log --format=%B |
| Fixes 태그 | 버그 수정 시 원인 커밋 참조 | git log --oneline --abbrev=12 |
| bisect-safe | 시리즈 중간 커밋에서도 빌드/동작 정상 | git rebase -x 'make -j$(nproc)' origin/master |
| 수신자 | 메인테이너, 리뷰어, 메일링 리스트 지정 | ./scripts/get_maintainer.pl |
| 테스트 전송 | 자신에게 먼저 보내서 형식 확인 | git send-email --to=self@ |
| base-commit | 패치 베이스 정보 포함 | git format-patch --base=auto |
자세한 내용은 커널 소스의 Documentation/process/submitting-patches.rst와
Documentation/process/coding-style.rst를 참조하세요.
패치 반려 패턴과 대응 전략
패치가 반려되는 이유는 대부분 코드 품질 자체보다 "제출 품질" 문제인 경우가 많습니다. 아래 패턴을 먼저 점검하면 v2/v3 반복 횟수를 줄일 수 있습니다.
| 반려 패턴 | 대표 코멘트 | 대응 |
|---|---|---|
| 커밋 범위가 큼 | "Please split this patch" | 기능/리팩터링/정리 커밋을 분리해 시리즈 재구성 |
| 커밋 메시지 부족 | "Why is this needed?" | 문제 재현 조건, 원인, 수정 의도, 영향 범위를 본문에 명시 |
| 수신자 누락 | "Cc missing maintainers" | get_maintainer.pl 재실행 후 리스트 확장 |
| 테스트 근거 부족 | "How did you test this?" | 빌드/런타임/회귀 테스트 항목을 커버레터에 명시 |
| 스타일/경고 문제 | "checkpatch warnings" | checkpatch.pl, W=1, C=1 재검증 |
v2 재전송 템플릿
[PATCH v2 0/N] subsystem: short summary
v2 changes:
- fix build warning in foo.c
- split patch 2 into two logical commits
- add Reviewed-by from Alice
- add test result on arm64 + x86_64
base-commit: abcdef1234567890
재전송 시에는 항상 이전 스레드에 답장 형태(--in-reply-to)로 보내고, 무엇이 어떻게 바뀌었는지 상단 변경 이력(v2 changes)을 명확히 적으세요.
관련 문서
커널 패치 제출과 관련된 다른 주제를 더 깊이 이해하고 싶다면 다음 문서를 참고하세요.