2013-01-10 29 views
3

在我的內核配置中CONFIG_PREEMPT沒有設置。由於schedule()在中斷處理程序中不被允許,因此在Linux內核中如何實現循環調度類型的調度。即誰經常調用調度器。在entry_32.S中,只有在CONFIG_PREEMPT被設置的情況下它纔會調用preempt_schedule_irq。linux scheduler

回答

2

發生什麼事是CPU上的定時器被設置爲每隔一段時間都會中斷內核。但是我們不能只從中斷環境中調用日程安排嗎?所以內核做的是一個巧妙的技巧。它在執行處理程序時更改當前正在執行的任務,然後返回。這個有效的做法是從處理程序的下面切出上下文,以便處理程序完成,但同時下一個要運行的上下文現在是將要執行的下一個任務。請閱讀do_context_switch(IIRC,我認爲這就是它所稱的),你會發現它從當前執行的下面切換堆棧和上下文,並在另一個上下文中恢復相同的功能。

CONFIG_PREEMPT僅適用於內核上下文中的內核代碼搶佔。用戶空間任務將始終搶佔先機。所有這一切意味着任何開始執行的內核代碼都會運行到完成狀態(除非您自己調用schedule()或阻止等待I/O等)。通常情況下,內核可以搶佔,只要它沒有任何鎖定,除非在某些情況下獲取鎖定可以讓線程進入休眠狀態。

+1

我認爲處理程序不能只是改變當前正在執行的任務。如果當前進程持有spin_lock併發生計時器中斷,會發生什麼情況? – Yogi

+1

@ user1428099如果當前內核上下文有一個引用計數(持有自旋鎖),則會忽略定時器中斷,並在schedule()函數中檢查它是否應該切換上下文。所以中斷處理程序運行,它只是沒有做任何事情。 –

+0

@ user1428099雖然這不適用於擁有鎖的用戶空間任務,但它們管理自己的喚醒和休眠過程,但不能被搶佔,因爲這可能會導致內核死鎖,在內核中這是可以接受的,因爲任何會導致死鎖的情況一個核心會最終降低系統的性能,或者讓你擁有一個旋轉核心。 –