美文网首页
Linux内核notifier机制

Linux内核notifier机制

作者: 小田BSP | 来源:发表于2021-07-19 23:22 被阅读0次

    Linux内核使用通知链的机制在内核各子系统之间进行事件通知(注:无法用于内核态和用户态之间的事件通知)。

    一、通知链介绍

    在文件include/linux/notifier.h中,可以查看Linux内核定义的四种通知链类型:

    通知链类型 初始化 注册函数 通知函数
    Atomic notifier chains(原子通知链) ATOMIC_NOTIFIER_HEAD() atomic_notifier_chain_register()/
    atomic_notifier_chain_unregister()
    atomic_notifier_call_chain()
    Blocking notifier chains(可阻塞通知链) BLOCKING_NOTIFIER_HEAD() blocking_notifier_chain_register()/
    blocking_notifier_chain_unregister
    blocking_notifier_call_chain()
    Raw notifier chains(原始通知链) RAW_NOTIFIER_HEAD() raw_notifier_chain_register()/<br />raw_notifier_chain_unregister() raw_notifier_call_chain()
    SRCU notifier chains(SRCU通知链) srcu_init_notifier_head() srcu_notifier_chain_register()/<br />srcu_notifier_chain_unregister srcu_notifier_call_chain()

    说明:

    1、原子通知链:通知链的回调函数在中断或原子上下文中运行,不允许阻塞。

    2、可阻塞通知链:通知链的回调函数在进程上下文中运行,允许堵塞。

    3、原始通知链:对通知链的回调函数没有限制,调用者维护锁和保护。

    4、SRCU通知链:阻塞通知链的一个变体。

    二、通知链应用

    以系统睡眠唤醒为例,介绍可阻塞通知链的使用。

    ## kernel/power/main.c
    ## 1.初始化通知链pm_chain_head
    static BLOCKING_NOTIFIER_HEAD(pm_chain_head);
    
    ## kernel/power/wakeup_reason.c
    ## 2.注册通知链
    ## 2.1通知链回调函数实现
    static int wakeup_reason_pm_event(struct notifier_block *notifier,
            unsigned long pm_event, void *unused)
    {
        switch (pm_event) {
        case PM_SUSPEND_PREPARE:
            ...
        }
    }
    
    static struct notifier_block wakeup_reason_pm_notifier_block = {
        .notifier_call = wakeup_reason_pm_event,
    };
    
    ## 2.2注册通知链
    int __init wakeup_reason_init(void)
    {
        ...
        retval = register_pm_notifier(&wakeup_reason_pm_notifier_block);
        ....
    }
    
    int register_pm_notifier(struct notifier_block *nb)
    {
        return blocking_notifier_chain_register(&pm_chain_head, nb);
    }
    
    ## kernel/power/suspend.c
    ## 3.通知
    static int suspend_prepare(suspend_state_t state)
    {
        ...
        ## 3.1 发送PM_SUSPEND_PREPARE通知时,调用.notifier_call()对应的wakeup_reason_pm_event()函数处理。
        error = __pm_notifier_call_chain(PM_SUSPEND_PREPARE, -1, &nr_calls);
        ...
    }
    
    int __pm_notifier_call_chain(unsigned long val, int nr_to_call, int *nr_calls)
    {
        ...
        ret = __blocking_notifier_call_chain(&pm_chain_head, val, NULL,
                            nr_to_call, nr_calls);
        ...
    }
    

    相关文章

      网友评论

          本文标题:Linux内核notifier机制

          本文链接:https://www.haomeiwen.com/subject/erukmltx.html