I am trying to understand the disadvantages of using Linux kernel modules. I understand the benefits of using them: the ability to dynamically insert code into a running system without having to recompile and reboot the base system. Given this strong advantage, I was guessing most of kernel code should then be in kernel modules instead as part of base kernel, but that does not seem to be the case -- a good number of core subsystems (like memory management) still go into the base kernel.

One reason I can think of is that kernel modules are loaded very late in the boot process and hence core functionality has to go in the base kernel. Another reason I read was about fragmentation.

I didn't really understand why kernel modules cause memory fragmentation, can someone please explain? Are there any other downsides of using kernel modules?

5 Answers 5


With a monolithic kernel, in theory a single contiguous block of memory can be allocated for the kernel. If modules are loaded (and unloaded) on demand, then it's improbable that all kernel memory will be contiguous, and hence by definition it will be fragmented. The trade off is that a modular kernel will usually use far less memory that a monolithic kernel. This is certainly true with a default distro monolithic kernel, which likely has many unused drivers, though less true if you build your own monolithic kernel.

Some subsystems simply don't lend themselves to being modular, memory management is clearly one, SMP another. Process scheduling isn't modular, but I/O scheduling strategy is. Other subsystems aren't modular likely because of complex interdependencies, like TCP/IP.

Another problem with modules is that they're not so good if they drive the device you need to boot from, solutions like initrd work around this.

A final consideration is security, allowing loadable modules is a potential risk, e.g. kernel loadable rootkit like knark. See http://www.la-samhna.de/library/rootkits/index.html and http://www.sans.org/security-resources/malwarefaq/Ptrace.php . You can reduce this risk by enforcing signed modules (since kernel 3.7), loading a lockdown module last, or other hardening.


Yes, the reason that essential components (such as mm) cannot be loadable modules is because they are essential -- the kernel will not work without them.

I can't find any references claiming the effects of memory fragmentation with regard to loadable modules is significant, but this part of the LLKM how-to might be interesting reading for you.

I think the question is really part and parcel of the issue of memory fragmentation generally, which happens on two levels: the fragmentation of real memory, which the kernel mm subsystem manages, and the fragmentation of virtual address space which may occur with very large applications (which I'd presume is mostly the result of how they are designed and compiled).

With regard to the fragmentation of real memory, I do not think this is possible at finer than page size (4 KB) granularity. So if you were reading 1 MB of virtually contiguous space that is actually 100% fragmented into 1024 pages, there may be 1000 extra minor operations involved. In that bit of the how-to we read:

The base kernel contains within its prized contiguous domain a large expanse of reusable memory -- the kmalloc pool. In some versions of Linux, the module loader tries first to get contiguous memory from that pool into which to load an LKM and only if a large enough space was not available, go to the vmalloc space. Andi Kleen submitted code to do that in Linux 2.5 in October 2002. He claims the difference is in the several per cent range.

Here the vmalloc space, which is where userspace applications reside, would be that which is potentially prone to fragment into pages. This is simply the reality of contemporary operating systems (they all manage memory via virtual addressing). We might infer from this that virtual addressing could represent a performance penalty of "several percent" in userland as well, but in so far as virtual addressing is necessary and inescapable in userland, it is only in relation to something completely theoretical.

There is the possibility for further compounding fragmentation by the fragmentation of a process's virtual address space (as opposed to the real memory behind it), but this would never apply to kernel modules (whereas the last paragraph apparently could).

If you want my opinion, it is not worth much contemplation. Keep in mind that even with a highly modular kernel, the most used components (fs, networking, etc) will tend to be loaded very early and remain loaded, hence they will certainly be in a contiguous region of real memory, for what it is worth (which might be a reason to not pointlessly load and unload modules).

  • hello, I'm stuck with this question : I made a kernel module in raspberry which dialog with external sensor to ask for temperature. to talk with the sensor, i should set gpio pins input and output for specified amount of time (in ms) according to specified protocol. and since I got right results, so the kernel module respect the timing, so the kernel didn't preempt the module execution, to allow other process to run. so are kernel modules not preempted by other processes by the scheduler, since if it's preempted, the timing will be wrong, and the result get from sensor will be wrong.
    – makouda
    Nov 30, 2014 at 5:05
  • 1
    @Makouda Everything has to be pre-emptable, yeah. There's a lot of variables in what you've described, including your method for creating the delay -- which presumably involves a passive sleep during which other processes can be run.
    – goldilocks
    Nov 30, 2014 at 15:10

I don't know what other disadvantages there might be to compiling code as a loadable kernel module rather than directly into the kernel image, but to use your particular example, suppose that memory management was built as a kernel module rather than built into the kernel binary image itself.

  • How would the kernel allocate the memory for an initial RAM disk?
  • How would the kernel allocate the memory for the structures necessary to mount a file system?
  • How would the kernel allocate the memory in which to load the memory management module?
  • How would the memory management module know what memory has already been claimed by other parts of the kernel (possibly other loadable kernel modules which were needed to access the memory management module)?

As you can see, this immediately opens a whole potential can of worms. Task scheduling is another similarly core kernel concept.

From another perspective, what useful work could the kernel do without the memory management module? It's not like a hardware driver which can simply be disabled if the hardware isn't installed on the system; it's a basic feature that the kernel itself needs to even bootstrap.

While true microkernels have certain benefits from a separation of concern and code readability/understandability point of view, even they need certain things inside the kernel itself to work at all. Memory and task handling are among the core concepts of a multitasking operating system kernel -- and as is illustrated by the above list, are for all intents and purposes required for anything to work at all. Trying to separate it into a separately loaded component would, if nothing else, add a large amount of complexity for absolutely no gain (since everyone would be loading that module anyway).


I think the most important side effect of LKM-s is the speed.

When you use LKMs, you can delay loading them, thus resulting an earlier appear of the login prompt. (over serial, for ex.)

But this is a downside too. If you store your modules on a filesystem not available during boot, loading them is impossible before mounting that filesystem, thus resulting a later availability and device initialization.

Otherwise, as mr.spuratic pointed out, you shouldn't compile your HDD and filesystem drivers as modules, or it's maybe impossible to reach the modules (if you store them on the HDD in my example).

A related advantage of using LKMs is that the compiled kernel blob won't be so big: You should have a large boot partition available before the kernel start's operating.


Linux kernel module code is allocated using vmalloc(). vmalloc() has no issue with fragmentation, because it is virtual memory. Memory is divided into pages, usually 4Kb, and virtual memory allows remapping fragmented physical pages as a contiguous virtual block.

In the other corner is vmalloc(), which allocates virtually contiguous (but physically dispersed) pages in a separate virtual address space. vmalloc() is relatively slow, but it can perform large allocations that look contiguous to the kernel. It is thus used, for example, to allocate space for code from loadable modules.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.