您的位置:首页 > 其它

try_module_get和module_put

2017-03-19 02:15 169 查看

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
plain copy

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] view
plain copy

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] view
plain copy

static inline void module_put(struct module *module)  ///不解!!  

{  

}  

Linux-3.7.5中

[cpp] view
plain copy

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] view
plain copy

/*模块初始化函数*/  

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] view
plain copy

[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里面就可以解决了!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: