当前位置:编程学习 > C/C++ >>

try_module_get和module_put

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]  
static inline int try_module_get(struct module *module)  
{  
    int ret = 1;  
  
    if (module) {  
        unsigned int cpu = get_cpu();  
        if (likely(module_is_live(module))) {  
            local_inc(__module_ref_addr(module, cpu));  
            trace_module_get(module, _THIS_IP_,  
                local_read(__module_ref_addr(module, cpu)));  
        }     
        else  
            ret = 0;  
        put_cpu();  
    }     
    return ret;  
}  
 
实现方式Linux-3.7.5中
[cpp]  
bool try_module_get(struct module *module)  
{  
    bool ret = true;  
  
    if (module) {  
        preempt_disable();  
  
        if (likely(module_is_live(module))) {  
            __this_cpu_inc(module->refptr->incs);  
            trace_module_get(module, _RET_IP_);  
        } else   
            ret = false;  
  
        preempt_enable();  
    }      
    return ret;   
}  
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]  
static inline void module_put(struct module *module)  ///不解!!  
{  
}  
 
 
Linux-3.7.5中
[cpp]  
void module_put(struct module *module)  
{  
    if (module) {  
        preempt_disable();  
        smp_wmb(); /* see comment in module_refcount */  
        __this_cpu_inc(module->refptr->decs);  
  
        trace_module_put(module, _RET_IP_);  
        /* Maybe they're waiting for us to drop reference? */  
        if (unlikely(!module_is_live(module)))  
            wake_up_process(module->waiter);  
        preempt_enable();  
    }      
}  
EXPORT_SYMBOL(module_put);  
 
这两个函数的使用实例,hello模块init函数
[cpp]  
/*模块初始化函数*/  
static int __init hello_init(void)  
{  
        printk("<0>module_refcount(module):%d\n",module_refcount(THIS_MODULE));  
        try_module_get(THIS_MODULE);  
  
        printk("<0>module_refcount(module):%d\n",module_refcount(THIS_MODULE));  
        module_put(THIS_MODULE);  
        printk("<0>module_refcount(module):%d\n",module_refcount(THIS_MODULE));  
        return 0;  
}  
 
打印的结果
[cpp] 
[root@root hello模块]#   
Message from syslogd@localhost at Feb  2 09:07:45 ...  
 kernel:module_refcount(module):1  
  
Message from syslogd@localhost at Feb  2 09:07:45 ...  
 kernel:module_refcount(module):2  
   
Message from syslogd@localhost at Feb  2 09:07:45 ...  
 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里面就可以解决了!
 
补充:软件开发 , C++ ,
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,