try_module_getとmodule_put

3344 ワード

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
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で
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>機能:指定したモジュール使用量を1つ減らす
実现方法Linux-2.6の中で、空の私はとても理解できなくて、达人の解釈を求めます!
static inline void module_put(struct module *module)  ///  !!
{
}

Linux-3.7.5
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);

この2つの関数の使用例、helloモジュールinit関数
/*       */
static int __init hello_init(void)
{
        printk("<0>module_refcount(module):%d
",module_refcount(THIS_MODULE)); try_module_get(THIS_MODULE); printk("<0>module_refcount(module):%d
",module_refcount(THIS_MODULE)); module_put(THIS_MODULE); printk("<0>module_refcount(module):%d
",module_refcount(THIS_MODULE)); return 0; }

印刷結果
[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に書けば解決できます!