2009-11-16 329 views
16

我在讀LKMPG(See Section 4.1.4. Unregistering A Device),我不清楚何時使用try_module_get/module_put函數。一些LKMPG的例子使用它們,有些則不。Linux內核模塊:什麼時候使用try_module_get/module_put

爲了增加混淆,try_module_get在2.6.24源文件中的193個文件中出現了282次,而在Linux Device Drivers (LDD3)Essential Linux Device Drivers中,它們甚至不出現在單個代碼示例中。

我想也許他們是綁在老register_chrdev接口(由CDEV接口2.6取代),但他們只一起出現在同一個文件中8次:

find -type f -name *.c | xargs grep -l try_module_get | sort -u | xargs grep -l register_chrdev | sort -u | grep -c . 

因此,它是適當的時使用這些函數,並且它們與特定接口或一組環境的使用有關係嗎?

編輯

我裝從LKMPG的sched.c例子,嘗試了以下實驗:

[email protected]:~/kernel-source/lkmpg/2.6.24$ tail /proc/sched -f & 
Timer called 5041 times so far 
[1] 14594 

[email protected]:~$ lsmod | grep sched 
sched     2868 1 

[email protected]:~$ sudo rmmod sched 
ERROR: Module sched is in use 

這使我相信,內核現在它是自己的會計和獲取/看跌期權可能已經過時。任何人都可以驗證此?

+0

有在第14章try_module_get'的'一個發生在第'引用計數manipulation'(頁367) – 2011-02-08 18:24:58

+0

我說的是LDD書在我之前的評論 – 2011-02-08 18:32:36

回答

15

你基本上不需要使用try_module_get(THIS_MODULE);幾乎所有這些用途都是不安全的,因爲如果您已經在模塊中,那麼衝擊引用計數就太遲了 - 總會有一個(小)窗口,您正在模塊中執行代碼,但未增加引用計數。如果有人在該窗口中完全刪除模塊,那麼您處於未加載模塊中運行代碼的不良情況。

其中代碼並通過file_operations結構設置.owner場try_module_get()的open()方法將在現代性的核心來處理你LKMPG鏈接的具體例子:

struct file_operations fops = { 
     .owner = THIS_MODULE, 
     .open = device_open, 
     //... 
}; 

這將使VFS代碼在調用之前參考模塊,這樣可以消除不安全的窗口 - 在調用.open()之前,try_module_get()會成功,或者try_module_get()將失敗,並且VFS將永遠不會調用模塊。無論哪種情況,我們都不會從已經卸載的模塊運行代碼。

唯一的好時候使用try_module_get()是當你想調用到它或使用它以某種方式(之前採取不同模塊的引用例如,作爲文件開放代碼確實在我解釋的例子以上)。內核源代碼中有很多try_module_get(THIS_MODULE)的用法,但大多數(如果不是全部)都是應該清除的潛在錯誤。

的原因,你無法卸載附表的例子是,你

$ tail /proc/sched -f & 

命令保持的/ proc /打開因爲附表,並

 Our_Proc_File->owner = THIS_MODULE; 
在sched.c中碼

,打開/ proc/sched會增加調度模塊的引用計數,該模塊會解釋lsmod顯示的引用計數。從其他代碼的快速瀏覽中,我想如果通過殺死tail命令來釋放/ proc/sched,您將能夠刪除調度模塊。

+0

--- 嗯,我知道最近在工作在看門狗設備驅動程序上,有一項名爲no-way-out的功能,這意味着一旦啓動該設備,就無法停止它。 由於這個原因,這個模塊不能被卸載,因此,在設備驅動程序的open()實現中,使用了__module_get(THIS_MODULE)和設備驅動程序模塊,當模塊的引用計數不爲零時,你不能卸載它。 最後,也許這是你需要使用module_get,module_put等的情況。 謝謝。 – 2013-07-31 06:52:25

+0

'init_module'函數中的'try_module_get'是安全的,但匹配的'module_put'必須在'cleanup_module'之前的某個時間點完成。 – fche 2014-08-07 20:17:11