커널 패치(Patch) 제출 (Kernel Patch Submission)

커널 소스 코드 변경 사항을 커뮤니티에 제출하는 전체 과정을 다룹니다. 코딩 스타일(Coding Style) 준수부터 git format-patch, git send-email, 리뷰 대응, 머지 과정까지 실무에 필요한 모든 단계를 설명합니다.

관련 표준: Linux Kernel Coding Style, SubmittingPatches (kernel.org) — 커널 패치 제출 공식 가이드라인입니다. 종합 목록은 참고자료 — 표준 & 규격 섹션을 참고하세요.
전제 조건: 커널 아키텍처빌드 시스템(Build System) 문서를 먼저 읽으세요. 입문 문서는 개발 환경, 코드 위치, 변경 절차를 연결해 보는 것이 핵심이므로 기본 작업 흐름을 먼저 고정해야 합니다.
일상 비유: 이 주제는 현장 작업 시작 전 안전 교육과 비슷합니다. 도구 사용법과 작업 순서를 먼저 익혀야 실수를 줄일 수 있듯이, 커널 개발도 기본 루틴을 먼저 갖추는 것이 중요합니다.

핵심 요약

  • git format-patch — 커밋을 이메일 형식의 패치 파일(.patch)로 변환하는 명령입니다.
  • git send-email — 생성된 패치를 SMTP로 메일링 리스트에 전송합니다.
  • checkpatch.pl — 커널 코딩 스타일 준수 여부를 자동으로 검사하는 스크립트입니다.
  • get_maintainer.pl — 패치를 보낼 메인테이너와 메일링 리스트를 찾아주는 스크립트입니다.
  • Signed-off-by — 개발자가 DCO(Developer Certificate of Origin)에 동의함을 나타내는 필수 태그입니다.

단계별 이해

  1. 코드 작성 — 커널 코딩 스타일(K&R, 탭 8칸, 80열)을 준수하며 버그 수정이나 기능 개선 코드를 작성합니다.

    checkpatch.pl로 스타일을 검증합니다.

  2. 커밋 생성 — 변경 사항을 논리적 단위로 분리하여 커밋합니다. 커밋 메시지에 Signed-off-by 태그를 포함합니다.

    git commit -s로 자동 추가할 수 있습니다.

  3. 패치 생성 및 전송git format-patch로 패치 파일을 만들고, get_maintainer.pl로 수신자를 찾은 뒤 git send-email로 전송합니다.

    전송 전 자신에게 먼저 보내서 형식을 확인하는 것이 좋습니다.

  4. 리뷰 대응 — 메일링 리스트의 피드백에 인라인으로 응답하고, 필요 시 수정 버전(v2, v3...)을 재전송(Retransmission)합니다.

    리뷰어의 Reviewed-by, Acked-by 태그를 수집합니다.

커뮤니티 문화와 기본 원칙

리눅스 커널은 세계 최대의 협업 소프트웨어 프로젝트입니다. 수천 명의 개발자가 이메일 기반 워크플로로 협업하며, 명확한 규칙과 에티켓이 원활한 협업의 기반이 됩니다.

오픈소스 에티켓

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>

패치 파일 구조 (Anatomy)

git format-patch가 생성하는 .patch 파일은 RFC 2822 이메일 형식을 따릅니다. 각 영역의 역할을 이해하면 커밋 메시지 작성, 리뷰 대응, 디버깅(Debugging) 시 혼란을 줄일 수 있습니다.

Email Header From: Author <email> Subject: [PATCH v2 1/3] subsystem: summary Date: ... Message-Id: <...> git send-email이 이 영역을 전송 Commit Message Body Detailed explanation of the change... (why, not what) Fixes: abc123 ("original commit") Signed-off-by: Author <email> git am 적용 시 커밋 메시지가 됨 --- 구분선 (삭제됨) Changelog + Diffstat Changes since v1: ... file.c | 5 ++--- git am이 자동 제거 (커밋에 포함 안 됨) Diff (실제 변경 내용) diff --git a/file.c b/file.c --- a/file.c +++ b/file.c @@ -10,6 +10,8 @@ ... 실제 코드 변경 base-commit: <SHA> --base=auto 추가
패치 파일 구조 — 이메일 헤더, 커밋 메시지, --- 구분선, changelog/diffstat, diff, base-commit

