Skip to main content

Command Palette

Search for a command to run...

Building a Mini Linux Kernel Object Registry Using SLAB, RCU, Hash Tables, Shrinkers, and Procfs

Updated
4 min read
Building a Mini Linux Kernel Object Registry Using SLAB, RCU, Hash Tables, Shrinkers, and Procfs

Building a Mini Linux Kernel Object Registry Using SLAB, RCU, Hash Tables, Shrinkers, and Procfs

Modern Linux kernels manage massive numbers of dynamically created objects.

Examples include:

  • Inodes
  • Dentries
  • Device objects
  • Routing entries
  • Network flows
  • Filesystem metadata

These objects must support:

  • Fast allocation
  • Fast lookup
  • Safe deletion
  • Memory reclamation
  • User-space visibility
  • Multicore scalability

In this article we build a miniature kernel object registry that combines several important Linux kernel technologies:

SLAB Allocator
Hash Tables
RCU (Read-Copy-Update)
Shrinkers
Procfs
Per-CPU Statistics

The result behaves like a tiny kernel object database.


What Happens When the Module Loads

Load the module:

sudo insmod kobjx_slab_rcu_registry.ko

Initialization sequence:

Module Load
      |
      v

Create SLAB Cache
      |
      v

Register Shrinker
      |
      v

Create /proc/kobjx_stats
      |
      v

Create Objects
      |
      v

Insert Into List
      |
      v

Insert Into Hash Table
      |
      v

Perform Lookup
      |
      v

RCU-Safe Deletion

The module demonstrates the complete lifecycle of a kernel-managed object.


High-Level Architecture

                 +------------------+
                 |   kmem_cache     |
                 +---------+--------+
                           |
                     alloc/free
                           |
                           v

      +----------------------------------+
      |             kobjx                |
      +----------------------------------+
      | id                               |
      | name                             |
      | created                          |
      | in_use                           |
      +----------------------------------+
            |                     |
            v                     v

      global_list          global_hash

            |                     |
            +----------+----------+
                       |
                       v

                  Lookup

                       |
                       v

                    RCU

                       |
                       v

                 call_rcu()

                       |
                       v

                  SLAB Free

Core Kernel Technologies Used

This project combines six major kernel concepts.

1. SLAB Cache

Provides efficient allocation of fixed-size kernel objects.

Example:

obj = kmem_cache_alloc(
        kobjx_cache,
        GFP_KERNEL);

Benefits:

  • Reduced fragmentation
  • Object reuse
  • Better cache locality
  • Faster allocations

Real kernel users:

inode cache
dentry cache
task_struct
file objects

2. Linked List

Tracks all active objects.

Insertion:

list_add_tail(
        &obj->list,
        &kobjx_list);

Visualization:

+---------+      +---------+      +---------+
| Obj A   | ---> | Obj B   | ---> | Obj C   |
+---------+      +---------+      +---------+

Purpose:

  • Object enumeration
  • Reclaim scanning
  • Registry tracking

3. Hash Table

Provides fast object lookup by ID.

Insertion:

hash_add_rcu(
        kobjx_hash,
        &obj->hash_node,
        obj->id);

Lookup:

hash_for_each_possible_rcu(
        kobjx_hash,
        obj,
        hash_node,
        id)
{
    if (obj->id == id)
        return obj;
}

Lookup flow:

Object ID
    |
    v

Hash Function
    |
    v

Bucket
    |
    v

Target Object

Average complexity:

O(1)

instead of

O(n)

for linked-list traversal.


The Kernel Object

Each registry entry contains metadata plus bookkeeping structures.

struct kobjx {
        u32 id;
        char name[32];

        unsigned long created;

        atomic_t in_use;

        struct list_head list;
        struct hlist_node hash_node;

        struct rcu_head rcu;
};

Field summary:

Field Purpose
id Unique identifier
name Human-readable name
created Creation timestamp
in_use Object state
list Linked-list tracking
hash_node Hash bucket entry
rcu Deferred destruction

Object Creation Flow

Allocation starts from the SLAB cache.

obj = kmem_cache_alloc(
        kobjx_cache,
        GFP_KERNEL);

Initialization:

obj->id = id;
obj->created = jiffies;

Registration:

list_add_tail(
        &obj->list,
        &kobjx_list);

hash_add_rcu(
        kobjx_hash,
        &obj->hash_node,
        id);

Lifecycle:

Allocate From SLAB
         |
         v

Initialize Object
         |
         v

Insert Into List
         |
         v

Insert Into Hash
         |
         v

Object Becomes Active

This is very similar to inode and dentry creation paths inside the Linux VFS.


RCU-Based Lock-Free Lookup

Readers execute:

rcu_read_lock();

obj = kobjx_lookup(id);

rcu_read_unlock();

Lookup path:

Reader
   |
   v

RCU Read Lock
   |
   v

Hash Lookup
   |
   v

Return Object

Advantages:

  • No reader locking
  • Minimal contention
  • Excellent scalability

Used heavily in:

Routing Tables
Dcache
Networking
Scheduler

Safe Object Deletion

A kernel object cannot be freed immediately because another CPU may still be reading it.

Unsafe:

hash_del(&obj->hash_node);
kfree(obj);

Potential failure:

CPU0 -> Reading Object

CPU1 -> Frees Object

CPU0 -> Dereferences Freed Memory

Kernel Crash

Correct approach:

hash_del_rcu(&obj->hash_node);

list_del(&obj->list);

call_rcu(
        &obj->rcu,
        kobjx_rcu_free);

Deletion lifecycle:

Remove From Hash
         |
         v

Remove From List
         |
         v

call_rcu()
         |
         v

Grace Period
         |
         v

Actual Free

GitHub Repository

https://github.com/aj333git/linux_kernel_kobjex