Linux Kernel Tuning and Module Management
The Linux kernel sits at the heart of every Linux system, mediating between hardware and user-space processes. Knowing how to tune kernel parameters and manage loadable modules is essential for anyone operating production servers, building embedded systems, or simply trying to squeeze every bit of performance out of a workstation. This guide covers the sysctl framework for runtime parameter adjustment, the module subsystem for loading and unloading drivers, DKMS for out-of-tree module management, and the full workflow for compiling a custom kernel from source.
Runtime Kernel Tuning with sysctl
The sysctl interface exposes thousands of tunable parameters organised under a
hierarchy that mirrors the /proc/sys virtual filesystem. Listing every parameter is
straightforward:
sysctl -a # dump all current values
sysctl -a | wc -l # typically 1000-2000+ entries
sysctl net.ipv4.ip_forward # read a single parameter
To change a value at runtime:
sysctl -w net.ipv4.ip_forward=1
sysctl -w vm.swappiness=10
Runtime changes are lost on reboot. For persistence, add entries to /etc/sysctl.conf
or, on modern distributions, drop a file into /etc/sysctl.d/:
# /etc/sysctl.d/99-custom.conf
net.core.somaxconn = 4096
vm.swappiness = 10
fs.file-max = 2097152
net.ipv4.tcp_tw_reuse = 1
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
kernel.pid_max = 4194304
Apply without rebooting:
sysctl --system # reload all config files in order
Key Tunables Explained
| Parameter | Default | Purpose |
|---|---|---|
net.core.somaxconn |
4096 | Max length of the listen backlog queue. Raise for busy web servers. |
vm.swappiness |
60 | How aggressively the kernel swaps out memory pages (0-100). Lower values prefer keeping pages in RAM. |
fs.file-max |
~100k | System-wide limit on open file descriptors. Critical for servers handling many connections. |
net.ipv4.tcp_tw_reuse |
0 | Allow reuse of TIME_WAIT sockets for new connections. |
vm.dirty_ratio |
20 | Percentage of RAM that can be dirty before processes are forced to write. |
Kernel Module Management
Linux uses loadable kernel modules (LKMs) so that drivers and features can be inserted
or removed without rebooting. The key commands live in the kmod package.
lsmod # list currently loaded modules
lsmod | grep nvidia # check for a specific module
modinfo e1000e # show metadata: version, author, parms, depends
modinfo -p e1000e # list only module parameters
modprobe e1000e # load module plus its dependencies
modprobe -r e1000e # unload module and unused dependencies
insmod ./my_module.ko # load a specific .ko file (no dependency resolution)
rmmod my_module # remove a loaded module by name
Persistent Configuration with /etc/modprobe.d/
Blacklist a module so it never loads automatically:
# /etc/modprobe.d/blacklist-nouveau.conf
blacklist nouveau
options nouveau modeset=0
Pass options to modules at load time:
# /etc/modprobe.d/snd.conf
options snd_hda_intel power_save=1 power_save_controller=Y
After changes, rebuild the initramfs:
# Debian/Ubuntu
update-initramfs -u
# RHEL/Fedora
dracut --force
DKMS: Dynamic Kernel Module Support
DKMS automatically recompiles out-of-tree modules whenever a new kernel is installed. This is how packages like VirtualBox guest additions and NVIDIA drivers survive kernel upgrades.
dkms status # show registered modules
dkms add -m mymod -v 1.0 # register a module source tree
dkms build -m mymod -v 1.0 # compile for the running kernel
dkms install -m mymod -v 1.0 # install into /lib/modules/
dkms remove -m mymod -v 1.0 --all # unregister from all kernels
Module source trees live under /usr/src/<module>-<version>/ and must include a
dkms.conf describing how to build the module.
Compiling a Custom Kernel
Sometimes you need a kernel feature that is not enabled in your distribution kernel, or you want to strip the kernel down to only the hardware you actually have.
# 1. Obtain source
wget https://cdn.kernel.org/pub/linux/kernel/v6.x/linux-6.8.tar.xz
tar xf linux-6.8.tar.xz && cd linux-6.8
# 2. Start from the running kernel's config (optional but recommended)
cp /boot/config-$(uname -r) .config
make olddefconfig # accept defaults for new options
# 3. Interactive configuration
make menuconfig # ncurses TUI
# make nconfig # alternative ncurses interface
# make xconfig # Qt GUI (needs qt5 dev libs)
# 4. Build
make -j$(nproc) # compile kernel + modules
# 5. Install
sudo make modules_install # copies .ko files to /lib/modules/<version>
sudo make install # copies vmlinuz, System.map, updates bootloader
After installation, verify the new entry appears in your bootloader (grub2-mkconfig
or update-grub) and reboot to test. Keep the previous working kernel as a fallback.
For further background on the kernel's role in the startup sequence, see Linux Boot Process. To learn how kernel tunables interact with real-world workload metrics, continue to Performance Monitoring.
Back to the Linux overview.