Recently, there was an opportunity to submit a patch to the Linux kernel. After struggling with SMTP configuration and being rejected by the boss multiple times, and after being advised by the maintainer to make modifications, it was finally accepted into the subtree... (Update: it has entered the mainline kernel!)
An opportunity to leave a lasting code name❌
The involved driver may be removed to avoid side-channel attacks. ✅
What is a Kernel Patch#
As we all know, the Linux kernel is one of the largest, most complex, and most important software in the world. Its development and maintenance rely on the collective efforts of thousands of developers worldwide.
The most basic way to contribute code to the Linux community is by submitting patches to the kernel maintainers via email (rather than "modern" pull requests on code hosting platforms).
A patch is a small text document containing a delta of changes between two different versions of a source tree. FROM kernel.org.
The patch file introduces the changes made to the code in a certain format, as well as the reasons for these modifications. After being reviewed and approved by the kernel maintainers, the patch will be merged into the mainline kernel or a specific branch.
Configuration Preparation#
This article is based on Ubuntu and introduces the basic configuration for sending patches.
- git
- git send-email (
apt install git-email
,git-core
is also needed) - diff
- perl
Among these, git is used for version control and code submission, git send-email is used for sending emails with patches, diff is used for comparing file differences, and perl is used as the Perl interpreter to execute scripts required for submitting patches.
To configure SMTP email sending, you need to add email-related configurations to the .gitconfig
file, as shown in the following example that uses Gmail as the sending email:
[user]
name = YOURNAME
# The email here should be the same as the sending email
email = [email protected]
[sendemail]
from = YOURNAME <[email protected]>
smtpencryption = ssl
# You can also use tls as the encryption method, and the port should be changed to 578
smtpserver = smtp.gmail.com
smtpuser = YOURNAME
smtpserverport = 465
smtpAuth = LOGIN # Optional
chainreplyto = false # Optional
# tocmd and cccmd are shortcuts for obtaining the kernel mailing list command. If you want to send it to yourself for testing, you can comment them out.
tocmd = "`pwd`/scripts/get_maintainer.pl --nogit --norolestats --nol"
cccmd = "`pwd`/scripts/get_maintainer.pl --nogit --norolestats --nom"
Making Modifications#
To submit a kernel patch, you need to first obtain a copy of the kernel code! You can obtain the kernel source code repository from kernel.org or other sources, clone it to a location of your choice using git clone
, and create a new branch for your modification work.
git clone git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
git branch -b fix/blablabla
Note that to avoid conflicts, you need to keep your local code consistent with the mainline. It is a good habit to do git pull
before starting modifications.
Describing the Changes#
When committing, briefly describe the changes you made. The commit title format can refer to other patches, usually in the form of A: B: blablabla
. Use git commit -s
to automatically add Signed-off-by: YOURNAME <[email protected]>
, or you can add this line manually in the patch file.
git format-patch -1
git format-patch
will generate a .patch
file in the current directory, which contains the standard email format (but not necessarily the standard patch format). Here, -1
means that the patch file should only contain one commit.
Between the Subject:
and Signed-off-by
lines, you need to provide a detailed description of the patch. In the patch I submitted, I described how I discovered the issue (using error information provided by Smatch), the cause of the error (unmapping of memory allocated by ioremap
), and the modification made (changed to devm_ioremap
to ensure memory unmapping when the device is removed).
Don't forget to test! You can choose to compile the entire kernel or only the modified part (such as a driver) for testing.
Sending and Waiting#
Format check: Use the built-in script in the kernel source code:
$PATH_TO_KERNEL/scripts/checkpatch.pl YOUR_PATCH.patch
A common error is:
WARNING: Possible unwrapped commit description (prefer a maximum 75 chars per line)
This is because the COMMIT_MSG
and patch in the Linux kernel need to be displayed properly on terminals with a limit of 80 characters per line. Therefore, each line should not exceed 80 characters (believe it or not, the kernel is full of magical ancient rules). Simply modify it according to the error message.
Do you remember the tocmd
and cccmd
we added in .gitconfig
?
tocmd = "`pwd`/scripts/get_maintainer.pl --nogit --norolestats --nol"
cccmd = "`pwd`/scripts/get_maintainer.pl --nogit --norolestats --nom"
The tocmd
line automatically retrieves the recipients, which are the kernel maintainers for the modified part. Similarly, the cccmd
line retrieves the email list for carbon copy. This simplifies the "CLI mental burden" when sending emails from the command line.
git send-email YOUR_PATCH.patch
Yes, the final sending command is that simple!
If you want to send it to yourself first or have someone experienced review it to avoid unreasonable patches that may anger the kernel maintainers, you can comment out the tocmd
and cccmd
lines, and add the --to
and --cc
options when sending, specifying the recipients and carbon copy recipients.
git send-email --to [email protected] --cc [email protected] YOUR_PATCH.patch
After sending, all you need is... to wait patiently. Well, kernel maintainers are very diligent, but no one can guarantee timely review and reply to all emails, right?
If several weeks have passed and your patch email is still unanswered (which is not uncommon), you can send a PING or RESEND to remind the maintainers.
git fromat-patch -1 --subject-prefix='PING'
# or
git format-patch -1 --subject-prefix='RESEND'
Modifications, v2, v3, v4...#
After a long wait, an email with "Re: PATCH" knocks on the door of your inbox. It may greet you with a simple "Applied, thanks," or it may be filled with complaints and anger (of course, most of the time it is polite and friendly).
Please note that the new PATCH, namely PATCH v2
, should be based on the original HEAD branch, just like the initial modification, instead of submitting new code based on your commit.
After making modifications according to the feedback, you can send out PATCH v2
. Remember to add changelog information after "Reviewed by," indicating the modifications you made. For example:
v2 -> v3: Directly deleted 'base' and its related code based on master.
v1 -> v2: Directly deleted 'base' and its related code based on PATCH v1.
The subject of the new email also needs to be modified:
git format-patch -1 --subject-prefix='PATCH v2'
The process of sending the new patch is the same as the first time, just be careful not to select the wrong file.
Perhaps the process of modifying the patch needs to be repeated many times, and maybe you still need to send v3, v4, but please don't be discouraged!
After Acceptance#
After your patch is accepted by the maintainers, it will first be merged into the submodule of the module (which can be found on git.kernel.org), and then all the patches will be submitted to Linus together and eventually enter the mainline kernel. Great success!
Other Things to Note#
- Instead of sending patches, you can also reply to emails using
git send-email
. You can find the specific commands you need after the email you want to reply to on https://lore.kernel.org/lkml/. - This article does not cover the case of sending multiple patches at once. You can find more information here.