R0KernelPath
module 102 / 262

Reviewing, Feedback & Patch Versions

Master the complete patch review lifecycle: how to respond, revise, version, and attribute so your patches actually land.

~6h focused study10 concepts

Overview

So you've sent your first patch to a Linux kernel mailing list. The maintainer — or a senior reviewer — has replied with comments. This moment is where most new contributors either grow into kernel developers or quietly disappear. The review process in the kernel is not a formality; it is the primary quality gate for code that will run on hundreds of millions of machines. Understanding how to participate in it properly is as important as writing the patch itself.

The Linux kernel uses email as its primary collaboration medium, and the conventions around it are not arbitrary. They evolved over decades to serve a workflow where thousands of contributors from different timezones, companies, and skill levels communicate asynchronously, with a paper trail that must be readable by anyone who later needs to understand why a change was made. The rules about how to reply, how to format your response, and how to re-submit are all in service of this goal: clarity, traceability, and respect for reviewers' time.

This module covers the complete lifecycle of a patch after it leaves your outbox: reading and responding to review comments in plain-text interleaved style, addressing feedback and sending improved versions (v2, v3, ...), writing the changelog block that explains what changed, understanding the formal sign-off tags (Reviewed-by, Acked-by, Tested-by, Fixes:), and handling the emotionally difficult but practically normal experience of rejection. The kernel community is blunt by culture, not by malice. Learning to decode terse technical criticism as helpful signal — and to respond with patience and precision — is a professional skill that will serve you well beyond kernel development.

By the end of this module, you will be able to participate fully in kernel review threads, iterate on patches to production quality, and read a patch header with all its tags and understand exactly what each one means and who is accountable for it.

why this matters for the kernel

The gap between "can write a correct kernel patch" and "can successfully land a kernel patch" is almost entirely social and procedural. Many technically excellent patches never get merged because their authors did not respond to reviews properly, sent v2 without a changelog, or gave up after a single round of criticism. This module directly addresses that gap. The review loop — patch, feedback, revision, re-submission — is the real unit of kernel contribution, not the individual patch.

From a broader perspective, the disciplines learned here — interleaved plain-text discussion, precise changelogs, formal attribution tags, resilience under critique — are transferable to any serious open-source project. The kernel's conventions represent the gold standard for asynchronous technical collaboration at scale, and understanding them deeply makes you a better engineer everywhere. The Reviewed-by and Acked-by system also teaches something profound about accountability: in a codebase with no merge commits and no PR approvals, the tag trail in a commit message is the permanent, auditable record of who reviewed what and staked their credibility on it.

Patch Lifecycle: From First Send to Mainline

rendering diagram…

The typical journey of a kernel patch. Each round-trip between author and reviewer corresponds to a new version. The maintainer queues the patch only after review tags are collected, then submits to Linus at the merge window.

The concepts

01Plain-Text Email and Why the Kernel Insists on It

The Linux kernel development process happens almost entirely over email, specifically plain-text email. This is not nostalgia; it is a deliberate engineering decision with real consequences.

HTML email embeds presentation inside content. A sentence in bold is semantically different from the same sentence in plain text in HTML — the bold is a formatting instruction that different clients render differently. More critically, HTML emails often break when quoted in replies: the threading collapses, code blocks lose indentation, and patches become unreadable. Kernel patches are sent as literal text attachments or inline text, and they must survive forwarding, quoting, and archiving across dozens of different email clients and mailing list archives over years.

Plain text also enforces clarity. You cannot hide a weak argument behind formatting. Every sentence must carry its own weight.

What this means practically: Configure your email client to send in plain text only. In Thunderbird: Account Settings → Composition & Addressing → uncheck 'Compose messages in HTML'. In Gmail (not recommended for kernel work), you would use a plugin or mutt/neomutt/aerc instead. The git send-email command always sends plain text, which is one reason it is the standard tool.

Code in emails must not be word-wrapped. Configure your client to not wrap lines, or wrap only at 72–74 characters without breaking code. A wrapped patch is a broken patch.

