# Linux Kernel Module for Memory and Per-Process RSS via /proc

# Building a Linux Kernel Module for Memory and Per-Process RSS via /proc

User-space utilities such as `top`, `htop`, and `free` present a polished view of system memory usage, but they abstract away substantial kernel-level mechanics. To understand how Linux actually tracks memory—both globally and per process—I implemented a **Linux kernel module** that exposes system-wide memory statistics and per-process **Resident Set Size (RSS)** directly through `/proc`.

The result is a minimal, educational kernel-space alternative to user-space monitoring tools, designed explicitly to reinforce core Linux kernel concepts rather than replace existing utilities.

---

## Overview

The module registers a virtual `/proc` entry that reports:

- System-wide memory statistics (total, free, used, buffers)
- Per-process memory usage (RSS) for all user-space processes

All data is gathered **inside the kernel**, without relying on `/proc/meminfo` or `/proc/[pid]/status` as intermediaries.

---

## Module Functionality

### `/proc` Interface

The module creates a virtual proc entry:


This file does not exist on disk. Its contents are generated dynamically each time it is read.

---

### System-Wide Memory Statistics

The kernel’s global memory state is retrieved using `si_meminfo()`:

- Total RAM
- Free RAM
- Used RAM
- Buffer memory

These values come directly from kernel accounting structures, ensuring accuracy and eliminating any user-space interpretation.

---

### Per-Process RSS Reporting

To report per-process memory usage, the module:

- Iterates over all tasks using `for_each_process`
- Skips kernel threads (which have no user memory context)
- Extracts RSS using `get_mm_rss(task->mm)`

For each eligible process, the output includes:

- PID
- Process name (`comm`)
- RSS in pages (or converted to kilobytes)

This mirrors how tools like `top` internally derive memory usage, but without leaving kernel space.

---

### Safe and Scalable Output with `seq_file`

The module uses the **`seq_file` API** to emit output:

- Supports large output safely
- Automatically handles pagination
- Prevents buffer overflows
- Avoids manual offset and length tracking

This is the canonical mechanism for `/proc` entries that may grow beyond a single page.

---

## Key Kernel Concepts Reinforced

Building this module clarified several core Linux internals that are often hidden by user-space abstractions.

### 1. Memory Accounting via `mm_struct`

- RSS is tracked at the `mm_struct` level
- Kernel threads do not have an `mm_struct`
- User processes share memory mappings in predictable ways

Understanding this explains why some processes appear in `ps` but not in memory listings.

---

### 2. Dynamic Nature of `/proc`

- `/proc` files are **generated on demand**
- No persistent storage exists for their contents
- Read operations invoke kernel callbacks

This reinforces that `/proc` is an interface—not a filesystem in the traditional sense.

---

### 3. Kernel Iteration Over Processes

- `for_each_process` walks the global task list
- Requires care to avoid dereferencing invalid memory
- Must handle tasks exiting concurrently

Even read-only inspection requires disciplined kernel programming.

---

### 4. Why `seq_file` Is Mandatory for Real Modules

Manual string buffers are unsafe for variable-length output. The `seq_file` API:

- Manages internal buffers automatically
- Scales with process count
- Is required for production-quality `/proc` modules

---

## Debugging and Learning Challenges

### Secure Boot and Kernel Lockdown

On UEFI systems with Secure Boot enabled:

- Unsigned kernel modules are rejected—even for root
- The kernel enforces lockdown mode

Resolution involved:

- Generating a Machine Owner Key (MOK)
- Signing the module using `sign-file`
- Enrolling the key via `mokutil`

This highlighted the security model modern kernels enforce by default.

---

### `vermagic` Mismatches

Several build failures were traced to:

- Compiling against incorrect kernel headers
- Header versions not matching the running kernel

This reinforced the importance of:

- Matching `uname -r` exactly
- Avoiding stale header packages

---

### Kbuild and Makefile Discipline

Kernel builds exposed why:

- Kernel Makefiles must be **path-sensitive**
- Build logic should be minimal and kernel-centric
- Project orchestration (docs, scripts, tooling) must remain outside Kbuild

Mixing human-oriented build steps with kernel build logic leads to fragile modules.

---

## Why This Matters

User-space tools provide convenience. Kernel modules provide **truth**.

By implementing this module, the following became concrete rather than theoretical:

- How Linux accounts memory internally
- How process memory differs from system memory
- Why certain abstractions exist in user-space tools
- How kernel APIs prioritize safety and scalability

This project was not about performance or production deployment—it was about **understanding Linux from the inside out**.

---

## Summary

This kernel module demonstrates:

- Creating a dynamic `/proc` entry
- Extracting global memory data using `si_meminfo`
- Iterating safely over processes with `for_each_process`
- Computing per-process RSS via `mm_struct`
- Using `seq_file` for robust output
- Navigating Secure Boot, module signing, and Kbuild pitfalls

For anyone serious about systems programming, kernel development, or low-level performance work, projects like this provide insight that no user-space API can fully replicate.

The complete source code for this Linux kernel module is available on
[GitHub Repository](https://github.com/aj333git/linux_kernel_process_03)

---

If needed, this can be extended further to:
- Filter processes by UID
- Export data via `debugfs`
- Track memory deltas over time
- Integrate with eBPF for hybrid kernel/user analysis

