Linux內核事件通知鏈(notifier chain)

Linux內核基礎--事件通知鏈(notifier chain)android

簡介:

內核許多子系統之間關聯緊密,所以在一個子系統發生或者檢測到的事件信息極可能對其餘子系統來講也是有價值的。爲了知足其餘子系統對這些事件信息的需求,即在某個子系統內發生或檢測到事件時,其餘對此感興趣的子系統也能知道事件的發生,內核提供了notification chain機制。ide

注意:notification chain適用於內核子系統之間的信息傳遞,不涉及用戶態。函數

Notification chain使用發佈-訂閱模型(publish-and-subscribemodel):在事件發生時,檢測或產生事件的子系統做爲主動一方經過通知函數來告知做爲被動一方的訂閱者(對此事件感興趣的子系統)。這裏有個額外要求,訂閱一方要提供callback函數以供發佈方調用,固然,提供什麼樣的callback函數徹底由訂閱方決定。atom

訂閱者必須知道其餘子系統提供了哪些事件通知支持,以選擇能夠訂閱的事件通知;固然,訂閱者自己也是一個子系統,所以也具備信息發佈功能,所以它也要清楚本系統內哪些事件對其餘子系統是有價值的,即有哪些本系統內的事件發生時須要通知訂閱者,可是子系統對誰訂閱了事件通知以及爲何要訂閱一無所知。code

根據展訊sc9820e display代碼分析實例

核驅動使用的接口:blog

Notifier.c (kernel)     16704       2018/10/12

Atomic notifier chains: chains callback run ininterrupt/atomic context.callouts are not allowed to block

Blocking notifier chains: Chain callbacks run in processcontext.Callouts are allowed to block.

在sc9820e android顯示子系統中有三個驅動(對應三個module):顯示控制器(Sprd_dispc.c),spi(Sprd_spi_intf.c),顯示屏(Sprd_panel.c)。驅動模塊之間經過notifier chain進行通知,執行相應的回調函數。接口

 

一、接口:註冊,發送通知

static ATOMIC_NOTIFIER_HEAD(vsync_notifier_list);
static BLOCKING_NOTIFIER_HEAD(disp_notifier_list);
 
int vsync_notifier_register(struct notifier_block *nb)
{
    return atomic_notifier_chain_register(&vsync_notifier_list, nb);
}
EXPORT_SYMBOL(vsync_notifier_register);
 
int vsync_notifier_unregister(struct notifier_block *nb)
{
    return atomic_notifier_chain_unregister(&vsync_notifier_list, nb);
}
EXPORT_SYMBOL(vsync_notifier_unregister);
 
int vsync_notifier_call_chain(unsigned long val, void *v)
{
    return atomic_notifier_call_chain(&vsync_notifier_list, val, v);
}
EXPORT_SYMBOL(vsync_notifier_call_chain);
 
 
int disp_notifier_register(struct notifier_block *nb)
{
    return blocking_notifier_chain_register(&disp_notifier_list, nb);
}
EXPORT_SYMBOL(disp_notifier_register);
 
int disp_notifier_unregister(struct notifier_block *nb)
{
    return blocking_notifier_chain_unregister(&disp_notifier_list, nb);
}
EXPORT_SYMBOL(disp_notifier_unregister);
 
int disp_notifier_call_chain(unsigned long val, void *v)
{
    return blocking_notifier_call_chain(&disp_notifier_list, val, v);
}
EXPORT_SYMBOL(disp_notifier_call_chain);

二、回調函數

好比,在顯示控制器驅動(Sprd_dispc.c (drivers\video\adf\sprd\drv) 27234 2018/10/12)註冊了:事件

image

在spi驅動中Sprd_spi_intf.c (drivers\video\adf\sprd\drv) 13037 2018/10/12:回調函數

image

三、發送通知

在Sprd_panel.c (drivers\video\adf\sprd\drv) 20403 2018/10/12 顯示屏驅動中:io

image

總結:

  1. 聲明struct notifier_block結構

  2. 編寫notifier_call函數

  3. 調用特定的事件通知鏈的註冊函數,將notifier_block註冊到通知鏈中

相關文章
相關標籤/搜索