move_tasks()在幾個地方調用:
1. load_balance()
2. migrate_thread()---migration_thread
load balance在每個時鐘節拍由 scheduler_tick()--->rebalance_tick()調用。 rebalance_tick開始在所有調度域上循環,其路徑是從基本域(本地運行隊列的sd字段)到最上層域(see page286 to know what's the meaning "schedule feilf")。load_balance試圖把本調度域中最繁忙的組的進程遷移到本地cpu上的運行隊列。如果load_balance中的move_task調用失敗,那麼喚醒migration thread去沿著調度域的鏈搜索(從最忙運行隊列的基本域到最上層)空閒cpu。
migration thread除了load_balance喚醒外, 在幾種情況下調用:
1. do_exec 系統調用, 尋找空閒cpu去加載新進程
2. 改變cpu的親和性affinity時
3. migration_call(), 有cpu增減時
4. 更新cpu domain時,(支持cpu熱插拔)
5. load_balance_newidle
move_task先按優先級掃描busiest rq的過期進程,再掃描貨到進程, 當發現的時候,調用pull_task進行遷移, 所謂遷移指先調用dequeue_task()(從遠端刪除), 再調用enqueue_task()(插入本地)。 如果新進程優先級比當前進程擁有更高優先級, 就調用reschedule_task()搶占本地cpu。 這裡傳入的參數max_nr_move用來限制最大遷移進程數。
有幾個條件滿足才能被遷移, see page 289 of linux kernel 3rd.
sched_getaffinity() and sched_setaffinity():
設置允許進程的cpu的位掩碼。