What is the SLOB (Simple List Of Blocks) memory allocator in the Linux kernel

What is the SLOB (Simple List Of Blocks) memory allocator in the Linux kernel

If you’ve only ever worked with modern desktop or server Linux, there’s a good chance you’ve never heard of SLOB. It’s not glamorous, it’s not the default, and as of kernel 6.4 it isn’t even in the tree anymore. But for over a decade, SLOB was the allocator of choice for the smallest, most memory-starved Linux devices in existence — old feature phones, routers, tiny industrial controllers. I want to walk through what SLOB actually is, how it works internally, and why it mattered.

The Problem SLOB Was Built to Solve

The mainline SLAB allocator (and later SLUB) both organize memory into size-class caches: fixed-size buckets like 32, 64, 128, 256 bytes, each managed as its own set of slabs. This is efficient in CPU terms — allocation is close to O(1) — but it costs memory. Every object gets rounded up to its size class, and each cache carries its own bookkeeping structures.

On a system with gigabytes of RAM, that overhead disappears into rounding error. On a system with 4MB or 8MB of total RAM — genuinely common in embedded Linux around the mid-2000s to 2010s — that overhead is a meaningful fraction of your total available memory. SLOB was written by Matt Mackall specifically to strip that overhead down to almost nothing, accepting slower allocation in return.

Core Design: A Literal List of Blocks

SLOB’s name is refreshingly literal. Rather than dividing memory into fixed size classes, SLOB treats free memory as a set of linked lists of free blocks, roughly analogous to classic heap allocators you’d find in a C runtime library (think early versions of dlmalloc).

Here’s the conceptual flow:

+------------------------------------------------------+
|                 Page obtained from buddy               |
|  [free 40B]->[used 24B]->[free 96B]->[used 8B]->[free 200B]
+------------------------------------------------------+

When a kmalloc() request comes in:

  1. SLOB walks its free list(s), looking for the first block that’s large enough to satisfy the request (a first-fit strategy, with some best-fit refinements added over the years to reduce fragmentation).
  2. If the found block is larger than needed, it’s split — the requested portion is returned to the caller, and the remainder stays on the free list as a smaller free block.
  3. If no free block anywhere is big enough, SLOB requests a fresh page from the page allocator (the buddy system), carves what it needs from it, and adds the rest to the free lists.

On free, the returned block is added back to the free list, and SLOB makes an effort to coalesce it with physically adjacent free blocks to avoid leaving tiny unusable slivers scattered everywhere.

SLOB actually maintains three separate lists by convention in its implementation — small, medium, and large object lists — as a lightweight way of reducing search time without going as far as full size-class buckets like SLAB/SLUB.

Why “Unreliable” Isn’t the Right Word (Common Misconception)

A frequent point of confusion — and it shows up in a lot of blog posts and quiz questions — is mixing up SLOB with something described as “unreliable.” SLOB has never officially stood for anything resembling “unreliable”; it stands for Simple List Of Blocks. It’s simple, not unreliable — it went through production use in real shipped devices for years. The “unreliable” label is sometimes mistakenly attached in casual explanations of SLUB’s name instead (SLUB stands for “the unqueued slab allocator,” which is a different and equally misleading mnemonic people love to garble). Getting this straight matters if you’re studying for a kernel internals exam or interview.

Strengths of SLOB

Weaknesses of SLOB

SLOB in Practice: Where You’d Actually See It

Historically, SLOB showed up in:

You’d typically select it via kernel config:

CONFIG_SLOB=y
# CONFIG_SLUB is not set
# CONFIG_SLAB is not set

And you could sanity-check which allocator was active by checking /proc/slabinfo — under SLOB, this file exists but reports far less detailed statistics than under SLUB, since SLOB doesn’t track the same per-cache metrics.

Why It Was Removed

By the early 2020s, two things had happened. First, even “small” embedded Linux targets had generally grown to have tens of megabytes of RAM at minimum, shrinking SLOB’s advantage. Second, SLUB itself had been tuned over the years to be reasonably competitive on memory footprint while being dramatically faster and better instrumented. The kernel community concluded the maintenance burden of keeping three separate slab allocators (SLAB, SLUB, SLOB) alive wasn’t worth it, SLAB was removed first, and SLOB followed in the 6.4 cycle. Projects still needing SLOB’s behavior are expected to stay on older LTS kernels or explore SLUB’s tuning knobs (like slub_min_order) to approximate similar memory savings.

Troubleshooting Tips (For Anyone Still on a SLOB Kernel)

Best Practices

Summary

SLOB was the Linux kernel’s answer to genuinely tiny memory budgets — a deliberately simple, linked-list-based allocator that traded CPU cycles and predictability for the smallest possible metadata footprint. It served its niche well for years across routers, feature phones, and small embedded boards, but growing device memory and a much-improved SLUB eventually made it redundant, leading to its removal from mainline in kernel 6.4. Understanding SLOB is still valuable, both historically and as a clean mental model of how a “simplest possible” memory allocator behaves.

FAQs

What does SLOB stand for? Simple List Of Blocks.

Is SLOB still maintained in the Linux kernel? No, it was removed from mainline in the 6.4 kernel release. It persists only in older kernel branches.

Why would anyone use SLOB over SLUB? Primarily on devices with extremely limited RAM (a few megabytes), where SLOB’s minimal metadata overhead outweighed its slower allocation speed.

Does SLOB support multi-core systems well? Not particularly well — it lacks the per-CPU caching that makes SLUB scale on multi-core hardware, which further limited its use case to small, often single-core embedded targets.

References

Exit mobile version