Skip to content

Day70 - Notifier Chain

Objective

Learn the Linux kernel notifier chain framework and understand how kernel subsystems propagate events to multiple subscribers.

Topics covered:

  • notifier_block
  • callback registration
  • callback unregistration
  • priority ordering
  • NOTIFY_STOP
  • event payload delivery
  • blocking notifier chain
  • atomic notifier chain

Lab Environment

Platform:

Raspberry Pi 5
Linux Kernel 6.6.x

Module:

notifier_demo

Directory:

d70-notifier-chain

Lab1 - Basic Blocking Notifier

Goal

Create a blocking notifier chain and register multiple subscribers.


APIs

BLOCKING_NOTIFIER_HEAD()

blocking_notifier_chain_register()

blocking_notifier_chain_unregister()

blocking_notifier_call_chain()

Test Flow

Register CLIENT-A
Register CLIENT-B
Register CLIENT-C

Trigger EVENT_START

Trigger EVENT_STOP

Result

CLIENT-A event=1
CLIENT-B event=1
CLIENT-C event=1

CLIENT-A event=2
CLIENT-B event=2
CLIENT-C event=2

Verified:

  • callback registration works
  • callback execution works
  • callback unregistration works

Lab2 - Priority Ordering

Goal

Verify notifier execution order.


Configuration

CLIENT-B priority=100
CLIENT-C priority=50
CLIENT-A priority=0

Test Flow

Trigger EVENT_START

Result

CLIENT-B
CLIENT-C
CLIENT-A

Verified:

Execution order follows priority.

and not registration order.


Lab3 - NOTIFY_STOP

Goal

Verify propagation control.


Configuration

CLIENT-C returns:

NOTIFY_STOP

Test Flow

Trigger EVENT_START

Result

CLIENT-B
CLIENT-C

CLIENT-A was not executed.

Verified:

NOTIFY_STOP prevents further callback execution.

Lab4 - Event Payload

Goal

Pass event-specific data through the notifier chain.


Event Structure

struct demo_event_data {
    int id;
    int value;
    const char *msg;
};

Event Examples

START:

id=1
value=100
msg=system start

STOP:

id=2
value=0
msg=system stop

Result

[CLIENT-B] id=1 value=100 msg=system start
[CLIENT-C] id=1 value=100 msg=system start
[CLIENT-A] id=1 value=100 msg=system start

Verified:

void *data carries event payload.

Lab5 - Blocking vs Atomic Notifier

Goal

Compare blocking and atomic notifier chains.


Chains

Blocking:

BLOCKING_NOTIFIER_HEAD()

Atomic:

ATOMIC_NOTIFIER_HEAD()

Registration APIs

Blocking:

blocking_notifier_chain_register()

Atomic:

atomic_notifier_chain_register()

Callback Observation

in_interrupt()

preempt_count()

Result

in_interrupt=0
preempt_count=0

for both chains when called from module_init().


Key Observation

Atomic notifier does not imply:

Interrupt Context

Instead:

Atomic-safe callback required

Callback implementation must avoid:

msleep()
mutex_lock()
schedule()
wait_for_completion()

when atomic execution is possible.


Lab6 - Dynamic Unregister

Goal

Verify runtime subscriber removal.


Initial Chain

B -> C -> A

Step 1

Unregister:

CLIENT-C

Result:

B -> A

Step 2

Unregister:

CLIENT-B

Result:

A

Result

CLIENT-C no longer receives events
CLIENT-B no longer receives events

Verified:

Callbacks are removed immediately from future event delivery.

Key Findings

Notifier Chain

Provides:

One publisher
Multiple subscribers

without tight coupling.


Priority

Execution order:

Higher priority first

Event Payload

Event context is delivered through:

void *data

Propagation Control

Callbacks may stop propagation using:

NOTIFY_STOP

Dynamic Registration

Subscribers may be:

Registered
Unregistered
Re-registered

at runtime.


Summary

This lab demonstrated the core functionality of the Linux kernel notifier chain framework.

Covered:

  • callback registration
  • callback unregistration
  • priority ordering
  • propagation control
  • event payload delivery
  • blocking notifier chains
  • atomic notifier chains

The notifier framework is commonly used by kernel subsystems to broadcast events to multiple listeners while keeping publishers and subscribers loosely coupled.