21

LKMPGを読んでいて(セクション4.1.4。デバイスの登録解除を参照)、いつ機能を使用するかが明確ではありませんでしたtry_module_get / module_put。LKMPGの例の中には、それらを使用するものと使用しないものがあります。

混乱を増すためにtry_module_get、2.6.24ソースの193ファイルに282回表示されますが、Linuxデバイスドライバー(LDD3)Essential Linuxデバイスドライバーでは、1つのコード例にも表示されません。

おそらくそれらは古いregister_chrdevインターフェース(2.6ではcdevインターフェースに取って代わられました)に関連付けられていると思いましたが、同じファイルに一緒に表示されるのは8回だけです。

find -type f -name *.c | xargs grep -l try_module_get | sort -u | xargs grep -l register_chrdev | sort -u | grep -c .

では、これらの機能を使用するのはいつ適切であり、特定のインターフェイスまたは一連の状況の使用に関連付けられているのでしょうか。

編集

LKMPGからsched.cの例をロードし、次の実験を試みました。

anon@anon:~/kernel-source/lkmpg/2.6.24$ tail /proc/sched -f &
Timer called 5041 times so far
[1] 14594

anon@anon:~$ lsmod | grep sched
sched                   2868  1 

anon@anon:~$ sudo rmmod sched
ERROR: Module sched is in use

これにより、カーネルが独自のアカウンティングを実行し、gets/putsが廃止された可能性があると私は信じています。誰かがこれを確認できますか?

4

1 に答える 1

22

基本的に、try_module_get(THIS_MODULE); を使用する必要はありません。すでにモジュールにいる場合、参照カウントを増やすには遅すぎるため、そのような使用のほとんどすべてが安全ではありません。モジュールでコードを実行しているが参照をインクリメントしていない(小さな)ウィンドウが常に存在します。カウント。誰かがそのウィンドウでモジュールを正確に削除した場合、アンロードされたモジュールでコードを実行するという悪い状況になります。

open() メソッドでコードが try_module_get() を実行する LKMPG でリンクした特定の例は、構造体 file_operations で .owner フィールドを設定することにより、最新のカーネルで処理されます。

struct file_operations fops = {
        .owner = THIS_MODULE,
        .open = device_open,
        //...
};

これにより、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 つの参照に相当します。残りのコードをざっと見てみると、tail コマンドを強制終了して /proc/sched を解放すると、sched モジュールを削除できると思います。

于 2011-05-21T05:32:56.880 に答える