Linuxの備忘録とか・・・(目次へ)Linuxの備忘録とか・・・(目次へ)kthread_runマクロkthread_runマクロはカーネルスレッドを作成し、起動(アクティブキューに接続)に繋ぐ。カーネルスレッドはユーザプロセスのマルチスレッドと同じような感じ。異なるのは、ユーザプロセスの親もプロセスとして動作するが、カーネルスレッドの親は、カーネル本体で、このカーネルはプロセスとして動作しているわけでない。lkmで/procのコールバック処理を実装した場合、この関数はカーネル上の1パスの関数にしか過ぎない。カーネルスレッドからコールされる事もありうる。従ってその処理が終了しても(return)、イメージとしての実態はカーネル内に存在し続ける。カーネルスレッドだと、カーネルパスの延長上で動作するのでなく、カーネルからスケジュールされるプロセスとして動作する。従って、その処理が終了したらプロセスとして存在しなくなる。rmmodしない限り、イメージとしてメモリ上に存在する。再度必要に応じてkthread_runすることも可能。従って、lkmから作成したカーネルスレッド、lkmをrmmmodする時に、その前にそのカーネルスレッドを削除する必要がある。この処理を忘れると、実在しないカーネルスレッドに起動がかかるって事になる。(たぶん)カーネルスレッド内の処理は、サービスの間retできない。上記のごとくretするとプロセスが削除されてしまう。カーネルの実装的には、カーネルスレッドとなる関数の復帰後に、do_exit関数がコールされるようになっている。以下はlkm下のカーネルスレッドでjiffiesを表示させるサンプル。kthread:3695328rmmod時に、kthread_should_stopがコールされる様にする必要がある。1として、カーネルスレッドを起床させ、wait_for_completionでスレッドが削除されるまでウエイトする。後、モジュールを削除する事が可能になる。ret;}実装kthread_runマクロはkthread_createマクロ展開し、dataを引数として、threadfnの関数をカーネルスレッドとして作成し、wake_up_process()でそのプロセスを起床させた後、タスク構造体を返す。\})kthread_createマクロでkthread_create_on_node()がコールされ、新規作成するカーネルスレッドをkthread_create_listに接続す。このリストはカーネルスレッドkthreaddが参照し、新規スレッドを作成することになる。kthreaddを起床させているのが、wake_up_process(kthreadd_task)。kthreaddにより新規スレッドが起床ができたら、そのタスク構造体に、プライオリティ/コマンド引数/スケジューラクラスを設定し、タスク構造体を返す。引数のでnodeは、NUMのケースっぽい。create.result;}kthreaddで、kthread_create_listにリストされている新規作成待ちカーネルスレッドを、create_kthread関数で作成し、そのリストからそのノードを削除する。0;}create_kthread関数からkernel_thread()をコールする事で、実際のカーネルスレッドが作成される。新規作成されるスレッド(create引数)は、kthread関数の引数となる。}}kernel_thread()で、やっとdo_forkをコールする。fn=kthread、arg=createだ。kernel_thread_helperから動作することになる。この関数はkernel_thread_helperってやつ。*%esiで、kthread関数がコールされ、create->threadfnに設定してある、新規スレッドがコールされてるみたい。そこから復帰したらdo_exit()でスレッド終了処理している。do_exitしている。kthread_runマクロ、大体こんな感じみたい。ノースAdsense広告情報が設定されていません。