カーネルモジュールの中でkthreadを作成する方法メモ
ローダブルカーネルモジュールの作成とビルド方法に関しては以下などを参考にしてください。
[Linux][kernel module] 簡単なローダブルカーネルモジュールのビルドとロード - Qiita
ソース
#include <linux/module.h>
#include <linux/sched.h>
#include <linux/kthread.h>
MODULE_LICENSE("MIT");
struct task_struct *k;
static void kthread_main(void)
{
schedule();
}
static int kthread_func(void* arg)
{
printk(KERN_INFO "[%s] start kthread\n", k->comm);
while (!kthread_should_stop()) {
kthread_main();
}
printk(KERN_INFO "[%s] stop kthread\n", k->comm);
return 0;
}
static int __init testmod_init(void)
{
printk(KERN_INFO "driver loaded\n");
k = kthread_run(kthread_func, NULL, "testmod kthread");
return 0;
}
static void __exit testmod_exit(void)
{
kthread_stop(k);
printk(KERN_INFO "driver unloaded\n");
}
module_init(testmod_init);
module_exit(testmod_exit);
基本的な流れ
メイン
- init関数で
kthread_run(3, ...)
マクロにてスレッドの作成を行う - exit関数で kthread を終了する
kthread_run(3, ...)
マクロは以下のようになっているとのことです。
#define kthread_run(threadfn, data, namefmt, ...) \
({ \
struct task_struct *__k \
= kthread_create(threadfn, data, namefmt, ## __VA_ARGS__); \
if (!IS_ERR(__k)) \
wake_up_process(__k); \
__k; \
})
kthread_create(3, ...)
を実行後、wake_up_process(1)
が実行されています。
namefmt
については、printfのようにフォーマット指定子が使用でき、変数を使用したスレッド名を設定することができます。
kthread側
- 新しいスレッドから、kthread_funcが呼び出される
- 終了まで繰り返し呼び出されるループを作成(スレッドの終了は
kthread_should_stop()
で検出する) -
schedule()
にて一定期間スリープ
TODO: schedule()
の動作については要調査
実行例
$ sudo insmod testmod.ko
$ ps aux | head -1 && ps auwx | grep "\[testmod kthread\]"
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 28716 84.8 0.0 0 0 ? R 23:14 16:07 [testmod kthread]
$ sudo rmmod testmod.ko
$ dmesg | tail
[187744.330108] driver loaded
[187744.330326] [testmod kthread] start kthread
[187812.178718] [testmod kthread] stop kthread
[187812.178743] driver unloaded
カーネルモジュール内でのスレッドの開始と終了がされていることが確認できました。
psコマンドで作成したスレッドの確認をすることもできました、
関連
[Linux][kernel module] 簡単なローダブルカーネルモジュールのビルドとロード - Qiita
[Linux][kernel module] ローダブルカーネルモジュールのロード時に引数でパラメータを渡す方法 - Qiita
[Linux][kernel module] kthreadの実行CPUを指定/制限する - Qiita
参考
カーネルスレッドのループと停止をカーネルモジュールで実装 - 人間とウェブの未来
kthread_runマクロ - Linuxの備忘録とか・・・(目次へ)
[PDF] kthreads