を返す関連するタイマコールバックするまでロードされたカーネルモジュールを維持するための良い方法はあります。 コードは、次のようなものです:私はいくつかの期間の後、モジュールにコールバック関数を呼び出して、タイマーをセットし、カーネルモジュールを書いています
static struct timer_list test_timer;
static void timeout_cb(unsigned long data)
{
printk("cb called\n");
}
static int __init timer_module_init(void)
{
init_timer(&test_timer);
test_timer.expires = jiffies + HZ*5;
test_timer.data = 0;
test_timer.function = timeout_cb;
add_timer(&test_timer);
return 0;
}
私はモジュールがアンロードされている場合、コールバック関数が呼び出される前に、システムがハングアップすることを考えました。そして、これは実際に起こった。
# insmod timer_test.ko && lsmod | grep timer_test && rmmod timer_test.ko
timer_test 1034 0 ### No ref count to the module
### After some seconds, the system hung up
私はこの問題の簡単な解決策はadd_timer()
前に、モジュールの参照カウントをインクリメントし、timeout_cb()
が終了するまでロードされたモジュールを保持timeout_cb()
の終わり、でそれをデクリメントされると思います。
static void timeout_cb(unsigned long data)
{
printk("cb called\n");
module_put(THIS_MODULE); // decrementing ref count
}
static int __init timer_module_init(void)
{
...
try_module_get(THIS_MODULE); // incrementing ref count
add_timer(&test_timer);
return 0;
}
これは正常に動作するようだが、モジュールがmodule_put()
戻った後、しかしtimeout_cb()
戻る前にアンロードされた場合は、厳密に言えば、システムがハングアップするでしょう。
//objdump
static void timeout_cb(unsigned long data)
{
0: 55 push %rbp
1: 48 89 e5 mov %rsp,%rbp
4: e8 00 00 00 00 callq 9 <timeout_cb+0x9>
9: 48 c7 c7 00 00 00 00 mov $0x0,%rdi
10: 31 c0 xor %eax,%eax
12: e8 00 00 00 00 callq 17 <timeout_cb+0x17>
printk("cb called\n");
module_put(THIS_MODULE);
17: 48 c7 c7 00 00 00 00 mov $0x0,%rdi
1e: e8 00 00 00 00 callq 23 <timeout_cb+0x23>
}
// I think the system would hang up if the module is unloaded here.
23: c9 leaveq
24: c3 retq
25: 90 nop
timeout_cb()
が完全に復帰するまでモジュールをロードしておくとよいでしょうか? timeout_cb()
は、割り込みコンテキストで呼び出されたので、私は、これは通常の方法であることを確認していないものの
ありがとうございました!私はあなたの答えを私のアプローチと組み合わせます。 –