Target Duration: 2–4 minutes (~300–450 spoken words)
Focus: Pointwise verbal delivery comparing historicalprocfsstreams against modern structuredsysfskobjects, single-opener mutual exclusion, and granular attribute show/store callbacks.
What You Mentioned: "Kernel telemetry via /proc and sysfs"
Why It Was Done (The Motivation): Contrast procedural stream interfaces with structured object-oriented sysfs attributes.
Problems Faced & How Solved (The Reality): Implemented struct proc_ops for lockless page-fault streaming and a sysfs kobject with container_of for per-PID memory queries.
Opening & Scope:
"In Part 3, I implemented kernel observability interfaces (3.1/get_pgfaults.c and 3.2/get_memstats.c) to export telemetry and control knobs to user space, comparing the historical procfs pseudo-filesystem with the modern, object-oriented sysfs subsystem."
Step 1: System Page Fault Telemetry via procfs (/proc/get_pgfaults):
"First, in Part 3.1, I built an interface under /proc to export aggregate system page fault statistics. Using the modern Linux 6.1 proc_create() (3.1/get_pgfaults.c:76) API and the struct proc_ops (3.1/get_pgfaults.c:68) table, I registered the pseudo-file /proc/get_pgfaults. When read, the module queries the kernel's virtual memory event counters using all_vm_events() (3.1/get_pgfaults.c:48), extracts system-wide major and minor page fault numbers, and copies the formatted string to user space via copy_to_user() (3.1/get_pgfaults.c:60)."
Step 2: Enforcing Single-Opener Mutual Exclusion:
"Next, to prevent interleaved reads or concurrent resource contention, I implemented a single-opener access guard inside procfile_open() & procfile_release() (3.1/get_pgfaults.c:20-35). Using an atomic tracking counter (open_count), any second process attempting to open /proc/get_pgfaults while an existing session is active receives an immediate -EBUSY error."
Step 3: Object-Oriented Hierarchy via sysfs (/sys/kernel/get_memstats):
"Then, in Part 3.2, I transitioned to modern kernel telemetry using sysfs. While procfs is traditionally used for freeform diagnostic text streams, sysfs strictly adheres to a 'one value per file' design rule organized around hardware and kernel objects. To reflect this, I created a kernel object under /sys/kernel/ using kobject_init_and_add() (3.2/get_memstats.c:234)."
Step 4: Implementing Granular Show/Store Attribute Callbacks:
"Underneath the mem_stats kobject, I exposed four separate attribute files using struct sysfs_entry (3.2/get_memstats.c:15) and __ATTR:
pid (read/write): Lets user space specify the target process PID with validation (pid_show/store in 3.2/get_memstats.c:34, 51).unit (read/write): Dynamically toggles output units between Bytes, Kilobytes, and Megabytes (unit_show/store in 3.2/get_memstats.c:181, 188).virtmem (read-only): Computes total virtual memory assigned across VMAs (virtmem_show in 3.2/get_memstats.c:114).physmem (read-only): Triggers a live page table walk to calculate exact physical resident pages (physmem_show in 3.2/get_memstats.c:145).
I bound these attributes to an attribute group using ATTRIBUTE_GROUPS(memstats) (3.2/get_memstats.c:212), ensuring atomic registration on load and destruction on unload."Step 5: Clean Teardown and Resource Reclamation:
"Finally, on module exit, I ensured clean teardown by calling proc_remove() (3.1/get_pgfaults.c:89) for procfs and kobject_put() (3.2/get_memstats.c:245) for sysfs. Calling kobject_put decrements the object's reference count, cleanly triggering the release of all child sysfs attribute files and preventing dangling directory nodes in /sys."
| Step | What Was Done | How It Works | Why This Mechanism / Order | Code Reference |
|---|---|---|---|---|
| 1. Procfs Creation | Registered /proc/get_pgfaults |
Uses proc_create with struct proc_ops callback table. |
Exposes system-wide aggregate telemetry via a familiar procfs entry. | 3.1/get_pgfaults.c:68, 76 |
| 2. Concurrency Guard | Implemented open_count guard |
Increments counter on open; rejects concurrent openers with -EBUSY. |
Prevents multiple readers from interleaving buffered stream outputs. | 3.1/get_pgfaults.c:20-35 |
| 3. Sysfs Kobject | Created /sys/kernel/get_memstats |
Anchored kobject under root kernel_kobj. |
Adheres to modern kernel object hierarchy and device model standards. | 3.2/get_memstats.c:234 |
| 4. Attribute Handlers | Defined show and store callbacks |
Uses __ATTR macros to bind read/write functions to attribute files. |
Enforces strict 'one value per file' philosophy, enabling scriptable automation. | 3.2/get_memstats.c:34-212 |
| 5. Subsystem Teardown | Invoked remove_proc_entry & kobject_put |
Cleans up directory nodes and decrements kobject reference counts. | Prevents kernel memory leaks and dangling virtual filesystem pointers. | 3.1/get_pgfaults.c:893.2/get_memstats.c:245 |
/proc and a /sys interface? When would you use one over the other?Answer: They serve distinct architectural roles. We used
/proc/get_pgfaultsfor system-wide streaming telemetry (aggregate page fault counters), where a single read stream dumps an overall metric snapshot. We used/sys/kernel/get_memstatsfor interactive, object-oriented process inspection where user space dynamically sets target PIDs and unit scaling (Bytes/KB/MB) viastorecallbacks, and reads back specific metrics viashowcallbacks. Sysfs strictly enforces the modern Linux device model's "one value per file" philosophy, making it clean and script-friendly for automated monitoring agents.
/proc/get_pgfaults simultaneously?Answer: Reading
/proc/get_pgfaultsformats kernel fault counters into a shared module buffer before copying to user space. If two processes (or two threads) opened and read/proc/get_pgfaultsconcurrently, their read offsets and buffer state interleaved, causing truncated output, corrupted text, or duplicated lines. To solve this without complex dynamic per-client streaming locks, we added an atomic single-opener guard inproc_open: if the file was already open by an active reader, subsequentopen()attempts were immediately rejected with-EBUSY.
rmmod) while a user-space monitoring script has /sys/kernel/get_memstats open?Answer: In Linux sysfs,
kobjectnodes are reference-counted viakref. When user space opens a sysfs attribute file, the VFS takes a reference count on the underlying kobject and increments the module's refcount (THIS_MODULE). If someone executesrmmod, the kernel detects that the module reference count is non-zero and refuses to unload (rmmod: ERROR: Module is in use). Once user space closes all file descriptors, the refcount decrements to zero, allowingkobject_put()to cleanly unlink attribute files and free descriptors without leaving dangling pointers.