linux-内核通知链相关(关机、重启通知,kernel-5.10为例)

还在修改中,欢迎批评指正

1. 什么是通知链?

通知链是 Linux 内核的一个基础组件,各种内核组件 (包括设备驱动、文件组件、网络组件等) 可以对向其感兴趣的一些内核事件进行注册,当该事件发生时,这些模块或者组件当初注册的回调函数将会被调用。

哪些模块提供了notify注册函数,通知哪些事件,哪些模块关系这些事件并注册了回调函数,这些应该是我们比较关系的。

2. 简单了解通知链的内部实现

通知链的实现机制:

通过链表的形式,内核将那些注册进来的关注同类事件的节点构成一个链表,当某一特定的内核事件发生时,事件所属的内核组件负责遍历该通知链上的所有节点,调用节点上的回调函数。

3 以 reboot restart 通知链为例

关机及重启所在文件 kernel/reboot.c

3.1 嵌入式linux系统关机或重启命令下发执行逻辑及硬件相关动作简介

待补充:上层下发关机或者重启指令后,上层先完成卸载关闭(关闭app保存处理缓存数据等),然后下发至framwork层,这个层完成相关动作后,下发至linux-kernel底层,通知到reboot.c相关函数,在这里遍历链表,依次执行回调函数(这里各个模块的动作都是寄存器硬件相关的,涉及上下电等动作,可能会相互影响)。

3.2 注册rebbot通知链

reboot通知注册函数,关心关机重启动作的模块需要调用该函数完成注册。

blocking_notifier_chain_register() 将通知节点加入 module_notify_list 管理的链表。在向一个通知链中加入新节点时,系统会把各节点的 priority 作为一个排序关键字进行简单排序,优先级越高的节点越靠近头节点,当有事件发生时,最先被通知:

linux-内核通知链相关(关机、重启通知,kernel-5.10为例)_第1张图片

例如:

ddata->reboot_notifier.notifier_call = xxx_set_xxx;//具体回调函数,当发生关机重启通知时会调用到

ddata->reboot_notifier.priority = 255;//调用优先级,其他模块也有关心关机动作的,优先级高,可以先调用

register_reboot_notifier(&ddata->reboot_notifier);

看看如何将注册的回调函数对应节点插入链表的

linux-内核通知链相关(关机、重启通知,kernel-5.10为例)_第2张图片

当有模块注册reboot通知链时,notifier_chain_register将上一个链表节点指针赋值到自己的notifier_block ->nl,再将自己的赋值给下一个链表节点。

linux-内核通知链相关(关机、重启通知,kernel-5.10为例)_第3张图片

static int xxx_set_xxx(struct notifier_block *reboot_notifier, unsigned long mode(具体通知类型), void *nouse)

关机重启四种notify类型

#define SYS_DOWN 0x0001 /* Notify of system down */

#define SYS_RESTART SYS_DOWN

#define SYS_HALT 0x0002 /* Notify of system halt */

#define SYS_POWER_OFF 0x0003 /* Notify of system power off */

3.3 当关机或重启事件发生时,是怎么具体通知相关节点的

reboot.c相关函数调用

linux-内核通知链相关(关机、重启通知,kernel-5.10为例)_第4张图片

使用 blocking_notifier_call_chain() 通知所有链表节点:

linux-内核通知链相关(关机、重启通知,kernel-5.10为例)_第5张图片
linux-内核通知链相关(关机、重启通知,kernel-5.10为例)_第6张图片

遍历所有节点,依次调用关心关机或重启事件的模块注册的回调函数

linux-内核通知链相关(关机、重启通知,kernel-5.10为例)_第7张图片

4 其他类型的通知方式

待补充

reboot及restart的通知就发生在reboot.c中,但是这里有另外一个通知类型不太一样,

register_adapter_device_notifier是注册函数,有一个回调函数notify_adapter_event注册了这个通知链。

linux-内核通知链相关(关机、重启通知,kernel-5.10为例)_第8张图片
linux-内核通知链相关(关机、重启通知,kernel-5.10为例)_第9张图片

这里类似自定义的通知类型,不在adapter_class.c里

如何寻找对应通知函数

根据第一个参数srcu_notifier_head *nh,来寻找通知函数,这里是struct adapter_device *adapter_dev。所有注册函数以及通知函数都需要用到adapter_device这个类型的链表头

linux-内核通知链相关(关机、重启通知,kernel-5.10为例)_第10张图片

5 当事件发生时,通知函数是如何运行的

待补充

参考链接及文章:

1,Linux内核品读 / 基础组件 / 通知链快速入门https://zhuanlan.zhihu.com/p/233944118#:~:text=blocking_notifier_call_chain%20%28%29%20%E5%B0%86%E4%BD%BF%E9%80%9A%E7%9F%A5%E9%93%BE%20module_notify_list%20%E4%B8%8A%E7%9A%84%E5%90%84%E8%8A%82%E7%82%B9%E7%9A%84%E5%9B%9E%E8%B0%83%E5%87%BD%E6%95%B0%E5%9D%87%E8%A2%AB%E8%B0%83%E7%94%A8%EF%BC%8C,%E5%85%B6%E5%8E%9F%E7%90%86%E5%B0%B1%E6%98%AF%E9%81%8D%E5%8E%86%20module_notify_list%20%E4%B8%8A%E7%9A%84%E5%90%84%E8%8A%82%E7%82%B9%EF%BC%8C%E4%BE%9D%E6%AC%A1%E8%B0%83%E7%94%A8%E5%90%84%E8%8A%82%E7%82%B9%E4%B8%8A%E7%9A%84%20notifier_call%20%28%29%20%3A

你可能感兴趣的:(linux)