Contributing to the Linux Kernel
Table of Contents
Introduction
I’ve been using Linux for a decade at this point, starting with Kali Linux as my first distro. As my fascination with C grew, so did my allure of Linux. The rich history of the language and *nix systems never failed to pique my interest. Having been an user and admirer from afar, I finally decided it was time to give back to the kernel development community. But how? I had heard ghastly, unnerving stories about the exacting nature of kernel development and the community’s sky-high standards, so how would I, a novice, be able to contribute?
Some search-fu with choice keywords lead to the LKMP – the Linux Kernel Mentorship Program. Currently, its an unpaid mentorship program offered by the Linux Foundation for new contributors wanting to get involved in kernel development. Besides the unpaid part (which is quite unfortunate), enrolling in the LKMP might have been the best jumping-off point I could’ve hoped for. The real strength of the program, in my opinion, is the mentorship group – it provides a much needed space for sharing / discussing bugs and potential fixes with other mentees who are going through the same ordeal as you are.
Learning from the mentor office hours was a great experience as well, it meant being exposed to different parts of the kernel you may not be looking to contribute to yourself. In my case, discussions about Rust were always interesting as I erred on the side of C. As a security enthusiast, I was interested in memory management and networking from the get-go, though unfortunately for me, those were the most complex and generic subsystems out there, leading to a lot of time spent buried in documentation and memory management source code – did you know Linux has a three-tier page table?
Overall, I found the program more challenging than expected because of work and other priorities taking up my weekdays, allowing only two days per week (sometimes even less) for contributions; And in no small part due to my lack of focus on selected subsystems. Instead, I dove head-first into various bug reports and bugzilla complaints trying to make sense of them before attempting any fixes, which significantly slowed me down and soaked up the limited time I had per week.
Accepted Patches
I started with a couple of low-hanging fruit to get used to the development process:
af3b45aac5c9d0bdaebf4e93e3fecddc3f363857 selftests/mm: fix spelling 04ec365e3fdf136ba5f9053b02fb6c3368a22e83 Documentation: fix doc link to fault-injection.rst
Thereafter, a significant amount of time was spent in getting to know the MM subsystem and trying my best to find contribution opportunities. My first significant patch stemmed from a few TODOs littered around in the testing code:
[mm-new]:
916bcd4c72fa869f8601071e84846e4ec39d4e43 selftests/mm/uffd: refactor non-composite global
vars into struct
This LKML archive link details discussions and reviews for the interested reader.
Next, aiming to contribute to the networking code, I found a TODO in the implementation of the Reliable Datagram Sockets protocol and contributed the following patches:
[net-next]:
bcb28bee987a1e161eaa5cc4cf2fb0e21306d4a7 rds: Fix endianness annotations for RDS extension headers
77907a068717fbefb25faf01fecca553aca6ccaa rds: Fix endianness annotation for RDS_MPATH_HASH
92b925297a2f233e0b16694df7b524360b8abb93 rds: Fix endianness annotation of jhash wrappers
9308987803bbf289d088d5266c5c3598e3fb3ddf rds: Replace POLLERR with EPOLLERR
Syzbot Bugs
I initially struggled (and still do to some extent) with reproducing the bugs
reported by syzbot on my system. As qemu
always crashed when run nested within a VM, I
had to resort to experimenting on my RaspberryPi & spin up (and pay for) cloud
instances, etc., all to not even be able to figure out the control flow sometimes 😫
Unaccepted Patches
Both the patches detailed below were rejected claiming that they were already fixed elsewhere, but that wasn’t immediately apparent from the syzkaller website and mailing list discussions.
The following patch against blockdev
attempted to fix a potential deadlock scenario reported by syzbot:
block: prevent deadlock in del_gendisk()
The following RFC patch against net/team
attempted switching from mutexes to
spinlocks to prevent sleeping functions from being called while interrupts were
disabled:
net: team: switch to spinlock in team_change_rx_flags
Closing Thoughts
My advice to anyone wanting to get into linux kernel development is to ensure you have a preferred email client setup beforehand so you can subscribe to mailing lists without having to worry about your allocated storage filling up. This is absolutely crucial to learn about a subsystem beyond the documentation and your own perusal of the source code. Additionally, sticking to one or two subsystems is a good choice rather than switching subsystems frequently, even though that might seem easier to find contribution opportunities.
Just doing these two things: subscribing yourself to mailing lists and focusing
on select subsystems will surely help with fixing bugs and contributing
effectively in the long run. TODO
s and XXX
s in the code are also a good
opportunity to learn as you’ve seen above. I highly encourage pushing yourself
beyond documentation and such once you’re comfortable, as that is the most
efficient way to grow.
Personally, it has been a thoroughly edifying, though taxing experience and I hope to find the time to continue contributing whenever possible.
You’ve made it to the end of my first ever blogpost, thanks! 🙌