Skip to content

Notifier Chain API Reference

Overview

Notifier Chain provides a generic event notification mechanism inside the Linux kernel.

It allows one subsystem to publish events while multiple subscribers register callback handlers independently.

Notifier chains are commonly used for:

  • CPU frequency transitions
  • Reboot notifications
  • Power management events
  • Network device state changes
  • USB device events

Core Structure

struct notifier_block

Definition

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

Purpose

Represents a subscriber entry within a notifier chain.

Members

Member Description
notifier_call Callback function
next Next notifier block
priority Callback priority

Callback Prototype

notifier_call

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

Return Values

NOTIFY_OK

Continue propagation.


NOTIFY_DONE

Event ignored.


NOTIFY_STOP

Stop further callback execution.


NOTIFY_BAD

Event handling failed.


Blocking Notifier

BLOCKING_NOTIFIER_HEAD()

Prototype

BLOCKING_NOTIFIER_HEAD(name);

Purpose

Declare and initialize a blocking notifier chain.

Characteristics

Process Context
Sleep Allowed

Example

static BLOCKING_NOTIFIER_HEAD(demo_chain);

blocking_notifier_chain_register()

Prototype

int blocking_notifier_chain_register(
        struct blocking_notifier_head *nh,
        struct notifier_block *nb);

Purpose

Register a notifier callback.

Parameters

Parameter Description
nh Notifier chain
nb Subscriber

Return Value

0

Success.

Negative error code on failure.


blocking_notifier_chain_unregister()

Prototype

int blocking_notifier_chain_unregister(
        struct blocking_notifier_head *nh,
        struct notifier_block *nb);

Purpose

Remove a notifier callback from a chain.

Parameters

Parameter Description
nh Notifier chain
nb Subscriber

blocking_notifier_call_chain()

Prototype

int blocking_notifier_call_chain(
        struct blocking_notifier_head *nh,
        unsigned long action,
        void *data);

Purpose

Broadcast an event to all registered subscribers.

Parameters

Parameter Description
nh Notifier chain
action Event identifier
data Event payload

Example

blocking_notifier_call_chain(
        &demo_chain,
        EVENT_START,
        &event);

Atomic Notifier

ATOMIC_NOTIFIER_HEAD()

Prototype

ATOMIC_NOTIFIER_HEAD(name);

Purpose

Declare and initialize an atomic notifier chain.

Characteristics

Atomic-safe callback required
Sleep Not Allowed

Example

static ATOMIC_NOTIFIER_HEAD(demo_chain);

atomic_notifier_chain_register()

Prototype

int atomic_notifier_chain_register(
        struct atomic_notifier_head *nh,
        struct notifier_block *nb);

Purpose

Register an atomic notifier callback.


atomic_notifier_chain_unregister()

Prototype

int atomic_notifier_chain_unregister(
        struct atomic_notifier_head *nh,
        struct notifier_block *nb);

Purpose

Remove an atomic notifier callback.


atomic_notifier_call_chain()

Prototype

int atomic_notifier_call_chain(
        struct atomic_notifier_head *nh,
        unsigned long action,
        void *data);

Purpose

Broadcast an event through an atomic notifier chain.

Notes

Callbacks must not sleep.

Avoid:

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

Raw Notifier

RAW_NOTIFIER_HEAD()

Prototype

RAW_NOTIFIER_HEAD(name);

Purpose

Declare a notifier chain without internal synchronization.

Characteristics

No internal locking
Caller manages synchronization

Typical Synchronization

mutex
spinlock
rwlock
RCU

Priority Ordering

Notifier callbacks are executed in descending priority order.

Example:

Priority 100
Priority 50
Priority 0

Execution order:

100 → 50 → 0

Priority is independent of registration order.


Event Payload

Event-specific information is passed through:

void *data

Example:

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

Publisher:

blocking_notifier_call_chain(
        &demo_chain,
        EVENT_START,
        &event);

Subscriber:

struct demo_event_data *event = data;

Common Pitfalls

Using Registration Order as Execution Order

Incorrect assumption:

First registered
First executed

Actual behavior:

Higher priority executes first

Sleeping in Atomic Notifier Callbacks

Incorrect:

msleep(100);
mutex_lock(&lock);

Atomic notifier callbacks must remain atomic-safe.


Reusing One notifier_block Across Multiple Chains

Avoid:

One notifier_block
        
Multiple chains

Recommended:

One notifier_block
Per chain

Related Notes


Related Topics


Related Labs

  • Day70 - Notifier Chain