Skip to main content
Getting a patch accepted into the Linux kernel requires following a well-established process. This guide covers the essentials drawn from Documentation/process/submitting-patches.rst.
The kernel development process happens entirely over email, on public mailing lists, using plain-text patches. There are no pull requests or web-based code review tools in the mainline workflow.

Obtain a current source tree

Start from the mainline repository or from the subsystem maintainer’s tree:
git clone git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
Most subsystem maintainers maintain their own trees and want patches prepared against those, not mainline. Check the MAINTAINERS file for the T: entry for your subsystem to find the right tree.

Describe your changes

Every patch needs a clear, well-written commit message. The message must stand on its own — do not expect reviewers to look up previous versions or linked URLs.
1

Describe the problem

Explain what is wrong and why it matters. Crashes and lockups are obvious, but subtler bugs need context. Describe user-visible impact, including excerpts from dmesg, performance regressions, lockup scenarios, or call traces.
2

Describe your solution

Once the problem is established, explain what you are doing about it in technical detail. Write in imperative mood: “make xyzzy do frotz” — not “[This patch] makes xyzzy do frotz”.
3

Quantify trade-offs

If you claim performance improvements, include numbers. Describe non-obvious costs. Optimizations trade CPU, memory, or readability.
4

Add tags

Include Fixes:, Closes:, and Link: tags where applicable. Reference commits by at least the first 12 SHA-1 characters plus the one-line summary.

Commit message format

subsystem: brief summary of what this patch does

Describe the problem motivating this patch. Be specific about
the impact — crashes, lockups, data corruption, performance
regressions. Include relevant dmesg excerpts or stack traces
(trimmed to the essential call chain, not raw dmesg output).

Describe your solution in technical detail. Explain why you
made the choices you did, especially when the approach is not
obvious.

Fixes: 54a4f0239f2e ("KVM: MMU: make kvm_mmu_zap_page() return the number of pages it actually freed")
Closes: https://bugzilla.kernel.org/show_bug.cgi?id=12345
Link: https://lore.kernel.org/r/[email protected]
Signed-off-by: Your Name <[email protected]>
Configure git for the Fixes: tag format:
git config core.abbrev 12
git config pretty.fixes 'Fixes: %h ("%s")'
# Then generate:
git log -1 --pretty=fixes 54a4f0239f2e

Separate your changes

Each logical change must be in its own patch. Do not mix bug fixes, performance improvements, and refactoring in a single commit.

One logical change per patch

If your changes include both a bug fix and a performance enhancement for a single driver, split them into separate patches. If you update an API and add a driver using it, those are two patches.

Single change across many files

A single logical change that touches many files belongs in a single patch. For example, a rename across the tree is one patch.

Kernel must build after each patch

Each patch in a series must leave the kernel in a buildable, bootable state. Developers use git bisect and will blame you if a mid-series patch breaks the build.

Limit series size

Post no more than ~15 patches at a time. Wait for review and integration before sending more.

Style-check your changes

Check for style violations before submitting:
# Primary style checker
scripts/checkpatch.pl my.patch

# Strict mode catches more issues
scripts/checkpatch.pl --strict my.patch

# Check a specific file (not a patch)
scripts/checkpatch.pl -f drivers/mydriver/myfile.c
The checker reports at three levels:
  • ERROR — very likely to be wrong
  • WARNING — requires careful review
  • CHECK — requires thought
You must be able to justify every remaining violation in your patch.

Find the right recipients

Using the correct maintainers and mailing lists is essential. get_maintainer.pl automates this:
# For a patch file
perl scripts/get_maintainer.pl my.patch

# For specific files
perl scripts/get_maintainer.pl -f drivers/net/ethernet/intel/e1000/e1000_main.c

# Output suitable for git send-email --to/--cc
perl scripts/get_maintainer.pl --nogit --norolestats my.patch
The script reads MAINTAINERS and the git log to identify:
  • File maintainers (M: entries)
  • Reviewers (R: entries)
  • Mailing lists (L: entries)
  • Subsystem trees (T: entries)
Always CC the subsystem mailing list. [email protected] is the default, but most subsystems have their own list. Do not spam unrelated lists.
For security-sensitive fixes, send to [email protected] instead of public lists. For fixes to released kernels, add to the sign-off area (not as an email recipient):

The Developer’s Certificate of Origin

Every patch must include a Signed-off-by: line. This certifies your agreement with the Developer’s Certificate of Origin (DCO 1.1):
By making a contribution to this project, I certify that: (a) The contribution was created in whole or in part by me and I have the right to submit it under the open source license indicated in the file; or (b) The contribution is based upon previous work that, to the best of my knowledge, is covered under an appropriate open source license and I have the right under that license to submit that work with modifications; or (c) The contribution was provided directly to me by some other person who certified (a), (b) or (c) and I have not modified it. (d) I understand and agree that this project and the contribution are public and that a record of the contribution is maintained indefinitely.
# git adds Signed-off-by automatically
git commit -s

