Typically, communication systems implement request-reply messaging, or polling. In such models, a program that receives a request will have to send the data available since the last transaction. Such methods sometimes require high bandwidth or they waste polling cycles.
To fulfill the need for interaction, Linux uses so called notification chains. These notifier chains work in a Publish-Subscribe model. This model is more effective when compared to polling or the request-reply model.
For each notification chain there is a passive side (the notified) and an active side (the notifier), as in the so-called publish-and-subscribe model:
- The notified are the subsystems that ask to be notified about the event and that provide a callback function to invoke.
- The notifier is the subsystem that experiences an event and calls the callback function.
struct notifier_block
The elements of the notification chain's list are of type notifier_block:
<include/linux/notifier.h> 50 struct notifier_block { 51 int (*notifier_call) (struct notifier_block *, unsigned long, void *); 52 struct notifier_block *next; 53 int priority; 54 };
- notifier_call - function to execute.
- next - used to link together the elements of the list.
- priority - the priority of the function. Functions with higher priority are executed first. But in practice, almost all registrations leave the priority out of the notifier_block definition, which means it gets the default value of 0 and execution order ends up depending only on the registration order (i.e., it is a semirandom order).
Types of Notifier Chains
Notifier chains are broadly classified based on the context in which they are executed and the lock/protect mechanism of the calling chain. Based on the need of the module, the notifiers can be executed in the process context or interrupt/atomic context. Thus, notifier chains are classified into four types:
Atomic Notifier Chains
As the name indicates, this notifier chain is executed in interrupt or atomic context. Normally, events that are time critical use this notifier. This also means it is a non-blockable call. Linux modules use atomic notifier chains to inform watchdog timers or message handlers.
<kernel/notifier.c> 96 int atomic_notifier_chain_register(struct atomic_notifier_head *nh, 97 struct notifier_block *n) 98 { . 102 spin_lock_irqsave(&nh->lock, flags); 103 ret = notifier_chain_register(&nh->head, n); 104 spin_unlock_irqrestore(&nh->lock, flags); 105 return ret; 106 } 107 EXPORT_SYMBOL_GPL(atomic_notifier_chain_register); . 118 int atomic_notifier_chain_unregister(struct atomic_notifier_head *nh, 119 struct notifier_block *n) 120 { . 124 spin_lock_irqsave(&nh->lock, flags); 125 ret = notifier_chain_unregister(&nh->head, n); 126 spin_unlock_irqrestore(&nh->lock, flags); 127 synchronize_rcu(); 128 return ret; 129 } 130 EXPORT_SYMBOL_GPL(atomic_notifier_chain_unregister);Check the PART-2
No comments :
Post a Comment
Your comments are moderated