--- 구분선은 핵심 경계입니다. 구분선 의 텍스트(커밋 메시지)는 git am 적용 시 그대로 커밋 로그에 남고, 구분선 아래의 텍스트(changelog, diffstat)는 자동으로 제거됩니다. 따라서 버전별 변경 이력이나 임시 메모는 --- 아래에 작성합니다.

# 패치 파일 내용 확인
$ cat 0001-example-fix-memleak.patch

From a1b2c3d4e5f6 Mon Sep 17 00:00:00 2001
From: Kim Developer <kim@example.com>
Date: Mon, 20 Jan 2025 14:30:00 +0900
Subject: [PATCH] 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>
---
 drivers/example/core.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/example/core.c b/drivers/example/core.c
...

코딩 스타일

스타일 개요 (K&R, 탭 8칸, 80열)

커널 코딩 스타일은 Documentation/process/coding-style.rst에 정의되어 있습니다. 핵심 규칙은 다음과 같습니다:

/* 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 에러 처리: 커널에서 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을 기준으로 합니다. 잘못된 베이스는 충돌을 야기하고 리뷰를 지연(Latency)시킵니다.

커밋 메시지 규약

커밋 메시지는 정해진 형식을 따라야 합니다:

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>

커밋 메시지 작성 규칙:

# Fixes 태그 생성 도우미
$ git log --oneline --abbrev=12 -1 a1b2c3d4e5f6
# 출력: a1b2c3d4e5f6 subsystem: commit that introduced the bug

# Fixes 태그 형식
Fixes: a1b2c3d4e5f6 ("subsystem: commit that introduced the bug")

커밋 메시지 흔한 실수

커밋 메시지 품질은 패치 수락 여부에 직접적으로 영향을 미칩니다. 아래는 초보 기여자가 자주 범하는 실수와 올바른 예시입니다.

실수 유형 잘못된 예 올바른 예
서브시스템 접두사 누락 Fix memory leak mm/page_alloc: fix memory leak in alloc_pages_bulk
과거형 사용 mm: Fixed null pointer mm: fix null pointer dereference in do_mmap
마침표 사용 net: add TCP fast open support. net: add TCP fast open support
대문자로 시작 Ext4: Add new ioctl ext4: add new ioctl for extent status
"what" 중심 본문 Added kfree() call after kmalloc() When probe fails, the allocated struct is leaked. Add kfree() in error path.
제목 줄 초과 (>75자) drivers/net/ethernet/intel/igb: fix a very long descriptive title ... igb: fix Tx timestamp timeout on 82576
서브시스템 접두사 찾기: 해당 파일의 최근 커밋을 보면 어떤 접두사를 사용하는지 알 수 있습니다. git log --oneline -20 <file>로 확인하세요.
# 서브시스템 접두사 관례 확인
$ git log --oneline -10 mm/page_alloc.c
# mm/page_alloc: ..., mm: ..., mm/compaction: ... 등 패턴 확인

# 제목 줄 길이 검사 (75자 초과 여부)
$ git log --format='%s' -1 | wc -c
# 75 이하여야 함

패치 생성 (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
--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 계정 → 보안 → 앱 비밀번호에서 생성
중요: 일반 이메일 클라이언트(Thunderbird, Gmail 웹 등)로 패치를 보내면 공백, 줄바꿈, 인코딩이 변경될 수 있습니다. 반드시 git send-email을 사용하세요.

이메일 클라이언트 설정 상세

리뷰 응답이나 일반 토론에는 git send-email 대신 이메일 클라이언트를 사용할 수 있습니다. 단, 패치가 손상되지 않도록 반드시 아래 설정을 확인해야 합니다.

클라이언트 필수 설정 비고
Thunderbird 편집 > 환경 설정 > 고급 > 일반 > 설정 편집 > mailnews.wraplength = 0, HTML 메일 비활성화 External Editor 확장 권장
mutt / neomutt set edit_headers=yes, set text_flowed=no 커널 개발자들이 가장 많이 사용
Gmail 웹 일반 텍스트 모드로 전환, 자동 줄바꿈 주의 패치 전송에는 부적합 (리뷰 응답만 사용)
Claws Mail HTML 비활성화, 서명 구분자 -- 유지 안정적인 플레인 텍스트 지원
# mutt 기본 설정 (~/.muttrc)
set from = "Your Name <your@email.com>"
set realname = "Your Name"
set edit_headers = yes
set text_flowed = no
set charset = "utf-8"
set send_charset = "us-ascii:utf-8"

# LKML 구독 (IMAP 설정)
set folder = "imaps://imap.gmail.com:993"
set spoolfile = "+INBOX"
플레인 텍스트 확인: 이메일을 보낸 뒤 lore.kernel.org에서 자신의 메일을 확인하면 공백 변환, 줄바꿈 오류, 인코딩 문제를 즉시 발견할 수 있습니다.

메인테이너 찾기 (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

메일링 리스트 에티켓

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:웹 페이지(Page)
T:SCM 트리 (git URL)
F:관련 파일/디렉토리 패턴
X:제외 파일 패턴
N:파일명 정규식
K:콘텐츠 정규식 (소스 코드 키워드)

유지보수 상태 (S: 필드)

상태값 의미
Supported활발히 유지보수, 버그 수정/기능 추가 모두 수용
Maintained메인테이너가 관리 중, 패치 수용
Odd Fixes간헐적 수정만 수용
Orphan메인테이너 없음, 패치는 LKML로
Obsolete더 이상 사용되지 않는 코드

서브시스템 계층 구조

대형 서브시스템은 여러 단계의 메인테이너 계층을 가집니다. 예를 들어 네트워킹은 netdev 메인테이너 아래에 각 프로토콜/드라이버별 메인테이너가 있습니다. 패치는 가장 구체적인(하위) 메인테이너에게 먼저 보내고, 상위 메인테이너와 메일링 리스트를 CC합니다.

리뷰 프로세스(Process)

리뷰 응답

리뷰어가 패치에 대해 코멘트를 달면, 인라인 형식으로 응답합니다:

# 리뷰어의 코멘트에 대한 응답 예시
> 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)

리뷰 피드백을 반영한 후 새 버전을 보내는 절차:

  1. 피드백을 코드에 반영하고 커밋을 갱신합니다 (git rebase -i로 기존 커밋 수정).
  2. git format-patch -v N으로 새 버전 패치를 생성합니다.
  3. 커버 레터에 변경 이력(changelog)을 추가합니다.
  4. 이전 버전의 리뷰 태그를 적절히 반영합니다.
  5. 새 스레드로 전송합니다 (이전 버전에 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나 임시 메모를 여기에 작성합니다.

머지 과정

커널 패치가 메인라인에 도달하기까지의 경로를 이해하면, 전체 개발 사이클에서 자신의 패치가 어느 단계에 있는지 파악할 수 있습니다.

Developer (패치 작성) Mailing List (리뷰 & 피드백) Subsystem Tree (메인테이너 적용) linux-next (통합 테스트) Linus Tree (메인라인) 피드백 반영 (v2, v3...) git send-email git am git pull git merge
패치 제출 워크플로 — Developer에서 Linus 메인라인 트리까지의 경로

서브시스템 트리

각 서브시스템 메인테이너는 자신만의 Git 트리를 관리합니다. 리뷰를 통과한 패치는 해당 서브시스템 트리에 먼저 적용됩니다.

서브시스템 트리 메인테이너
메모리 관리(Memory Management) mm (Andrew Morton) Andrew Morton
네트워킹 net-next / net Jakub Kicinski 등
블록 I/O block Jens Axboe
파일시스템 (VFS) vfs Christian Brauner
스케줄러(Scheduler) tip (sched/core) Ingo Molnar 등
드라이버 코어 driver-core Greg KH

linux-next 통합 테스트

linux-next는 Stephen Rothwell이 관리하는 통합 테스트 트리입니다. 모든 서브시스템 트리의 다음 머지 윈도우 예정 패치를 매일 병합하여 충돌과 빌드 문제를 사전에 발견합니다.

머지 윈도우와 RC 릴리즈

리눅스 커널은 약 9~10주 주기로 새 버전을 릴리즈합니다. 이 중 첫 2주가 머지 윈도우(Merge Window)로, 이 기간에만 새로운 기능이 Linus 트리에 병합됩니다.

Merge Window ~2주 rc1 rc2 rc3 rc4 rc5 rc6 rc7 Release v6.x RC 기간: 버그 수정만 허용 (~7주) Next MW
커널 릴리즈 타임라인 — 머지 윈도우(~2주) + RC 기간(~7주) = 약 9~10주 사이클
타이밍: 새 기능 패치는 머지 윈도우가 열리기 에 서브시스템 트리에 적용되어 linux-next에서 테스트를 거쳐야 합니다. 머지 윈도우 직전에 보내면 다음 사이클로 밀릴 가능성이 높습니다.

도구와 리소스

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로 직접 접근할 수 있습니다.

Patchwork

Patchwork는 패치의 상태를 추적하는 웹 시스템입니다. 메인테이너가 패치를 적용(Accepted), 거절(Rejected), 보류(Deferred) 상태로 관리합니다.

Bugzilla & 회귀 추적

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 백포트 규칙:

패치 적용과 테스트

자신의 패치를 제출하기 전에 깨끗한 트리에 적용하여 테스트하거나, 다른 개발자의 패치를 검토하기 위해 적용하는 방법입니다.

git am으로 패치 적용

# 단일 패치 적용
$ git am 0001-subsystem-fix-something.patch

# 패치 시리즈 적용 (순서대로)
$ git am patches/*.patch

# mbox 파일에서 적용
$ git am patches.mbx

# 3-way merge 모드 (충돌 해결이 더 쉬움)
$ git am -3 0001-*.patch

# 적용 실패 시 중단
$ git am --abort

# 충돌 해결 후 계속 진행
$ git am --continue

셀프 테스트 절차

패치 제출 전 다음 테스트를 실행합니다:

# 1. 깨끗한 브랜치에서 패치 적용 테스트
$ git checkout -b test-apply origin/master
$ git am 0001-*.patch

# 2. 전체 빌드 (해당 아키텍처)
$ make defconfig
$ make -j$(nproc)

# 3. allmodconfig 빌드 (최대 커버리지)
$ make allmodconfig
$ make -j$(nproc)

# 4. 크로스 컴파일 (ARM64)
$ make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- defconfig
$ make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- -j$(nproc)

# 5. sparse 정적 분석
$ make C=1 drivers/example/

# 6. coccinelle 의미적 패치 검사
$ make coccicheck MODE=patch COCCI=scripts/coccinelle/api/kfree.cocci \
    M=drivers/example/

# 7. 런타임 테스트 (QEMU)
$ qemu-system-x86_64 -kernel arch/x86/boot/bzImage \
    -initrd rootfs.cpio -append "console=ttyS0" -nographic
bisect-safe 확인: 패치 시리즈의 모든 중간 커밋에서 빌드가 성공해야 합니다. git rebase -x 'make -j$(nproc)' origin/master로 각 커밋별 빌드를 자동 검증할 수 있습니다.

b4로 다른 개발자의 패치 가져오기

# lore.kernel.org에서 Message-ID로 패치 시리즈 다운로드
$ b4 am 20250115103000.12345-1-dev@example.com

# 자동으로 최신 버전(v2, v3...)을 선택하여 mbox 생성
# 출력: 20250115103000.12345-1-dev@example.com.mbx

# 바로 적용
$ git am 20250115103000.12345-1-dev@example.com.mbx

# 특정 버전만 가져오기
$ b4 am -v 2 <message-id>

커널 CI와 자동화 테스트

패치를 제출하면 여러 자동화 시스템이 빌드 및 테스트를 수행하고 결과를 메일링 리스트에 보고합니다. 이 시스템들의 동작을 이해하면 보고된 문제를 빠르게 대응할 수 있습니다.

시스템 운영 주체 테스트 범위 보고 방식
0-day (kernel test robot) Intel 200+ config/arch 빌드, sparse, smatch, coccinelle 이메일 (lkp@intel.com)
syzbot Google 퍼징 기반 런타임 버그 탐지 (KASAN, KCSAN, KMSAN) 이메일 + syzkaller.appspot.com
KernelCI Linux Foundation 실제 하드웨어 기반 부팅/기능 테스트 kernelci.org 대시보드
CKI (CentOS Kernel CI) Red Hat RHEL 커널 기반 기능/회귀 테스트 이메일
patchew 각 서브시스템 패치 적용 가능성, 빌드 상태 patchew.org

CI 보고서 대응

자동화 봇이 문제를 보고하면 다음과 같이 대응합니다:

# 0-day bot 빌드 실패 예시 메일
# Subject: [PATCH] mm: fix ... (build error)
# From: kernel test robot <lkp@intel.com>
#
# >> drivers/example/core.c:42:5: error: implicit declaration of ...

# 1. 보고된 config로 재현
$ wget "https://download.01.org/.../.config" -O .config
$ make olddefconfig
$ make -j$(nproc)

# 2. 문제 수정 후 v2 재전송
# 커버 레터에 "Reported-by: kernel test robot <lkp@intel.com>" 추가
syzbot 재현: syzbot이 보고한 버그는 대부분 C 재현 프로그램을 제공합니다. syzkaller.appspot.com에서 해당 링크를 찾아 QEMU 환경에서 재현할 수 있습니다. 재현 성공 후 수정하면 Reported-by: syzbot+<hash>@syzkaller.appspotmail.com 태그를 포함합니다.
Patch send-email LKML 아카이브 0-day Bot 200+ config 빌드 sparse, smatch syzbot 퍼징 테스트 KASAN, KCSAN KernelCI 실 HW 부팅 테스트 기능 테스트 결과 메일/대시보드 PASS / FAIL 보고 Reported-by 태그 포함 + Human Review
패치 제출 후 자동화 CI 파이프라인(Pipeline) — 0-day, syzbot, KernelCI가 병렬로 테스트 수행

첫 번째 패치 제출 가이드

커널에 처음 기여하는 개발자를 위한 단계별 안내입니다. 첫 패치로는 리스크가 낮은 작업을 선택하는 것이 좋습니다.

좋은 첫 패치 유형

유형 설명 난이도 찾는 방법
오탈자/문법 수정 커널 문서 또는 주석의 오류 낮음 Documentation/ 디렉토리 검토
checkpatch 경고 수정 기존 코드의 코딩 스타일 위반 낮음 checkpatch.pl --file 실행
deprecated API 교체 오래된 API를 새 API로 변환 중간 coccinelle 규칙, TODO 파일
컴파일러 경고 수정 W=1 빌드 시 나오는 경고 중간 make W=1 빌드
syzbot 버그 수정 자동 퍼저가 발견한 버그 (재현 가능) 중~높음 syzkaller.appspot.com/upstream

staging 드라이버로 시작하기

drivers/staging/ 디렉토리는 아직 메인라인 품질을 충족하지 못하는 드라이버를 모아둔 곳입니다. Greg Kroah-Hartman이 메인테이너이며, 초보자의 코딩 스타일 정리 패치를 적극적으로 수용합니다.

# staging 드라이버에서 checkpatch 경고 찾기
$ ./scripts/checkpatch.pl --file --terse drivers/staging/rtl8723bs/core/*.c

# 출력 예시:
# drivers/staging/rtl8723bs/core/rtw_cmd.c:42: WARNING: Prefer ...
# drivers/staging/rtl8723bs/core/rtw_cmd.c:88: CHECK: Alignment ...

# TODO 파일 확인
$ cat drivers/staging/rtl8723bs/TODO
# - fix all checkpatch warnings
# - use kernel coding style
# - replace custom debug macros with dev_dbg()
Outreachy / LFX Mentorship: Linux Foundation의 인턴십 프로그램을 통해 멘토와 함께 첫 기여를 시작할 수도 있습니다. 개발 환경 설정 문서에서 기본 환경을 먼저 구축하세요.

첫 패치 전 확인 사항

  1. 개발 환경 준비개발 환경 설정 문서 참고. git send-email이 동작하는지 확인합니다.
  2. 커널 빌드 성공빌드 시스템 문서 참고. 최소한 defconfig로 빌드 성공을 확인합니다.
  3. 코딩 스타일 학습코딩 스타일 문서와 Documentation/process/coding-style.rst를 읽습니다.
  4. 테스트 이메일 전송 — 자신에게 먼저 git send-email을 보내 형식을 확인합니다.
  5. LKML 구독/검색lore.kernel.org에서 유사한 패치를 검색하여 형식과 관례를 파악합니다.
/*
 * 첫 패치 예시: deprecated API 교체
 * strlcpy() → strscpy() 변환
 *
 * strlcpy()는 반환값의 의미가 혼동되어 커널에서 deprecated 되었습니다.
 * strscpy()는 실제 복사된 길이를 반환하며, 버퍼 오버플로에 안전합니다.
 */

