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.