Fixing One Line — Learning the Whole Process
I didn’t submit this patch out of curiosity. I submitted it because I had to. It was part of the application process for the Linux Kernel Bug Fixing Summer Unpaid 2025 program — a real, structured mentorship with real expectations.
One of the tasks seemed simple enough:
Fix a documentation warning, spelling, or grammar issue. Create a patch. Send it to Shuah Khan and the appropriate mailing list.
I had completed the prerequisite course — A Beginner’s Guide to Linux Kernel Development — where I learned how to generate and send patches. But this wasn’t an exercise. This was real.
I didn’t know how to identify something worth fixing. I didn’t know how to build the documentation or confirm I hadn’t introduced a new warning. I didn’t know what format maintainers expected — or even how to send a patch properly in the real workflow.
I knew editing documentation wouldn’t break the kernel. But it wasn’t about that. It was about proving I could follow the process, start to finish — even for a one-line change.
That was exactly the point.
This isn’t a story about a typo. It’s about how learning to contribute means learning the entire process, not just editing a file — and how that process starts with the smallest real step.
The Task I Was Assigned — and Where It Actually Led
The instructions were clear. As part of the application, I needed to find a real issue in the kernel documentation — a typo, grammar mistake, or a build warning — and send a patch upstream. Not a tutorial. Not a sandbox. A real patch to the real kernel.
Before I could fix anything, I needed to be sure I wasn’t making things worse.
The kernel documentation is written in reStructuredText (.rst) and built using Sphinx. If I introduced a syntax error or broke the formatting, I wouldn’t just be submitting a weak patch — I’d be breaking the build.
So the first thing I had to figure out was how to build the documentation and confirm that any changes I made were valid.
To do that, I ran the Sphinx documentation build process using the following target:
But before that, I had to install the required packages.
Once that was done, I ran the build from the root of the kernel source tree. The output appeared under:
Once I had the build process working, I was ready to start looking for something small — but real — to fix.
Finding a Real Problem — Not Just Typing Blindly
This wasn’t about rewriting a document or proving I could write clever prose. I needed to find one real issue — something traceable and worth submitting. That meant I couldn’t guess or fix what didn’t need fixing. I needed a way to identify small but valid problems, and confirm they hadn’t already been handled.
I turned to codespell, a command-line tool designed to catch common spelling mistakes across source trees. But using it blindly would have caused more noise than help. The Documentation/ directory includes translated .rst files in many languages, and I couldn’t confidently review them for accuracy. I didn’t want to touch what I couldn’t verify.
To restrict the scan to English documentation only, I excluded the translations/ directory using this command:
That gave me a focused list of files I could actually read and review. And it worked — one of the results was in energy-model.rst, where I found this sentence:
“than it should be possible to simply re-use them…”
It should have said:
“then it should be possible to simply reuse them…”
A one-word correction — but a valid one. Real grammar, real submission, right size. That was enough. It was my fix to own, and the kind of change that made sense for a first patch.
The First Patch — Getting It Out There
Finding the typo was just the beginning. To make it a real contribution, I had to follow the kernel process — not just editing the file, but preparing and sending a patch the way maintainers expect.
Writing the Commit
Once I staged the change, I committed it with the required sign-off:
At first, the message was brief — just a one-liner stating what changed.
Before preparing the patch, I amended the commit message to describe the actual fix:
Fixes a grammar issue ("than" → "then") and changes "re-use" to "reuse" for consistency with modern spelling.
It was still short and focused, but now it clearly stated what was corrected — not just that a correction was made.
To turn that commit into a patch file, I ran:
It generated a file like:
This file was ready to be sent. But to whom?
Finding the Right People
Kernel patches don’t go to a single centralized location. They’re sent directly to the maintainers of the relevant subsystem, and to the appropriate mailing lists.
To find the right recipients, I used the standard script:
It returned:
Because this patch was part of the mentorship application, I also copied my mentor:
Setting Up git send-email
Patches in the kernel community are still sent by email. On Ubuntu 25.04, I installed the required tool:
Then I configured SMTP in my ~/.gitconfig using Gmail and an App Password:
Note: Gmail requires App Passwords for tools like this — not my regular login password.
Sending the Patch
Before sending it, I checked formatting:
Then I tested delivery with a dry run:
Everything checked out. I sent it.
That was the moment the patch left my machine and entered the community. It wasn’t just a local edit anymore. It was now part of a review process — under the eyes of real maintainers, on the same path as every serious contribution.
Mentorship in Action — Feedback That Mattered
After sending the patch, I waited. It was only a one-line fix — valid, formatted correctly, signed off — but I didn’t know what to expect. I had done the technical part. What would happen next?
The reply came from Shuah Khan, a maintainer and coordinator of the mentorship program.
Her feedback wasn’t about the change itself. The code was fine. But something was missing around it.
She wrote:
“Add a short change log. You can include details on how you found the problem.”
“Send it to everybody get_maintainer.pl recommends you to send.”
This wasn’t a rejection. It was real guidance. I had submitted a clean patch — but I hadn’t communicated the context. Reviewers shouldn’t have to guess whether a change was the result of a warning, a tool, or a manual review. Even a fix that’s technically correct needs to carry its rationale.
It was a simple, essential reminder: a patch isn’t just a change. It’s a contribution — and it needs to stand on its own. That includes showing how the problem was identified and why the fix is appropriate. Especially for new contributors, this matters more than the size of the diff.
That one comment changed how I saw the process. It wasn’t just about sending patches. It was about helping others understand why they’re right.
I hadn’t done that. Now I would.
Writing v2 — and Getting It Right
Shuah’s feedback didn’t ask for a different fix. It asked for a better message. The patch was fine, but it lacked context — and that context matters.
So I revised it. Not the content of the change, but the way it was presented. I updated the commit message to include how the issue was found, giving reviewers confidence that the fix wasn’t arbitrary.
To do that, I amended the original commit:
In the new message, I added a changelog:
This explained the method — running codespell on non-translated documentation — and showed that the change was traceable, limited, and thoughtful.
Then I regenerated the patch:
And sent it again with the same recipients and an updated subject line:
I wasn’t thinking about email threading at the time, but by sending it as a new message, v2 showed up separately in the thread. That helped reviewers see it clearly, even if they were using Gmail or other clients that thread by default.
This time, the patch didn’t just fix a typo. It explained how the issue was discovered, how the fix was scoped, and why it was safe to apply. It wasn’t just about code. It was about communicating clearly — and respecting the process.
Patch Accepted — It Worked
After I sent the v2 patch with the changelog added, I considered the task done. I had followed the instructions, submitted the revision, and met the expectations. Whether it went any further didn’t matter — I had done my part.
I wasn’t expecting it to be accepted. That hadn’t been the point.
But then, on a Friday, the reply came in.
From Rafael Wysocki, the maintainer of the power management subsystem:
“Applied as 6.16 material, thanks!”
It was sudden — and honestly, surprising. I hadn’t written the patch with the intention of getting it merged. I wrote it to fulfill an application task. But there it was: accepted and queued for Linux 6.16.
That reply changed how I saw the entire effort.
The patch was small. But the process was real. The review was real. A maintainer had read it, understood it, and marked it for the mainline.
It confirmed something I had only hoped for: that doing the work correctly, no matter how minor, matters.
It Went Upstream — Now It’s Part of the Kernel
Getting a maintainer’s reply was already more than I expected. But what followed confirmed that this patch had truly become part of something bigger.
A few weeks later, I saw it: my name in the subject line of a [GIT PULL] email — part of the power management updates for Linux 6.16. The summary line was short, but clear:
“Fix typos in energy model documentation and example driver code (Moon Hee Lee...)”
That email came from the subsystem maintainer — and it was addressed to Linus Torvalds.
At that point, the patch wasn’t just accepted. It was in motion, on its way to mainline. It had passed review, entered the tree, and was advancing through the same process every patch follows — large or small.
The change was minor, but the path was real. It went through the proper steps and was included because it met the standards — not just as a kind gesture.
This wasn’t just a documentation fix anymore. It was now part of the kernel’s history.
Mainline Confirmed — Now It’s Forever
After the merge window for Linux 6.16 opened, I searched the commit history in the official repository. A few weeks had passed since I sent the patch, and I wanted to know if it had made it through.
And there it was.
My name. My patch. In the mainline commit log:
PM: EM: Documentation: fix typo in energy-model.rst
The log included the full commit message, my Signed-off-by, and a note from the maintainer indicating a subject tweak before merging. It had moved through every stage — review, acceptance, pull request, and merge.
This time, it wasn’t just on a mailing list or in an inbox. It was in the source. In the tree. The same tree built, mirrored, and shipped across millions of machines.
One small correction — and now, it’s part of Linux.
What I Actually Learned
This started as a requirement — just one of the steps to apply for the kernel mentorship program. Fix a typo. Make a patch. Follow the instructions.
But it didn’t stay that way.
I didn’t just correct a word. I learned how to track down a real issue in the tree. How to verify my change didn’t introduce a build error. How to find the right maintainers, prepare the patch properly, and send it in a way that fits the kernel’s workflow.
I learned that feedback isn’t a blocker — it’s part of the process. That the response to a patch is about more than the diff. That even a one-line fix is reviewed with care — and welcomed when it’s solid.
Most importantly, I saw what the kernel community values. Not perfection — but clarity, respect, and a willingness to learn.
This wasn’t just a step in applying. It was my first real contribution — and I can stand by it, not because it was big, but because it was done right.
From Patch to Program — I’m In
That single patch did more than fix a typo. It showed that I could follow the process, respond to feedback, and contribute the way the kernel community expects.
A few weeks later, I got the confirmation: I had been officially accepted into the Linux Kernel Bug Fixing Summer Unpaid 2025 program.
This patch was part of the application — but it wasn’t just about making a correction. It was about proving I could engage with the process. That I could read the code, build the docs, check the results, revise my work, and submit it properly. That I understood not just the code itself, but how it’s maintained and reviewed.
Now the real work begins. I’ll be learning from my mentor and maintainers — understanding how bugs are found, how fixes are shaped, and how the kernel stays reliable. And I’ll be sending patches that go beyond documentation.
But this one line made it possible. It opened the door.
Associate Architect | Embedded SW Engineer | Automotive | Learning Rust Language 🦀 | AUTOSAR | C | Diagnostics | DCM | UDS | CAN/CAN-FD | Ethernet | DoIP | I talk about C, AUTOSAR and Communication Protocols
2moHello Moon Hee Lee, Thank you for sharing your experience and this gonna help me a lot in coming days. Do you have any write-up about cloning the Linux kernel in VirtualBox (Ubuntu-based) and then compiling it. This is one of the step were I felt stuck and some tasks also include compiling kernel. And each time, if we compile whether it is mandatory to do complete compilation? I remember, if we use WSL we can't modify any kernel files.
Moon Hee Lee - what a super write up - very interesting. Really enjoyed reading that - Thank You
IP MPLS product/protocol Testing (Manual/Automation)
2moThanks for sharing, Moon Hee. I honestly enjoyed your full write up. Keep writing
Hee. I was thinking your original commit message was a bit sparse :-) Anyway congratulations on becoming a kernel contributor. Pretty soon your code will run on billions of devices!