雲計算之路:2009年Xen一個補丁背后那不為人知的故事


仔細閱讀了http://www.cnblogs.com/cmt/p/3729386.html這篇關於xen的博文,這篇博文寫的挺贊的,分析的也很細致,涉及到4年前的一個patch的故事。在講這個故事之前,先說明下,阿里雲官方的xen已經包含了博文中提到的xen的cpu idle潛在問題的修復版本(commit見:
http://xenbits.xen.org/gitweb/?p=xen.git;a=commit;h=964fae8ac2fa6732856179a2532b0914dba5e4bb),請童鞋們放心。

 

下面進入故事環節:先說patch的V1 版。當時是Xen Power Management開發的高峰時期,又正快到Xen3.4的代碼凍結時間,代碼凍結后就不會再接受新的feature patch,但bugfix patch還是可以提交進入upstream。

 

當時有一系列Xen cpuidle/cpufreq的patch已經進了Xen3.4 upstream-upstable,所以希望讓這個feature patch先上車,然后補票(追加一個bugfix patch)。這是基於兩點:一是這個patch的開發者Ke Ke同學是調bug的高手,有把握在代碼凍結期間搞定這個bug;二是這個bug波及不到普通用戶,所以放到patch里一般不會有什么負面影響。博主博客中提到的‘普通用戶’其實就是指HVM domain,原因是在Xen3.4時期VCPUOP_set_singleshot_timer僅屬於PV domain的一個hypercall(不像現在擴展到對HVM domain提供支持),所以對HVM domain沒影響。但Keir同學還是沒同意,所以Ke Ke同學只好苦哈哈地加班調bug去了 :)

 

這個bug其實比較詭異,如同博主博文中對V2 patch分析的那樣,根源是V1 patch的出現導致IPI喚醒處於deep Cx的處理器失敗。這里我只是補充一點問題產生的背景:Xen為什么要用IPI喚醒deep Cx處理器?V1 patch為什么導致IPI中斷喚醒失敗?

 

其實這一問題產生於某些老處理器硬件上存在的缺陷。通常中斷的發生都會導致處於deep Cx的處理器被喚醒,所以理論上大可不必大費周章地由一個處理器發IPI喚醒另一個睡眠中處理器。但凡事總有例外 -- 處理器的設計一般是希望CPU進入deep Cx時,關閉盡可能多的部件以節省更多能耗 -- 但有些老處理器設計時把諸如APIC Timer部件的電源也順手關了。這使得CPU進入deep Cx時產生不了APIC Timer中斷。為了防止這種有問題的處理器進入深度睡眠時,無法產生APIC Timer中斷而導致的Timer到期無法醒來的問題,Xen采用了比較保守的方法來處理,即由另一處理器在HPET Timer 發生時通過IPI來喚醒處於深度睡眠的處理器。HPET部件位於南橋,不受CPU狀態的影響,工作可靠,精度開銷都還可以接受,於是皆大歡喜…

 

但Ke Ke同學的V1 patch又踩了什么坑,導致IPI無法喚醒處於深度睡眠的處理器?原來Xen hypervisor的wakeup IPI的邏輯是,先檢查對方是否有pending的softirq。如果有,則不必發IPI以節省開銷,其原因是處理器進入深度睡眠之前都要檢查並處理自己當前pending的softirq,所以如果對方有pending softirq則肯定沒睡,那就沒必要發IPI了。V1 patch正好踩了這個坑:在CPU進入睡眠前處理完pending softirq后,新增的sched_tick_suspend()會在某些情況下設置TIMER_SOFTIRQ,於是別的處理器發wakeup IPI就‘被節省’了,再后來就是博主所說的那樣,處於深度睡眠的處理器悲催了…

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM