Arm-Linux子系統的互相Notify

江湖評談發表於2023-02-11

前言:

Linux下面不同的子系統一個個的組成了整個系統的執行環節,為了讓這些子系統能夠互相通訊,有一種叫做:notify chain(通知鏈)的東西。本篇看下。



概括

所謂通知鏈,有通知,就有執行的地方。比如A子系統通知B子系統,麻煩你幫我執行一件事情。這時候,A子系統就會通知B子系統,把需要執行的事情資訊同時傳遞給B子系統,讓其幫助執行。

這個過程,首先是需要有執行的事情,所以就需要註冊。當註冊好了之後,A子系統通知B子系統,B子系統就會找到註冊的那個事情進行執行。

這裡以原子通知鏈(Atomic notifier chains)為例,它分別由註冊通知鏈,解除安裝通知鏈,以及呼叫通知鏈三種函式:

1. int atomic_notifier_chain_register(struct atomic_notifier_head *nh, struct notifier_block *n);  
2. int atomic_notifier_chain_unregister(struct atomic_notifier_head *nh, struct notifier_block *n);  
3. int atomic_notifier_call_chain(struct atomic_notifier_head *nh, unsigned long val, void *v);

還以上面的為例,假如A子系統需要通知B子系統你幫我完成一個事情。那麼B子系統首先需要註冊一個這個事情,透過函式:atomic_notifier_chain_register來完成。

當A子系統需要通知B子系統執行的時候,A子系統會呼叫atomic_notifier_call_chain來通知B子系統,你該做事了。

當A子系統不需要B子系統為它做事的時候,可以解除安裝掉這件事情:atomic_notifier_chain_unregister。

為什麼會有解除安裝這個函式,因為所有的做事情的函式都在一個連結串列裡面,當A子系統通知B子系統做事的時候,有可能會查詢整個連結串列。當成百上千的子系統相互註冊的時候,連結串列非常龐大,解除安裝這些事情(函式回撥),可以很好的提高效能。




elf入口

當Arm32呼叫使用者態的C Main的時候,堆疊裡面的ret_from_fork就是透過原子呼叫鏈來執行的。

thread #1, stop reason = breakpoint 84.1
frame #0: 0x8010011c vmlinux`ret_from_fork at entry-common.S:142
frame #1: 0x801468b8 vmlinux`atomic_notifier_call_chain [inlined] __rcu_read_unlock at rcupdate.h:74:2
frame #2: 0x801468b4 vmlinux`atomic_notifier_call_chain [inlined] rcu_read_unlock at rcupdate.h:719:2
frame #3: 0x801468b4 vmlinux`atomic_notifier_call_chain(nh=<unavailable>, val=<unavailable>, v=<unavailable>) at notifier.c:199:2

另外一個需要注意的是Arm32的elf入口是透過讀取記憶體異常的中斷處理程式來呼叫使用者態Glibc的_start函式入口。
而X64則是透過缺頁異常來呼叫使用者態Glibc的_start入口。



結尾

作者:江湖評談
歡迎關注我,帶你瞭解進階技術。
image

相關文章