linux2 6 29 CFS排程詳細分析 二

2021-05-23 15:37:28 字數 3099 閱讀 7190

上次主要講了

cfs排程的基本原理,並且沒有分析有喚醒和程序遷移時候的排程流程,所以本文主要 從核心中幾個重要的排程點來詳細的分析一下排程的基本流程,主要以流程圖的形式給出。

核心中主要有以下幾個重要的切入點

:(1)tick

相關,即時鐘中斷

這就是上篇文章中講的每次中斷中,更 新

vruntime

的整個過程,可以理解為是在中斷的上半部分做的,很顯然我們會想到前一篇文章中 講到的檢查

tif_need_sched

位並顯示呼叫

schedule()

的地方就是中斷的下半部分了,為了更好的理解我把中斷的整個處理流程也做了個流程圖

(以時鐘中斷為例):

) 與中斷相關的部分,我會在以後的文章裡詳細介紹,在這裡就不具體接講解了。

現在來總結一下這個切入點的整個過程:

當來乙個時鐘中斷的時候,概括來說核心做了兩個操作

(參見上圖中):

(1)do_timer():

它主要來更新系統的時間

(2)update_progress_times():

一方面去執行我們上面談到的

scheduler_tick()

,另一方面他又去觸發乙個軟中斷

執行完上面幾個步驟後,時鐘中斷就要返回了,因為其他的任務留給軟中斷做了。具體怎麼做我會在中斷一部分在分析。我們來看看中斷返回時的一段 **:

call do_irq

jmp ret_from_intr  #

執行完do_irq

後跳到ret_from_intr

ret_from_intr:

..............

cmpl $user_rpl, %eax 

#判斷返回使用者態還是核心態

jb resume_kernel  # not returning to v8086 or userspace

entry(resume_userspace)

..............

jne work_pending

jmp restore_all

entry(resume_kernel)

..........

need_resched:

movl ti_flags(%ebp), %ecx # need_resched set ?

testb $_tif_need_resched, %cl    #檢查

tif_need_sched

有沒有被置位

jz restore_all

testl $x86_eflags_if,pt_eflags(%esp) # interrupts off (exception path) ?

jz restore_all

call preempt_schedule_irq         

#在這裡顯示呼叫 了

schedule()

jmp need_resched

到這裡我們已經跟蹤了在時鐘中斷裡面的乙個完整的排程過程。

(2)當前程序主動放棄

cpu

既然是主動放棄,直接主動呼叫

schedule()

就行了,核心裡面的很多地方都是這麼做的,只要搜一下

schedule

的呼叫點就會看到。下面是從

schedule()

開始的乙個呼叫

流程圖:

總結一下執行的流程:

(1)清除tif_need_sched

(2)判斷一下當前程序應該被繼續設定為

task_running

狀態,如果不是的話就把它從執行佇列中刪除

(3)看一下當前執行佇列是否還有可執行進 程,沒有的話,呼叫

idle_balance(cpu, rq)

平衡負載

(4)把當前程序放回執行佇列,並設定當前 程序的指標為空。

(5)選擇下乙個程序作為當前程序

(6)判斷如果當前程序不等於選擇的程序的 話,就進行程序切換,執行swtich_to,這部分將在下次講解。

先說這麼多,因為有很多細節我也不怎麼理解,下面提出幾個問題,希望能和大家一塊討論:

(1)schedule()函式中的這段**及其展開

if (prev->state && !(preempt_count() & preempt_active)){

/*prev->state >0 即當前程序處在stopped狀態下,而且可搶占的情況下*/

if (unlikely(signal_pending_state(prev->state, prev)))

prev->state = task_running;/**/

else

deactivate_task(rq, prev, 1) ;/*從紅黑樹中刪除prev*/

switch_count = &prev->nvcsw;

這部分的意思是如果當前程序還需要呆在執行佇列中就設定其prev->state = task_running,否則把它從

紅黑樹中刪除。

問題一:繼續留在執行佇列的那個判斷條件具體是什麼意思?

if (unlikely(signal_pending_state(prev->state, prev)))

猜測應該 是,task_interruptible這種狀態時,可隨時接受訊號來繼續執行。

問題二: 如果不留在執行佇列就要從紅黑樹種刪除,跟蹤刪除函式最後到了dequeue_entity()的這段**

/*清除夥伴*/

clear_buddies(cfs_rq, se);

/*大部分情況下二者是相等的,不執行,

因為當前程序一直就不在執行佇列中

問題的關鍵是什麼情況下執行呢?*/

if (se != cfs_rq->curr)

__dequeue_entity(cfs_rq, se);

這個判斷條件是什麼意思?se不就是當前程序嗎?什麼情況下這個判斷條件才能成立,最好能有個具體的例子。

我是這麼想的,大部分情況下se = cfs_rq->curr,那麼出隊操作就不執行,因為當前程序是不在執行佇列中的,這一點可以從新選擇乙個程序來執行的時候要先把它出列得到印 證,具體可見pick_next_task().

Linux程序排程之CFS

在linux2.6核心中,開發人員引入了一種新的排程策略,旨在解決2.5及之前的排程器在處理使用者互動式程式時延遲大的不足。這種排程器就是completely fair scheduler 簡稱cfs 排程器的任務就是從當前系統中的就緒任務中選擇合適的任務執行。排程器需要確定在什麼時候排程什麼任務,...

linux排程器(四) 主排程器與CFS

當核心從系統呼叫返回,或者從中斷處理程式返回,核心都會檢查當前程序是否設定了tif need resched標誌 或者程序主動放棄cpu時 sched yield,sleep或者收到sigstop,sigttop訊號 都會進入主排程器。同樣的我們先看一下主排程的框架部分,該部分就是sched.c s...

linux核心分析之排程演算法 CFS排程分析

前面對linux排程演算法的框架進行了介紹,在這裡對cfs 完全公平排程 演算法進行分析。cfs允許每個程序執行一段時間 迴圈輪轉 選擇執行最少的程序作為下乙個執行程序,而不再採用分配給每個程序時間片的做法了,cfs在所有可執行程序總數基礎上計算出乙個程序應該執行多久,而不是依靠nice值來計算時間...