/* 변경 전 */
strlcpy(info->driver, "example", sizeof(info->driver));

/* 변경 후 */
strscpy(info->driver, "example", sizeof(info->driver));

완전한 실습 예제

드라이버의 메모리 누수를 수정하는 패치를 제출하는 전체 과정입니다:

## 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.rstDocumentation/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)을 명확히 적으세요.

패치 개발 Git 고급 기법

커널 패치를 효율적으로 관리하기 위한 Git 고급 사용법입니다. 여러 패치 시리즈를 병행 개발하거나, 리베이스/수정을 반복할 때 유용합니다.

git worktree로 병렬 작업

git worktree는 하나의 저장소에서 여러 브랜치를 동시에 체크아웃할 수 있게 합니다. 빌드 중인 트리를 유지하면서 다른 브랜치에서 작업하거나, 리뷰를 위해 다른 개발자의 패치를 적용할 때 유용합니다.

# 새 worktree 생성 (별도 디렉토리)
$ git worktree add ../linux-fix-memleak fix/memory-leak
$ git worktree add ../linux-test-review origin/master

# worktree 목록 확인
$ git worktree list
/home/dev/linux               a1b2c3d [master]
/home/dev/linux-fix-memleak   d4e5f6a [fix/memory-leak]
/home/dev/linux-test-review   789abcd [master]