# Configure git to use your preferred mail client
git config --global sendemail.smtpserver smtp.example.com
git config --global sendemail.smtpuser you@example.com
git config --global sendemail.smtpencryption tls
git config --global sendemail.smtpserverport 587

# Send a single patch
git send-email --to=linux-kernel@vger.kernel.org 0001-my-patch.patch

# Check that your patch survives the trip (view the raw mbox)
# Most mailing lists archive at lore.kernel.org

02Interleaved (Inline) Replies: The Correct Technique

When a reviewer sends comments on your patch, the correct way to reply in the kernel community is interleaved or inline style: you quote the reviewer's specific sentences and respond below each quoted section. This is sometimes called "bottom-posting" by context, but more precisely it is inline replies.

Contrast this with top-posting (writing your entire reply at the top, with the original message quoted below) which is common in corporate email but is strongly discouraged in kernel development. Top-posting breaks the conversational flow — the reader must scroll to the bottom to recall context, then back to the top to read your reply.

The mechanics of a good inline reply:

  1. Delete all quoted text that you are not directly responding to. If a reviewer sent 20 lines and you are only addressing 5 of them, delete the other 15. Unnecessary quoting clutters the thread archives.
  2. Quote the specific sentence or code block being addressed.
  3. Write your response on a new line below the quote.
  4. Use > for the first level of quoting (the reviewer's words), >> for the second level (your original patch, which the reviewer was quoting), etc.
  5. If you agree with a comment and will fix it, say exactly that: "Good catch, will fix in v2." This acknowledges the feedback and tells the reviewer the thread for that comment is resolved.
  6. If you disagree, explain why technically and respectfully. Do not say "I disagree"; say "I think approach X is preferable because [technical reason]." The maintainer may agree with you, agree with the reviewer, or request a third approach.

Trimming scissors: Many kernel developers put a line like > <snip> where they removed irrelevant quoted text. This tells the reader that the trimming was deliberate, not accidental.

This technique rewards careful reading. Before you reply, read the entire review thread. Often a question in one comment is answered by another. Address all comments in one reply pass rather than sending multiple emails.

From: Reviewer <reviewer@example.com>
Subject: Re: [PATCH] mm: fix null deref in page_fault handler

> +	if (vma->vm_flags & VM_WRITE) {
> +		ret = handle_mm_fault(vma, address, flags, regs);
> +	}

This misses the case where the vma is NULL. You need to check
vma != NULL before dereferencing it.

---
From: You <you@example.com>
Subject: Re: [PATCH] mm: fix null deref in page_fault handler

On Mon, Jun 08 2026, Reviewer wrote:
> This misses the case where the vma is NULL. You need to check
> vma != NULL before dereferencing it.

You're right, I was relying on an earlier check that doesn't
guarantee vma is non-NULL at this point in the path. Will add
the NULL check before the dereference in v2.

Thanks for catching this.

You

03Sending v2, v3, ...: Versioning Your Patches

After addressing review feedback, you do not re-send the same patch. You send a new version, identified with a version number in the subject line prefix.

The format: The subject prefix changes from [PATCH] to [PATCH v2], [PATCH v3], and so on. If it is a series (multiple patches), it becomes [PATCH v2 1/3], [PATCH v2 2/3], [PATCH v2 3/3].

How to generate versioned patches with git:

git format-patch -v2 HEAD~1
# Produces: v2-0001-mm-fix-null-deref-in-page_fault-handler.patch

For a series:

git format-patch -v2 HEAD~3
# Produces three files prefixed with v2-

For a series with a cover letter (a separate email summarizing the series):

git format-patch -v2 --cover-letter HEAD~3

Critical rule: A new patch version starts a new email thread. You do NOT reply to the original thread with the new patch embedded. Send it as a fresh email (with the same subject minus the version number). This keeps the archive clean: each version is its own thread, and reviewers can easily find the latest version.

Exception: Some subsystem maintainers prefer that you link to the previous version in the cover letter or in the patch header. When in doubt, look at how others do it in the subsystem you're targeting via lore.kernel.org.

Practical tip: Between versions, re-read Documentation/process/submitting-patches.rst and run scripts/checkpatch.pl again on your new patch. It is surprisingly easy to introduce a new style violation while fixing a logic issue.

# v1 was:
# Subject: [PATCH] mm: fix null deref in page_fault handler

# After review, generate v2:
git add -p          # stage only your intentional changes
git commit --amend  # or create a new commit and squash

git format-patch -v2 --subject-prefix='PATCH' HEAD~1
# Output: v2-0001-mm-fix-null-deref-in-page_fault-handler.patch

# Send:
git send-email \
  --to=linux-mm@kvack.org \
  --cc=akpm@linux-foundation.org \
  v2-0001-mm-fix-null-deref-in-page_fault-handler.patch

04The Changelog Block: Documenting What Changed Between Versions

When you send v2 or later, reviewers need to know what changed. They have already reviewed v1; they do not want to re-read the entire patch from scratch. You document changes in a changelog block placed in the patch's commit message, below the --- separator line.

The --- line is the dividing line between permanent and ephemeral content in a patch. Everything above --- in the commit message becomes part of the permanent git history. Everything below --- (before the actual diff) is strip-comment: git am and git apply discard it. This is where you put:

  • The version changelog (what changed from v1 to v2, etc.)
  • Diffstat (auto-generated by git format-patch)
  • Any other reviewer notes that are relevant during review but should not clutter the permanent log.

Format of the changelog:

Changes in v2:
- Added NULL check for vma before dereference (per Reviewer's comment)
- Removed unnecessary blank line (checkpatch warning)

Changes in v3:
- Moved NULL check earlier in the function as suggested by Maintainer
- Added Reviewed-by tag from Reviewer

List specific changes with attribution where helpful ("per Reviewer's comment"). This is both polite and practically useful: it tells the reviewer exactly where to look to verify their feedback was addressed.

Do not put the changelog above ---. The commit message should describe what the patch does and why, not how it evolved through the review process. The evolution is noise for anyone reading the history six months later.

From 1a2b3c4d5e6f Mon Sep 17 00:00:00 2001
From: You <you@example.com>
Date: Mon, 08 Jun 2026 12:00:00 +0530
Subject: [PATCH v3] mm: fix null ptr deref in handle_page_fault

When a fault occurs on an address that has no associated VMA,
vma_lookup() returns NULL. The subsequent dereference of
vma->vm_flags causes a null pointer dereference and kernel panic.

Add an explicit NULL check and return VM_FAULT_SIGSEGV to the
caller, which will deliver SIGSEGV to the faulting process.

Fixes: 8f3e1a29b4d2 ("mm: introduce vma_lookup helper")
Reported-by: Syzbot <syzkaller@googlegroups.com>
Signed-off-by: You <you@example.com>
---
Changes in v3:
- Move NULL check before the flags test (suggested by Andrew Morton)
- Add Fixes: tag pointing to the commit that introduced the bug

Changes in v2:
- Added NULL check for vma (caught by Reviewer in v1 review)
- Dropped unrelated whitespace cleanup

 mm/memory.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/mm/memory.c b/mm/memory.c
...

05Reviewed-by, Acked-by, Tested-by: The Tag System and What It Means

Linux kernel commit messages carry a set of formal tags that document who was involved and in what capacity. These are not decorative — they are accountability records baked permanently into the git history. Every tag is a person staking their technical reputation on a specific claim.

Signed-off-by (SOB): Added by the author and every person in the chain of custody. It certifies, under the Developer's Certificate of Origin (DCO), that the contributor has the right to submit this code under its license, and that they understand the project's licensing terms. Every patch must have at least the author's SOB. Maintainers add their SOB when they apply a patch to their tree.

Reviewed-by: "I have read this patch carefully, I believe it is correct, and I am willing to stand behind that claim." This is the strongest endorsement. A Reviewed-by from a subsystem expert carries significant weight and often accelerates merging. To add someone's Reviewed-by to your patch, they must have explicitly granted it in the review thread — you don't add it speculatively.

Acked-by: "I have seen this patch, I don't object to it, and it looks okay to me" — but with less depth than Reviewed-by. Typically used by maintainers of adjacent subsystems to signal that the patch doesn't break their area. Also used when a subsystem maintainer is okay with someone else's tree merging a patch that touches their subsystem.

Tested-by: "I ran this code on real hardware and it works." Very valuable for hardware-specific drivers, architecture patches, and bug fixes. Tells Linus and maintainers that the patch survived contact with reality.

Reported-by: Credits the person who first reported the bug being fixed. Courtesy credit; does not imply they reviewed or tested the fix.

Fixes: Not a person tag — it's a reference tag: Fixes: <commit-hash> ("<commit subject>"). Documents which commit introduced the bug being fixed. Enables automated tooling to identify stable backport candidates and provides essential context for anyone reading the history.

How to collect tags: After a reviewer says "Looks good to me" or "LGTM" in the thread, you may add their Reviewed-by: tag in your next version. Always copy the exact email address from their email headers, not from memory. The tag format is precisely:

Reviewed-by: Firstname Lastname <email@domain.com>

If you are uncertain whether a "LGTM" constitutes a Reviewed-by grant, it is perfectly acceptable to reply: "May I add your Reviewed-by tag to v3?"

/* A real commit message showing correct tag usage */

mm: fix null ptr deref in handle_page_fault

When a fault occurs on an address with no VMA, vma_lookup()
returns NULL. The dereference of vma->vm_flags that follows
causes a null pointer dereference and kernel panic under
specific race conditions exposed by syzkaller.

Add explicit NULL check and return VM_FAULT_SIGSEGV.

Fixes: 8f3e1a29b4d2 ("mm: introduce vma_lookup helper")
Reported-by: Syzbot <syzkaller@googlegroups.com>
Reviewed-by: Matthew Wilcox <willy@infradead.org>
Acked-by: Vlastimil Babka <vbabka@suse.cz>
Tested-by: Guenter Roeck <linux@roeck-us.net>
Signed-off-by: You <you@example.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>

06The Cover Letter: Contextualizing a Patch Series

A single patch sent to a mailing list stands alone. But patches often come in series — logically related changes that must be understood together. A cover letter (patch 0/N) is a separate email that precedes the series and explains the big picture.

The cover letter is the place for:

  • The 'why' of the series: What problem does this series solve? Why is this approach better than alternatives?
  • Structure summary: "Patch 1 refactors X to make Y easier. Patch 2 adds Y. Patch 3 adds selftests."
  • Known limitations or TODOs: Things you know are missing and plan to address later.
  • Changelog for series versions: What changed from v1 to v2 at the series level (individual patch-level changes go in each patch's --- section).
  • Testing information: How you tested the series (hardware, distro, test suite, syzkaller run, etc.)

Generate a cover letter:

git format-patch --cover-letter -v2 HEAD~3
# Creates: v2-0000-cover-letter.patch, v2-0001-..., ...

Edit v2-0000-cover-letter.patch: replace the *** SUBJECT HERE *** and *** BLURB HERE *** placeholders.

The cover letter is especially important for subsystem maintainers who receive hundreds of patches per week. A clear cover letter is an act of respect for their time — it lets them quickly decide whether and when to look at your series in depth.

For a single-patch submission, a cover letter is usually not needed. Include the contextual information directly in the commit message.

# Generate a 3-patch series with cover letter
git format-patch --cover-letter -v2 \
  --subject-prefix='PATCH' \
  --to=linux-mm@kvack.org \
  --cc=akpm@linux-foundation.org \
  HEAD~3

# The cover letter (0000) needs manual editing:
# Subject: [PATCH v2 0/3] mm: fix page fault race conditions
#
# This series addresses three related race conditions in the page
# fault handler identified by syzkaller fuzzing.
#
# Patch 1 adds a missing NULL check for vma.
# Patch 2 corrects the locking order in do_page_fault.
# Patch 3 adds regression tests to tools/testing/selftests/mm/.
#
# Tested on x86_64 and arm64 with LTP mm tests, no regressions.
#
# Changes in v2:
# - Addressed Matthew's comment about locking order (patch 2)
# - Added selftest (new patch 3)
#
# You (3):
#   mm: fix null ptr deref in handle_page_fault
#   mm: fix locking order in do_page_fault
#   selftests/mm: add page fault race regression tests

07Responding to Rejection: Technical and Emotional Dimensions

Patches get rejected. This is not an exception — it is a normal, frequent event, even for experienced kernel developers. Understanding what rejection actually means, and how to respond, is a core competency.

Types of 'rejection' and what they actually mean:

  1. "This approach is wrong, please do it differently." This is not a rejection of your contribution; it is guidance. The maintainer has seen this approach fail, cause maintenance burden, or conflict with ongoing work you weren't aware of. Treat it as a valuable code review from someone with deep context.

  2. "This is out of scope / not the right subsystem." Your patch may be correct but sent to the wrong list, or it solves a problem that the kernel community has decided belongs in userspace, or it duplicates something being worked on elsewhere. This is process feedback, not a judgment on your skill.

  3. "NACK" (Negative Acknowledgment). A formal NACK means a maintainer explicitly does not want this change. NACKs require technical justification — a NACK with no reasoning is unusual and can be challenged. If you receive a NACK, read it very carefully and respond to the technical substance.

  4. No response. The most common experience for new contributors. The kernel mailing lists receive thousands of emails per week. If two weeks pass with no response, a polite single-sentence ping is appropriate: "Gentle ping on this patch — any feedback welcome." If silence continues, reconsider the mailing list routing, check that your patch passes checkpatch, and check lore.kernel.org to confirm the email arrived.

How to respond to criticism: The kernel community is famously blunt. A reply that says "This is wrong for reason X" with no softening is the norm, not rudeness. Read the technical content; try to separate the emotional register from the technical claim. Almost always, the claim is worth engaging with seriously.

If you believe you are correct and the reviewer is wrong, argue your position with evidence: cite the specification, link to a performance measurement, explain the failure mode you are preventing. Maintainers respect technical arguments. They do not respect repetition of the same claim without new evidence.

What NOT to do:

  • Do not send a new patch version without addressing all feedback, hoping the reviewer won't notice.
  • Do not CC more senior maintainers to pressure a reviewer — this is considered rude and will damage your reputation.
  • Do not abandon a good fix because of terse feedback. Terse does not mean hostile.
  • Do not take longer than a few days to respond. Long gaps cause reviewers to lose context and interest.
# A real-world example of a healthy NACK response flow

# Reviewer: "NACK. Using a spinlock here will cause priority inversion
# under RT kernels. Use a mutex instead."

# BAD response:
# "I tested this and it works fine. Resubmitting as-is."

# GOOD response:
# "You're right about the RT concern. I've switched to a mutex in v2.
# I also verified that the callers are never in atomic context
# (checked with might_sleep() in a debug build). Does v2 look better?"

# This response:
# 1. Acknowledges the reviewer was correct
# 2. Shows you understood WHY they were correct
# 3. Shows you verified the fix doesn't introduce new problems
# 4. Invites further review constructively

08Patience and the Kernel Development Timeline

The Linux kernel merge window opens twice per year (every 63–77 days, when Linus releases a new -rc1). During the merge window, subsystem maintainers submit their accumulated trees to Linus. After the merge window closes, the subsystem trees enter a stabilization phase, and maintainers are not accepting new patches (only fixes). Understanding this rhythm explains a lot of the "radio silence" new contributors experience.

The typical journey of a patch:

  1. You send a patch.
  2. If it is lucky, a reviewer replies within a few days.
  3. You address feedback and send v2.
  4. The maintainer queues it in their 'next' or 'testing' branch.
  5. The patch sits there for weeks while other patches are reviewed, while -rc cycles run, while conferences happen.
  6. At the next merge window, the maintainer submits their tree.
  7. Linus pulls the tree.
  8. Your patch appears in the mainline kernel, usually 1–3 months after v1.

For a simple one-liner bug fix, this can be faster (especially if it has a Fixes: tag pointing to a recent commit, which makes it a strong stable backport candidate). For a large new feature, it can take multiple kernel cycles — six months to a year is not unusual.

Practical patience strategies:

  • Subscribe to lore.kernel.org/subsystem RSS feeds so you can see when the subsystem is active.
  • Watch the maintainer's public git tree (linked in MAINTAINERS). If your patch appears there, it is queued.
  • Use b4 am and b4 shazam (from the b4 tool by Konstantin Ryabitsev) to fetch and apply patches from lore, and b4 prep to manage your own series — it handles many of the v2/v3 logistics automatically.
  • If a patch is important for stable trees (security fixes, serious bug fixes), the Fixes: tag and Cc: stable@vger.kernel.org accelerate it.

Patience is not passive. You can contribute more patches while waiting. You can review other people's patches in the same subsystem. Every review you give — even as a newcomer, even just "I tested this and it works" or "I think this comment on line 42 is slightly misleading" — is valuable and builds your reputation in the community.

# The b4 tool — modern helper for kernel patch workflows
pip install b4

# Fetch a patch series from lore by message-id
b4 am https://lore.kernel.org/linux-mm/20260608120000.12345-1-you@example.com/

# Track your own series through revisions
b4 prep --new my-fix-branch
b4 prep --auto-to-cc      # auto-detect recipients from MAINTAINERS
b4 send                    # send via git send-email with proper threading

# Check if a patch landed in Linus's tree
git log --oneline v6.10..v6.11 | grep 'your patch subject'

09Collecting and Verifying Stable-Tree Tags

Beyond the mainline kernel, there are stable kernel trees maintained by Greg Kroah-Hartman and Sasha Levin. These are the kernels that distributions ship: the 5.15.y, 6.1.y, 6.6.y long-term support (LTS) series. Bug fixes that are important enough get backported to these trees.

To request that your fix be backported to stable:

  1. Add Cc: stable@vger.kernel.org in the body of your patch (below the diffstat, in the --- area, so it is a hint to the stable team but not part of the permanent commit message). Actually, the convention is to put it as a tag line in the commit message:

    Cc: stable@vger.kernel.org  # v5.15+
    

    This tells the stable bot to consider the patch for all kernels from v5.15 onward.

  2. The Fixes: tag is even more powerful: the stable bot automatically queues patches with Fixes: tags for backport consideration. If your commit fixes a bug introduced in v6.8, it will be queued for all stable trees that include v6.8 or later.

  3. For complex patches that need manual backporting, you may be asked to produce the backport yourself and send it directly to stable@vger.kernel.org with [PATCH 5.15] ... in the subject.

Why this matters: If you are fixing a real bug, the users who matter most are often running stable kernels, not the bleeding-edge mainline. Understanding the stable process ensures your fix reaches them.

/* Commit message with proper stable targeting */

net: fix use-after-free in sk_destruct

The socket cleanup path calls sk_destruct() which may race with
an incoming packet being processed in softirq context. If the
packet processing reads sk->sk_prot after the socket has been
freed, a use-after-free occurs.

Hold a reference until all softirq processing completes.

Fixes: 3a4b5c6d7e8f ("net: refactor socket cleanup path")
Cc: stable@vger.kernel.org  # v6.1+
Reported-by: syzbot+abc123@syzkaller.appspotmail.com
Reviewed-by: Eric Dumazet <edumazet@google.com>
Signed-off-by: You <you@example.com>

10Using lore.kernel.org and patchwork to Track Your Patches

Once you have sent a patch, how do you know it arrived? How do you track its status? The kernel community provides two primary tools.

lore.kernel.org is the canonical public archive of all kernel mailing lists. Every message sent to a vger.kernel.org list (or many others) is archived here. You can:

  • Search for your patch by subject, author, or message-id
  • Read the entire thread context in a clean web UI
  • Access raw mbox for downloading with b4 am
  • Get a permanent link to share in future correspondence (always include the lore link when referring to a previous version)

To verify your patch arrived: search lore.kernel.org/subsystem-name for your name or subject within an hour of sending.

Patchwork (patchwork.kernel.org, or subsystem-specific instances like patchwork.ozlabs.org) is a patch tracking system that parses mailing list archives and tracks the state of each patch: New, Under Review, Accepted, Superseded, Deferred, RFC, Not Applicable, Rejected, Changes Requested. Maintainers update patch state here.

You can create a patchwork account and delegate patches to yourself, leave notes, and track review state. Checking patchwork for your subsystem occasionally tells you if a maintainer has seen and queued your patch without sending an explicit reply.

Practical workflow:

  1. Send patch with git send-email
  2. Within an hour, verify arrival on lore.kernel.org
  3. Note the message-id from the lore URL (looks like 20260608120000.12345-1-you@example.com)
  4. Include Link: https://lore.kernel.org/r/20260608... in your v2 cover letter
  5. Monitor patchwork for status changes
  6. If no response in 2 weeks, send a polite ping replying to the original thread
# Verify your patch arrived on lore
# After sending, go to: https://lore.kernel.org/linux-mm/
# Search for your name or subject

# Or use lei (lore email interface) CLI tool:
lei q --format text 'f:you@example.com s:"fix null ptr deref"'

# Download a thread by message-id for offline reading:
b4 mbox 20260608120000.12345-1-you@example.com -o /tmp/thread.mbox

# Include the lore link in your cover letter:
# Link to v1: https://lore.kernel.org/r/20260601...
# This lets reviewers compare v1 and v2 easily.

Key insights

  • ✦The `---` separator line in a patch is the boundary between permanent history and ephemeral review notes: everything below it is stripped when the patch is applied, which is exactly where changelogs belong.
  • ✦Sending v2 always starts a fresh email thread — never reply to the v1 thread with the new patch embedded, because archives and tooling expect each version as its own thread.
  • ✦Reviewed-by, Acked-by, and Tested-by are permanent accountability records staked by real engineers with their reputation; you must have explicit permission to add someone's tag.
  • ✦Terse kernel review emails are a style, not hostility — separate the emotional register from the technical content and address the technical content directly.
  • ✦The Fixes: tag does two things simultaneously: it explains the history of a bug and automatically flags the patch as a stable backport candidate.
  • ✦Patience in the kernel is structural: the merge window rhythm means patches can wait 1–3 months even when everything is going well; this is not silence, it is process.
  • ✦Every review you give as a newcomer builds reputation — 'I tested this on hardware X and it works' is a real Tested-by contribution that maintainers value.
  • ✦The `b4` tool handles the mechanical complexity of versioning, threading, and recipient list management that previously required careful manual work.

Common pitfalls

  • ⚠Putting the version changelog above the `---` line, which embeds review iteration noise into the permanent git history that future developers must read.
  • ⚠Replying to the old patch thread with v2 attached instead of sending a fresh email, which breaks mailing list threading and confuses tooling like patchwork.
  • ⚠Adding a Reviewed-by or Tested-by tag without the person explicitly granting it in the review thread — this is considered dishonest and will be noticed.
  • ⚠Sending v2 that silently ignores some review comments, hoping the reviewer won't check — reviewers almost always check, and it signals poor faith.
  • ⚠Top-posting in review replies instead of inline/interleaved replies, which forces reviewers to scroll and reassemble context and is considered disrespectful of their time.
  • ⚠Escalating to more senior maintainers to bypass a NACK or silence — this is considered rude and can permanently damage your standing in a subsystem community.
  • ⚠Omitting the Fixes: tag on a genuine bug fix, which means the stable team may never see it and millions of users on LTS kernels remain vulnerable.
  • ⚠Abandoning a valid patch after one round of blunt criticism — kernel review style is direct, not hostile, and most first-round feedback is refinement, not rejection.

Practice

  1. 01
    easy

    Find an open patch series on lore.kernel.org (try lore.kernel.org/linux-staging) that has at least one reviewer reply. Write a draft inline reply to one of the reviewer comments, correctly trimming irrelevant quoted text, using proper `>` quoting style, and responding to the technical substance of the comment. You do not need to send it — save it as a text file and review it against the guidelines in this module.

  2. 02
    easy

    Take any small, real change in a test kernel tree (or a toy kernel module you've written). Use `git format-patch -v1` to produce a v1 patch, then make a small additional change and produce a v2 patch with `git format-patch -v2`. Write a proper changelog block below the `---` line in the v2 patch documenting what changed. Verify using `git am` on a fresh branch that the patch applies cleanly and that the changelog does NOT appear in `git log`.

  3. 03
    medium

    Find a real, merged kernel commit that has Reviewed-by, Acked-by, and a Fixes: tag (search git.kernel.org or lore.kernel.org for commits in a subsystem you care about). Then trace backwards: find the original v1 patch thread on lore.kernel.org, read the entire review thread, and write a short (1 page) narrative of how the patch evolved from v1 to the final merge, noting which comments led to which changes.

  4. 04
    medium

    Install the `b4` tool and use it to fetch a recent patch series from lore.kernel.org that is not yet merged (search for [PATCH 0/] in a subsystem). Apply it to a kernel build tree, build the relevant subsystem (`make drivers/net/` for example), and write a 'Tested-by' statement in the form it would appear in a reply email. Identify any build warnings or errors and describe what you would do next.

  5. 05
    hard

    Write a complete simulated review cycle for a toy patch you invent. The patch should have at least one real bug or style issue. Write: (1) the v1 patch with commit message, (2) a review email with inline comments pointing out the issue, (3) a reply email addressing the review, (4) the v2 patch with corrected code and a proper changelog below ---. All four artifacts should be complete, correctly formatted plain text.

Resources

📄Submitting Patches: the essential guide
docsfree

The canonical, authoritative reference for the entire patch submission and review process. Read it before sending any patch.

🔧Linux Kernel Mailing List Archive (lore.kernel.org)
toolfree

The primary archive for all kernel mailing lists. Essential for studying real review threads and tracking your own patches.

🔧b4: tool for working with patches in a public-inbox archive
toolfree

Modern Python tool by Konstantin Ryabitsev that automates patch threading, versioning, recipient detection, and mbox handling.

📄Developer's Certificate of Origin (DCO)
docsfree

Explains the legal meaning of Signed-off-by and the DCO. Required reading before any submission.

📕Linux Kernel Development (3rd ed.)
bookpaidRobert Love — Addison-Wesley / Pearson. ISBN 978-0672329463.

Chapter on the kernel development process gives excellent human context for the review culture and workflow.

📄How the development process works
docsfree

Explains the merge window, -rc cycle, and stable tree cadence — the structural reasons patches take time.

✎Linux Kernel Newbies — First Kernel Patch
articlefree

Step-by-step walkthrough of the full patch lifecycle targeted at beginners, complementing the official docs with examples.

🔧Patchwork Kernel Patch Tracker
toolfree

Web interface for tracking patch state (New/Accepted/Rejected/Superseded) across kernel subsystems.

📄Email clients info for Linux (kernel docs)
docsfree

Specific configuration instructions for Thunderbird, mutt, neomutt, aerc, and others to send patch-safe plain text email.

✎LWN.net — Kernel development articles
articlefree

Weekly articles covering kernel development process, subsystem news, and review culture. Older articles are free; recent ones require subscription.

Checkpoints — you can now…

  • ✓You can write a correctly formatted interleaved reply to a kernel review email, trimming irrelevant quoted text and responding below each quoted section.
  • ✓You can generate a v2 patch with `git format-patch -v2` and correctly place a changelog block below the `---` separator, verifying it does not appear in `git log` after `git am`.
  • ✓You can explain the precise meaning of Reviewed-by, Acked-by, Tested-by, Fixes:, and Signed-off-by, and you know you must have explicit permission before adding someone's tag.
  • ✓You can look up any kernel mailing list thread on lore.kernel.org and trace a patch from v1 through its review iterations to its final merge commit.
  • ✓You can write a cover letter for a multi-patch series that explains the big picture, documents per-version changes, and includes testing information.
  • ✓You can articulate the difference between a NACK and silence, and describe an appropriate response to each.
  • ✓You can identify whether a bug-fix patch should carry a Fixes: tag and a Cc: stable@vger.kernel.org, and explain why this matters for users on LTS kernels.