try_module_get和module_put

来源:互联网 发布:阿里云计算认证考试 编辑:程序博客网 时间:2024/05/29 11:57

try_module_get

注解:

        1>位置:/linux/kernel/module.c

        2>声明:static inline int  try_module_get(structmodule *module)

        3>功能:判断module模块是否处于活动状态,然后通过local_inc()宏将该模块的引用计数加1

        4>返回值:

linux-2.6中返回值是一个整数,如果该模块处于活动状态且对它引用计数加1操作正确则返回1,否则返回0

linux-3.7.5中返回值是一个bool量,正确返回true,错误返回false!

实现方式Linux-2.6

[cpp] view plaincopy
  1. static inline int try_module_get(struct module *module)  
  2. {  
  3.     int ret = 1;  
  4.   
  5.     if (module) {  
  6.         unsigned int cpu = get_cpu();  
  7.         if (likely(module_is_live(module))) {  
  8.             local_inc(__module_ref_addr(module, cpu));  
  9.             trace_module_get(module, _THIS_IP_,  
  10.                 local_read(__module_ref_addr(module, cpu)));  
  11.         }     
  12.         else  
  13.             ret = 0;  
  14.         put_cpu();  
  15.     }     
  16.     return ret;  
  17. }  

实现方式Linux-3.7.5中

[cpp] view plaincopy
  1. bool try_module_get(struct module *module)  
  2. {  
  3.     bool ret = true;  
  4.   
  5.     if (module) {  
  6.         preempt_disable();  
  7.   
  8.         if (likely(module_is_live(module))) {  
  9.             __this_cpu_inc(module->refptr->incs);  
  10.             trace_module_get(module, _RET_IP_);  
  11.         } else   
  12.             ret = false;  
  13.   
  14.         preempt_enable();  
  15.     }      
  16.     return ret;   
  17. }  
  18. EXPORT_SYMBOL(try_module_get);  

module_put

注解:

     1>声明:

Linux-3.7.5中void module_put(struct module *module)

Linux-2.6中static inline void module_put(struct module *module) 

2>功能:使指定的模块使用量减一

实现方式Linux-2.6中,是空的   我很不解,求高手解释!

[cpp] view plaincopy
  1. static inline void module_put(struct module *module)  ///不解!!  
  2. {  
  3. }  


Linux-3.7.5中

[cpp] view plaincopy
  1. void module_put(struct module *module)  
  2. {  
  3.     if (module) {  
  4.         preempt_disable();  
  5.         smp_wmb(); /* see comment in module_refcount */  
  6.         __this_cpu_inc(module->refptr->decs);  
  7.   
  8.         trace_module_put(module, _RET_IP_);  
  9.         /* Maybe they're waiting for us to drop reference? */  
  10.         if (unlikely(!module_is_live(module)))  
  11.             wake_up_process(module->waiter);  
  12.         preempt_enable();  
  13.     }      
  14. }  
  15. EXPORT_SYMBOL(module_put);  

这两个函数的使用实例,hello模块init函数

[cpp] view plaincopy
  1. /*模块初始化函数*/  
  2. static int __init hello_init(void)  
  3. {  
  4.         printk("<0>module_refcount(module):%d\n",module_refcount(THIS_MODULE));  
  5.         try_module_get(THIS_MODULE);  
  6.   
  7.         printk("<0>module_refcount(module):%d\n",module_refcount(THIS_MODULE));  
  8.         module_put(THIS_MODULE);  
  9.         printk("<0>module_refcount(module):%d\n",module_refcount(THIS_MODULE));  
  10.         return 0;  
  11. }  

打印的结果

[cpp] view plaincopy
  1. [root@root hello模块]#   
  2. Message from syslogd@localhost at Feb  2 09:07:45 ...  
  3.  kernel:module_refcount(module):1  
  4.   
  5. Message from syslogd@localhost at Feb  2 09:07:45 ...  
  6.  kernel:module_refcount(module):2  
  7.    
  8. Message from syslogd@localhost at Feb  2 09:07:45 ...  
  9.  kernel:module_refcount(module):1  

由上面的程序可以看出来在模块加载的过程中,模块的使用量就是1了,然后用try_module_get把使用量变为2,再使用module_put把使用量变为1,加载完成后使用量为0
开始写程序的时候把module_put写在了__eixt中,导致加载了模块使用量一直为1,无法卸载只能重启!后来才知道rmmod是在调用module_exit之前检查模块的引用计数的,所以在exit之前就应该要module_put释放引用计数,这样一来把module_put写在init里面就可以解决了!
http://blog.csdn.net/jk110333/article/details/8564640

0 0