Skip to content

Notifier Chain Framework

Overview

Notifier Chain is a generic event notification framework used throughout the Linux kernel.

It allows one subsystem to broadcast events to multiple interested subscribers without creating direct dependencies between components.

The framework provides a loosely coupled mechanism for event propagation.


Why Notifier Chain Exists

Without a notifier chain:

Publisher
 ├─ Callback A
 ├─ Callback B
 ├─ Callback C
 └─ Callback D

The publisher must know every consumer.

This creates strong coupling between subsystems.


Using a notifier chain:

Publisher
Notifier Chain
 ┌──┼──┬──┐
 ▼  ▼  ▼  ▼
A  B  C  D

The publisher only knows the notifier chain.

Subscribers register themselves independently.


Core Components

notifier_block

A notifier callback is represented by:

struct notifier_block {
    notifier_fn_t notifier_call;
    struct notifier_block *next;
    int priority;
};

Fields:

Field Description
notifier_call Callback function
next Next notifier in chain
priority Execution priority

Callback Prototype

int callback(struct notifier_block *nb,
             unsigned long action,
             void *data);

Parameters:

Parameter Description
nb Current notifier block
action Event identifier
data Event payload

Event Propagation

Publisher:

blocking_notifier_call_chain(
        &chain,
        action,
        data);

Kernel internally:

Walk notifier list
Invoke callback
Invoke callback
Invoke callback

Every registered subscriber receives the event.


Priority Ordering

Notifier callbacks are executed according to:

Higher priority first

Example:

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

Execution order:

CLIENT-B
CLIENT-C
CLIENT-A

Priority determines ordering regardless of registration time.


Event Payload

Notifier chains support event-specific payloads.

Example:

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

Publisher:

blocking_notifier_call_chain(
        &chain,
        EVENT_START,
        &event);

Subscriber:

struct demo_event_data *event = data;

This allows callbacks to receive additional context about the event.


Propagation Control

Callback return values influence chain execution.

Common values:

NOTIFY_OK
NOTIFY_DONE
NOTIFY_STOP
NOTIFY_BAD

NOTIFY_OK

return NOTIFY_OK;

Continue executing remaining callbacks.


NOTIFY_STOP

return NOTIFY_STOP;

Stop further event propagation.

Example:

CLIENT-B
CLIENT-C
STOP

CLIENT-A is not executed.


Blocking Notifier

Definition:

BLOCKING_NOTIFIER_HEAD(chain);

Registration:

blocking_notifier_chain_register()

Event propagation:

blocking_notifier_call_chain()

Characteristics:

Process Context
Sleep Allowed
Protected by rwsem

Suitable for:

CPUFreq
Power Management
Reboot Events

Atomic Notifier

Definition:

ATOMIC_NOTIFIER_HEAD(chain);

Registration:

atomic_notifier_chain_register()

Event propagation:

atomic_notifier_call_chain()

Characteristics:

Atomic-safe callbacks required
Sleep Not Allowed
Protected by spinlock

Typical callback restrictions:

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

Important Clarification

Atomic notifier does not guarantee execution inside interrupt context.

Instead:

Callback must be safe if called from atomic context.

Raw Notifier

Definition:

RAW_NOTIFIER_HEAD(chain);

Characteristics:

No internal locking
No synchronization
Highest flexibility

Users must provide their own synchronization.

Examples:

mutex
spinlock
rwlock
RCU

Dynamic Registration

Subscribers may join or leave at runtime.

Register:

*_notifier_chain_register()

Unregister:

*_notifier_chain_unregister()

The notifier chain immediately reflects the changes.


Internal Structure

Conceptually:

Notifier Head
  NB(100)
   NB(50)
    NB(0)
    NULL

The framework internally maintains a priority-ordered linked list.


Comparison with Other Synchronization Mechanisms

Wait Queue

Purpose:

Condition-based waiting

Relationship:

Wait until condition becomes true

Completion

Purpose:

Operation completion synchronization

Relationship:

One waiter
One completer

Workqueue

Purpose:

Deferred execution

Relationship:

Execute work later in process context

Notifier Chain

Purpose:

Event propagation

Relationship:

One publisher
Multiple subscribers

Real Kernel Examples

Notifier chains are widely used throughout the kernel.

Examples:

CPUFreq

Frequency transition events

Reboot Notifier

System reboot
System shutdown

Power Management

Suspend
Resume

Network Subsystems

Device up
Device down
Address changes

USB Subsystems

Device attach
Device remove

Summary

Notifier Chain is the Linux kernel's generic event broadcast framework.

Key features:

  • Multiple subscribers
  • Dynamic registration
  • Priority ordering
  • Event payload delivery
  • Propagation control
  • Blocking, Atomic, and Raw variants

It is one of the fundamental mechanisms used by kernel subsystems to propagate events while maintaining loose coupling between components.