# 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:

```text
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:

```bash
sudo insmod kobjx_slab_rcu_registry.ko
```

Initialization sequence:

```text
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

```text
                 +------------------+
                 |   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:

```c
obj = kmem_cache_alloc(
        kobjx_cache,
        GFP_KERNEL);
```

Benefits:

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

Real kernel users:

```text
inode cache
dentry cache
task_struct
file objects
```

---

## 2. Linked List

Tracks all active objects.

Insertion:

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

Visualization:

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

Purpose:

- Object enumeration
- Reclaim scanning
- Registry tracking

---

## 3. Hash Table

Provides fast object lookup by ID.

Insertion:

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

Lookup:

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

Lookup flow:

```text
Object ID
    |
    v

Hash Function
    |
    v

Bucket
    |
    v

Target Object
```

Average complexity:

```text
O(1)
```

instead of

```text
O(n)
```

for linked-list traversal.

---

# The Kernel Object

Each registry entry contains metadata plus bookkeeping structures.

```c
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.

```c
obj = kmem_cache_alloc(
        kobjx_cache,
        GFP_KERNEL);
```

Initialization:

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

Registration:

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

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

Lifecycle:

```text
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:

```c
rcu_read_lock();

obj = kobjx_lookup(id);

rcu_read_unlock();
```

Lookup path:

```text
Reader
   |
   v

RCU Read Lock
   |
   v

Hash Lookup
   |
   v

Return Object
```

Advantages:

- No reader locking
- Minimal contention
- Excellent scalability

Used heavily in:

```text
Routing Tables
Dcache
Networking
Scheduler
```

---

# Safe Object Deletion

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

Unsafe:

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

Potential failure:

```text
CPU0 -> Reading Object

CPU1 -> Frees Object

CPU0 -> Dereferences Freed Memory

Kernel Crash
```

Correct approach:

```c
hash_del_rcu(&obj->hash_node);

list_del(&obj->list);

call_rcu(
        &obj->rcu,
        kobjx_rcu_free);
```

Deletion lifecycle:

```text
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

