Linuxカーネルに関する技術情報を集めていくプロジェクトです。現在、Linuxカーネル2.6解読室の第2章までを公開中。
マルチプロセッサ動作時のスケジューラの動きを以下に示す。★印が、シングルプロセッサから追加される機能である。
プロセスがなるべく同じCPU上で実行が繰り返された方が効率がよい。(そのプロセスが利用した情報がキャッシュメモリ上に残っているなど)最も高いプライオリティのプロセスを探すgoodness関数においては、スケジューラが動作しているCPU上で、以前動作していたプロセスであれば、プライオリティ計算に下駄を履かせ、なるべく同じCPU上で実行できるよう配慮している。
schedule() タスクキューtq_schedulerの実行(run_task_queue関数) ソフト割り込みハンドラ呼び出し(do_softirq関数) プリエンプション要求をクリア if(スケジューラを呼び出したプロセスの状態がTASK_RUNNINGでない){ プロセスをRUNキューから外す(del_from_runqueue関数) } while(RUNキューに継っている全てのプロセスに対して) { ★ただし、現在CPUが割り当てられている(has_cpuフラグが立っている)プロセスを除き、 最も高いプライオリティのプロセスを探す(goodness関数) } while(システム上の全てのプロセスに対して) { プライオリティ再計算 } ★選ばれたプロセスのtask_structにCPU番号を格納(processorメンバ) ★選ばれたプロセスをCPU割当て状態にする(has_cpuフラグを立てる) メモリ空間の切替え(enter_lazy_tlb関数, switch_mm関数) プロセスコンテキストの切替え(switch_to関数) ★if(まさに今WAITするためCPUを放棄したプロセスにwake_upが行われた) ★カレントプロセスに再スケジーリング要求を出す ★CPUを放棄したプロセスのCPU割り当て状態を解除(has_cpuフラグのクリア)
スケジューラに対し、再スケジューリング要求を出す関数(reschedule_idle関数)もマルチプロセッサを意識した動作になる。CPU間通信はヘビーな為、 ほどほどのところで妥協した作りとなっている。以下のような方針でプリエンプト要求を出すCPUを選んでいる。二つのCPUが存在する時、優先度でみて上から二つのプロセスにCPUが割り当てられるわけではない。
v2.2では、「今起床されたプロセスが、現在このCPUのカレントプロセスから起床 されたものであった場合、他のCPU上へ実行権を与えられても カーネルロック(後述lock_kernel関数)処理でビジーウェイトする だけで無駄なのでこのままにしておく」という処理が行われていたが、v2.4では原則Linxuカーネル内をカーネルロック(後述lock_kernel関数)を行わずに走行できるようになったため、この処理は外された。
(NIS)HirokazuTakahashi
2000年12月09日 (土) 23時55分06秒 JST1
[PageInfo]
LastUpdate: 2008-08-27 14:18:38, ModifiedBy: hiromichi-m
[Permissions]
view:all, edit:login users, delete/config:members