ページフォルトハンドラ

9vx上で動作するPlan9プロセスは、ホストOSのプロセスと1対1対応している訳ではない。これはホストOSでpsしてみれば、9vxという1つのプロセスしか見えない(Plan9プロセスは見えない)ことからもわかる。

9vxの内部実装は基本的に「1 CPU = 1スレッド(pthread)」になっている。そして、1つのkproc(カーネルスレッド)が1つのCPUに張りつくという都合、(kprocが生成されるたび、動的にCPU数が増加し)最終的に7 CPUシステムとなる。もちろんここ言うCPUは「仮想」CPUである。cpu0がメイン、cpu1でx11、cpu2でtimer、cpu3〜6でioカーネルスレッドが動作している。/dev/sysstatの出力からも想像がつくが、vxプロセスの実行、システムコール処理、ページフォルトなどの処理はすべてcpu0で実行するようだ。

/dev/sysstatの見方は左から順にcpu id、コンテキストスイッチ回数、割込み回数、システムコール回数、ページフォルト、TLBフォルト、TLBパージ、ロードアベレージ、アイドル時間、割込み処理時間。

% cat /dev/sysstat
          0       28603           0       69259      164066           0           0           0           0           0 
          1           2           0           0           0           0           0           0           0           0 
          2           0           0           0           0           0           0           0           0           0 
          3         495           0           0           0           0           0           0           0           0 
          4         181           0           0           0           0           0           0           0           0 
          5        8650           0           0           0           0           0           0           0           0 
          6        5180           0           0           0           0           0           0           0           0 

ページフォルト(存在しないメモリへのアクセス)はSIGSEGVとして処理される。SIGSEGVはPlan9 VXカーネルの実行中もしくはPlan9ユーザプロセス(vx32インスタンス)のどちらでも起こり得る。前者は基本的にpanicで、後者だと代替シグナルスタックを使ってvx32_sighandlerを実行する。この関数は以前も軽く触れたが、SIGSEGVの場合はトラップ番号をVXTRAP_PAGEFAULTに設定してvxemu_sighandlerを呼ぶ。その結果、vxproc_runの実行を中断し、faultでページフォルト処理を実行後、(touser内でループになっているので)vxproc_runの実行を再開する。