Deep understanding of Linux Network Technology Insider--notification core notification bracelet

Source: Internet
Author: User
Tags mutex what callback what callback function

Why should I have a kernel notification bracelet:Linux is made up of multiple interdependent subsystems. Some of these subsystems may need to be interested in some of the events of other subsystems. This requires some communication mechanisms between the subsystems to achieve this function.     before touching notification chain, we may think of polling to implement, when the event occurs, the subsystem polls all other subsystems to see if there is any interest in this event, there is no need to execute the sub-function.
If (subsystem_x_enabled) {do_something_1}if (subsystem_y_enabled) {do_something_2}if (subsystem_z_enabled) {Do_ Something_3} .....


    This approach seems to satisfy our needs, but the code is too complex to make each subsystem very large. andNotification chain has greatly improved these deficiencies.
Notification Chain Fundamentals
    Notification Chain is a publish-subscribe model that notifies all subsystems interested in this event when an event occurs in a subsystem in order to execute a response function. In this model, the subsystem in which the event occurs is the active side, and the subsystem that is interested in the event is the passive side. (This article also makes the passive end the notified side).  When an event occurs, the subsystem that detects or generates the event is notified by the active party as the passive party by a notification functionthe Subscriber (the subsystem of interest for this event). There is an additional requirement that the subscribing party will provide the callback function tofor the publisher to invoke, of course, what callback function is provided is entirely up to the subscriber.
notification Bracelet Model diagram:

Notification Chain source code parsing

structure:
Notification block struct Notifier_block{int (*notifier_call) (struct Notifier_block *self, unsigned long, void *);//callback function struct Notifier_block *next; int priority;    The priority of the registration, the user specifies, the higher the priority of the callback function, the earlier the execution};

Definition of the notification bracelet there are three notification bracelets in the Linux kernel:
Atom Notification bracelet struct Atomic_notifier_head {    spinlock_t lock;    struct Notifier_block __rcu *head;}; Block notification bracelet struct Blocking_notifier_head {    struct rw_semaphore rwsem;    struct Notifier_block __rcu *head;}; Original notification bracelet struct Raw_notifier_head {    struct notifier_block __rcu *head;};/ Variant struct Srcu_notifier_head {    struct mutex mutex)/can block notification bracelet;    struct srcu_struct srcu;    struct Notifier_block __rcu *head;};


When a notification bracelet needs to be defined, it is defined with Xxx_notifier_head (name), with Raw_notifier_head as an example:
Static Raw_notifier_head (Netdev_chain);

Track Raw_notifier_head,
#define ATOMIC_NOTIFIER_HEAD (name)                  struct Atomic_notifier_head name =                  atomic_notifier_init (name) #define Blocking_notifier_head (name)                    struct Blocking_notifier_head name =                    blocking_notifier_init (name) #define Raw_ Notifier_head (name)                     struct Raw_notifier_head name =                     


Go on
#define ATOMIC_NOTIFIER_INIT (name) {                        . Lock = __spin_lock_unlocked (Name.lock),            . Head = NULL} #define Blocking_ Notifier_init (name) {                      . Rwsem = __rwsem_initializer ((name). Rwsem),         . Head = NULL} #define RAW_NOTIFIER_INIT ( Name) {                       . Head = NULL}/* srcu_notifier_heads cannot be initialized statically *


This completes the definition and initialization of a notification bracelet.
There are a lot of notification chain in the Linux kernel, and there are three commonNetdev_chain,inetaddr_chain,inet6addr_chain. Combinedstruct Notifier_block, a queue with a callback function on each chain (linked list)Notifier_call, then how are these callback functions (notification notification blocks) used and appropriate for invocation? first we are at the beginning of the notice bracelet, notice that the bracelet is only linked to the head, no otherNotifier_block block, this list will focus on some events (such asNetdev_chain will be concerned about the removal of equipment, and so on, the specific following will be more clearly described. If a subsystem is interested in the time this chain is concerned about, it registers aNotifier_block to the linked list. the registration and logoff of Notifier_block blocks are implemented in the following form:
int Notifier_chain_register (struct notifier_block **list, struct notifier_block *n) int Notifier_chain_unregister ( struct Notifier_block **nl, struct notifier_block *n)


These two are encapsulation functions, and the specific notification chain encapsulates both functions, defining their own registration and logoff functions. Taking Netdev_chain as an example, the encapsulation process:
int register_netdevice_notifier (struct notifier_block *nb) {    raw_notifier_chain_register (&netdev_chain, NB) ; }int raw_notifier_chain_register (struct raw_notifier_head *nh,                                                                    struct notifier_block *n) {           return notifier_ Chain_register (&nh->head, n);}      


When a subsystem needs to focus on the device's change information, it will process the function notifier_call (itself) as a notification bracelet for notifier_block registration.
    When an event occurs, the notification bracelet execution processWhen an event occurs, the time invokes the callback function in each notification block in the NOTIFIER_CALL_CHAIN traversal notification chain, and the callback function determines whether to perform the processing.
static int __kprobes notifier_call_chain (struct notifier_block **nl, unsigned long val, void *v,                                                                                                                            int nr_to_call, int *nr_calls) {    int ret = Notify_done;     struct Notifier_block *nb, *next_nb;      NB = Rcu_dereference_raw (*NL);  while (NB && nr_to_call) {next_nb = Rcu_dereference_raw (Nb->next); #ifdef Config_debug_notifiers if (Unlikely (!func_ptr_is_kernel_text (Nb->notifier_call))) {WARN (1, "I            Nvalid notifier called! ");            NB = NEXT_NB;        Continue         } #endif ret = Nb->notifier_call (nb, Val, v);         if (nr_calls) (*nr_calls) + +;        if (ret & notify_stop_mask) = = Notify_stop_mask) break;        NB = NEXT_NB;    nr_to_call--; } return ret;}



    
    






























Deep understanding of Linux Network Technology Insider--notification core notification bracelet

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.