linux調度器(四)——主調度器與CFS

來源:互聯網
上載者:User

         當核心從系統調用返回,或者從中斷處理常式返回,核心都會檢查當前進程是否設定了TIF_NEED_RESCHED標誌;或者進程主動放棄CPU時(sched_yield,sleep或者收到SIGSTOP,SIGTTOP訊號)都會進入主調度器。同樣的我們先看一下主調度的架構部分,該部分就是sched.c:schedule(void):
關閉核心搶佔
如果進程之前是不可運行並且被核心搶佔了,那麼如果它現在有非阻塞訊號,則將它的狀態改為TASK_RUNNING而且不移出就緒隊列,否則該進程(不可運行)從就緒隊列中取出deactivate_task
判斷是否要進行負載平衡(當前運行隊列為空白)
通知調度器類將當前(活動)進程將被其它進程替換掉(put_prev_task)
選擇下一個將要被執行的進程(pick_next_task),並清除前一個進程的TIF_NEED_RESCHED
進行環境切換(context_switch)
重新計算新進程所在的cpu及rq,即為當前cpu(因為新的進程之前可能在不同的cpu上運行了,同樣老的進程喚醒時也是所這裡開始)
如果新的進程也被設定了TIF_NEED_RESCHED,則再次調度
大體過程如:


圖 schedule與CFS的互動

         下面我們主要來分析下CFS的相關的三個操作:
deactivate_task:該函數最終調用CFS的dequeue_task_fair,並且將進程的p->se.on_rq置0,表示該進程不在運行隊列裡。dequeue_task_fair對於非組調度的話就是調用dequeue_entity更新執行進程的資訊update_curr,把該se從buddies中去掉(clear_buddies,見後面的分析),如果這個se不是正在啟動並執行進程則把該se從運行隊列的紅/黑樹狀結構上刪除掉(啟動並執行進程已經不存在紅/黑樹狀結構裡),置se->on_rq
= 0,並且減少運行列隊的相應load(update_cfs_load:這裡更新的是統計值的load,account_entity_dequeue這個才是真正更新跟進程調度相關的cfs_rq->load)及se的weight(update_cfs_shares)其它統計資訊(注意:當se出隊時如果它不是DEQUEUE_SLEEP必須把vruntime標準化se->vruntime -= cfs_rq->min_vruntime,否則就不需要標準化,這裡不是很明白?)。對於組調度,它從當前進程開始dequeue_entity,如果它的父group
load為0,那麼說明這個父group也應該被dequeue_entity,直到不為0(該group有其它進程就緒)的祖先group為止,到這裡就把從葉子(當前進程)到該進程向上遞迴load為空白的父group都出隊了;然後再更新從這個非空的父group到根的其餘group se的load(這裡只是更新統計的load update_cfs_load,而cfs_rq的load因為只記錄它本層的se的load之和不遞迴,所以不需要再更新該load),shares及h_nr_running統計,因為它們下層的se已經被出隊列了。另外,所有被dequeue的se的on_rq被置為0

put_prev_task_fair:該過程是與上一個函數不一樣的,上一個把不可啟動並執行進程從運行隊列中刪除掉,而put_prev_task_fair主要是通知CFS當前進程將會被調度出去了,如果當前進程已經不是可運行進程(on_rq=0),那麼這個函數只會把當前cfs_rq->curr置為NULL,表示當前cfs_rq沒有進程正在運行,否則如果當前進程還是可啟動並執行那麼還需要對它的狀態進行更新:update_curr更新它的實質物理已耗用時間,虛擬時間及它從現在開始就是進入等待的時間,並且再次將該進程重新入隊列(__enqueue_entity當前進程還是可運行狀態)。對於組調度同樣的需要更新從該進程到它的根group的所有se,包括每個se的執行時間(這裡的執行時間並不是代表它在cpu的執行時間,而是由它的下級執行時間的一個反映),至於每個層次的se都把它的cfs_rq->curr置為NULL是因為:在一個CPU上某一時刻只有一個進程在運行,噹噹前運行要被調度出去的時候,也代表了它的所有上層group在這個CPU上將被調度出去(對於group這隻是一個理論概論,它並不會真正在CPU上運行,只是為了與真正task統一起來才有這個標誌,表示當它的葉子task在CPU上運行;同樣的,當某group的葉子被調度[運行]時,它的所有上層group在它所在的運行隊列裡也被表示為啟動並執行)。

