The Notification System (2.6.5)

References:

Event notification is important when a kernel component needs to be made aware that something happened without having to inquire about it repeatedly. Event notification is like signals for user programs. Unlike signals, the component has to sign up (register) for the notification, and is thus notified only of the events it has registered for. There is no default notifier for events, as default handlers for signals.
A component signs up for notification by registering a notifier_block with a notifier_chain. The notifier block must contain the callback function to call when the event occurs. This function is executed in the context that triggered the notification on the chain [... ???]
The header file include/linux/notifier.h defines the struct notifier_block,

A chain of notification is a list of notifier blocks. The notification system is implemented in kernel/sys.c and exports three API,


The first two take a pointer to a list of notifier_block's and a pointer to the notifier_block. The last one takes a pointer to a list of notifier_block's, a unsigned long event code, and a void *. The callback is usually a (big) switch on the event code, and should return NOTIFY_DONE to indicate success. The function notifier_call_chain invokes the callbacks of the registered notifier_block, passing them the notifier_block itself, the event code, and the void * pointer. It stops if a callback return has the NOTIFY_STOP_MASK bit active.

The kernel lists of notifier_block's have grown are


The cpufreq_notifier is called by cpufreq_set() and cpufrq_get(). [where did it go?]

Several driver and network code use lists of notifier_block. net/core/dev.c has a netdev_chain list of notifier_block's, and net/ipv4/devinet.c has a inetaddr_chain list.

The table below summarizes the cases when the netdev_chain is notified.
  event code pointer
a net_device changes state (dev_set_allmulti()) NETDEV_CHANGE net_device
a net_device changes from "down" to "up" (dev_oopen()) NETDEV_UP net_device
a net_device is about to go "down" (dev_close) NETDEV_GOING_DOWN net_device
a net_device has gone "down" (dev_close) NETDEV_DOWN net_device
a net_device changes MTU (dev_ifsioc() with command SIOCSIFMTU) NETDEV_CHANGEMTU net_device
a net_device changes MAC address (dev_ifsioc() with command SIOCGIFHWADDR) or broadcst address (dev_ifsioc() with SIOCSIFHWBROADCAST) NETDEV_CHANGEADDR net_device
a net_device changes name (dev_ifsioc() with command SIOCSIFNAME) NETDEV_CHANGENAME net_device
a net_device registers with the net core (register_netdevice) NETDEV_REGISTER net_device
a net_device unregisters from the net core (unregister_netdevice) NETDEV_UNREGISTER net_device

For example net/ipv4 has

Exercise

Write a driver that register with the module_notifier_list and when a new module is insmod-ed prints a message.
Example and Makefile.


Marco Corvi - 2003, 2005