你本来应该根本不用使用try_module_get(THIS_MODULE);几乎所有这些用途都是不安全的,因为如果你已经在你的模块中了,引用次数太迟了 – 总会有一个(小)窗口,你在模块中执行代码,但是没有增加引用计数.如果有人在该窗口中完全移除模块,那么您处于卸载模块中运行代码的不利情况.
在LKMPG中链接的特定示例,其中代码在open()方法中执行try_module_get())将在现代内核中通过在struct file_operations中设置.owner字段来处理:
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)的许多用途,但大多数(如果不是全部)都是应该被清理的潜在错误.
你无法卸载sched示例的原因是你的
$tail /proc/sched -f &
命令保持/ proc / sched打开,因为
Our_Proc_File->owner = THIS_MODULE;
在sched.c代码中,打开/ proc / sched会增加sched模块的引用计数,这是lsmod显示的1引用.通过快速浏览其余的代码,我想如果你通过杀死你的尾部命令释放/ proc / sched,你可以删除sched模块.