# For reverts
git revert -s <commit>

Other tags

TagMeaning
Reviewed-by:Reviewer carried out a technical review and finds it acceptable
Acked-by:Maintainer/stakeholder accepts the patch without thorough review
Tested-by:Person has successfully tested the patch in some environment
Reported-by:Credits the person who found and reported the bug
Suggested-by:Credits the person who suggested the approach
Co-developed-by:Multiple co-authors; must be followed immediately by a Signed-off-by:
Fixes:Identifies the commit that introduced the bug
Closes:Links to a bug report; some trackers auto-close on merge
Most tags (except Cc:, Reported-by:, and Suggested-by:) require explicit permission from the person named. Do not add tags without asking.

The git send-email workflow

Patches must be submitted as plain-text inline in email — no MIME attachments, no compression.
1

Format your patches

# Single patch
git format-patch -1 HEAD

# Patch series with cover letter
git format-patch --cover-letter --base=auto -o outgoing/ origin/master

# Include base commit info for CI
git format-patch --base=auto --cover-letter -o outgoing/ master
2

Edit the cover letter

Open outgoing/0000-cover-letter.patch. Replace the *** SUBJECT HERE *** and *** BLURB HERE *** placeholders with:
  • A summary subject line
  • An overview of the series, the problem being solved, and any context reviewers need
  • Links to previous versions (from lore.kernel.org)
3

Send with git send-email

# Send all patches in the series
git send-email \
  [email protected] \
  [email protected] \
  outgoing/*.patch

# Or get recipients from get_maintainer.pl
git send-email \
  --to=$(perl scripts/get_maintainer.pl --nogit outgoing/0001-*.patch | \
         grep -E 'M:|L:' | awk -F'[<>]' '{print $2}' | paste -sd,) \
  outgoing/*.patch
4

Verify delivery

Check the public archive at lore.kernel.org to confirm your patch arrived intact and unmangled.

Patch subject format

[PATCH] subsystem: summary phrase
[PATCH v2] subsystem: summary phrase
[PATCH 2/5] subsystem: summary phrase
[PATCH v3 01/27] subsystem: summary phrase
[PATCH RFC] subsystem: request for comments summary
[PATCH v2 RESEND] subsystem: summary phrase
Use RESEND only when reposting a patch unchanged. Use v2, v3, etc. when you have made changes. The summary phrase must be 70–75 characters maximum and appear in the permanent git log.

Responding to review comments

Ignoring reviewers is the fastest path to having your work ignored in return.

Reply to all comments

Use interleaved (inline) replies, not top-posting. Quote the specific part you are addressing. Thank reviewers for their time — review is exhausting work.

Document your decisions

Comments that don’t lead to code changes should result in a comment or changelog entry so the next reviewer understands the rationale.

Add a patch changelog

Put the changelog between --- and the diffstat. It is stripped when the patch is applied and does not pollute the git log.

CC commenters on v2

Add everyone who commented on the previous version to the CC list of your revised submission.

Version changelog format

subsystem: fix the frobnication logic

Describe the actual fix here.

Signed-off-by: Author Name <[email protected]>
---
V3 -> V4: Addressed review comment from Jane; moved error path to label
V2 -> V3: Removed redundant helper function per Bob's suggestion
V1 -> V2: Fixed off-by-one in loop bound

v3: https://lore.kernel.org/r/[email protected]
v2: https://lore.kernel.org/r/[email protected]
v1: https://lore.kernel.org/r/[email protected]

 path/to/file | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

Submission checklist

Before sending, verify:
  • Every #include is for a header you directly use
  • scripts/checkpatch.pl --strict passes or violations are justified
  • All memory barriers have comments explaining their purpose
  • No new BUG() or BUG_ON() calls
  • New CONFIG options default to off
  • All new Kconfig options have help text
  • Tested with relevant CONFIG_ options enabled and disabled
  • Global kernel APIs have kernel-doc comments
  • New /proc entries are documented under Documentation/
  • New module parameters have MODULE_PARM_DESC()
  • New ABI is documented in Documentation/ABI/
  • Builds with CONFIG_=y, =m, and =n
  • Passes allnoconfig and allmodconfig
  • No GCC warnings with make KCFLAGS=-W
  • Tested on multiple architectures if touching arch-sensitive code
  • Tested with CONFIG_PREEMPT, CONFIG_DEBUG_PREEMPT, CONFIG_SLUB_DEBUG, CONFIG_DEBUG_PAGEALLOC, and lockdep all enabled simultaneously
  • Tested with and without CONFIG_SMP
  • Tested against linux-next

Patience and persistence

Expect a wait of 2–3 weeks before receiving comments. During merge windows, wait longer. Do not ping after less than one week. If you receive no response after a few weeks, you may resubmit with RESEND in the subject. After substantial time with no response, consider reaching out to the maintainer directly or to their backup (often Andrew Morton, [email protected]).

Build docs developers (and LLMs) love