pick_next_task:挑選一個最需要啟動並執行進程來運行。如果當前隊列的等待啟動並執行進程總數等於cfs等待的數目,那麼就直接從cfs中挑選一個,否則從高優先策略的調度類中挑選一個進程來運行。這裡我們直接看CFS的pick_next_task_fair(這裡從根的cgroup開始一層一層往左邊找):通過pick_next_entity從當前層的cfs_rq判斷哪個se將被取出,它採用這樣的優先順序(從高到低)——已經被要求啟動並執行se(cfs_rq->next,即next要求搶佔),上一個啟動並執行se(cfs_rq->last),不是被skip的se,而且這三個優先順序都還需要滿足——它們比起cfs_rq最左邊的se更需要先被運行(wakeup_preempt_entity,它們的虛擬已耗用時間小於最左邊的虛擬已耗用時間,或者比最左邊再運行最小已耗用時間後的新的虛擬時間還小,減少不必要的切換);這樣就能選出一個合適的se;然後調用set_next_entity將該se設定為當前cfs_rq上正在啟動並執行進程:如果這個se還在運行隊列裡則更新它的等待結束時間,及出隊列(運行進程不應該放在就緒隊列裡,注這裡調用的是__dequeue_entity而不是dequeue_entity,後者是把這可啟動並執行se出隊列並需要更新nr_running--,on_rq=0等,而前者是不需要的,即啟動並執行進程雖然不在紅/黑樹狀結構裡,但是se->nr_rq還是等於1,cfs_rq->nr_running還是包括這個啟動並執行進程);更新開始執行的時鐘,將cfs_rq->curr置為該se。對於非組調度這樣就能把該se的task返回;而對於組調度其實也很簡單,如果pick_next_entity取得的是一個group的話,那麼再從它的運行隊列裡se->my_q裡選出一個合適的se出來,直到該se是非group,而且這些group的se所在的cfs_rq也會把curr置為當前遞迴的group
se(這也是我們上面說的put_prev_entity的反操作)。
    總之,schedule是為了完成從prev進程切換到next進程的過程,如果prev是不可啟動並執行並且沒收到訊號那麼應該先把它從運行隊列裡去掉(deactivate_task),注意此時還是它佔用的CPU所以還需要更新它的執行時間(update_curr);然後告訴CFS該prev將要被調度出去了,此時也是需要考慮它是否是可啟動並執行狀態,還是不可運行狀態,如果是不可運行狀態,那麼上面它已經被從運行隊列中去掉,並且on_rq的標誌也被清0,所以只需要把cfs_rq->curr置為NULL就可以了,否則就是它是可啟動並執行,那麼首先也是先更新它的執行時間update_curr,然後把它重新放到運行隊列裡(當前啟動並執行進程是不在運行隊列裡的),最後同樣把cfs_rq->curr置為NULL;接著從CFS裡挑選一個合適的進程來執行,一些比較優先考慮的進程被儲存在buddies(next,last),所以它先從這些裡及最左篩選,篩選後把該se從運行隊列中出隊,相應的最後需要把cfs_rq->curr置為當前被篩選出來的se,表示該se是當前cfs_rq上啟動並執行se。
         這樣我們就把調度器兩個主要組件介紹完了,下面介紹到task建立時的調度器對新任務的初始化過程。我們估且把該過程稱為進程調度初始化,下面我們就來分析該過程。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.