# 리뷰할 패치를 test worktree에서 적용
$ cd ../linux-test-review
$ b4 am <message-id>
$ git am *.mbx
$ make -j$(nproc)

# worktree 삭제
$ git worktree remove ../linux-test-review

interactive rebase로 패치 시리즈 정리

# 최근 5개 커밋을 정리 (squash, reorder, edit)
$ git rebase -i HEAD~5

# 리베이스 편집기에서:
# pick   abc123 net: refactor helper function
# squash def456 fixup: typo in previous commit     ← 이전 커밋에 합침
# pick   ghi789 net: add new feature
# edit   jkl012 net: update documentation          ← 커밋 메시지 수정
# pick   mno345 net: add test cases

# 서브시스템 트리 기준으로 리베이스 (최신 base 반영)
$ git fetch net-next
$ git rebase net-next/main

# 리베이스 중 bisect-safe 확인
$ git rebase -x 'make -j$(nproc) 2>&1 | tail -1' origin/master
Force push 주의: 커널 개발에서는 공유 브랜치에 force push하지 않습니다. 자신의 토픽 브랜치에서만 rebase를 사용하고, 메인라인/서브시스템 트리에는 절대 force push하지 않습니다. 리뷰 중인 패치를 수정할 때는 항상 새 버전(v2, v3)으로 재전송합니다.

git range-diff로 버전 간 비교

git range-diff는 패치 시리즈의 두 버전을 비교하여 무엇이 변경되었는지 보여줍니다. 리뷰어에게 변경 사항을 명확히 전달할 때 유용합니다.

# v1과 v2 시리즈 비교
$ git range-diff origin/master v1-base..v1-tip v2-base..v2-tip

# 태그를 사용한 비교
$ git tag fix-memleak-v1 HEAD~3   # v1 시리즈 끝
# ... 수정 후 ...
$ git range-diff origin/master fix-memleak-v1 HEAD

# format-patch에 range-diff 포함 (--range-diff 옵션)
$ git format-patch -v 2 --cover-letter \
    --range-diff=fix-memleak-v1 origin/master

참고자료

공식 문서

패치 도구

커뮤니티 리소스