pcid support in upstream kernel

asid在x86中最多可以用4096個,內核維護者們也嘗試了不同的方法來利用pcid,比如上一篇中提到的方法,還有的嘗試給每一個進程分配一個asid,這種方式在一些特殊的系統裏沒有效果,比如光cpu就有上千個的系統,總之各有利弊。最終內核維護者Andy Lutomirski 開發了一個新的思路。


給每個cpu分配6個槽來緩存6個最近被調度的進程上下文,每個槽一個ctx_id和tlb_gen。ctx_id是一個全局唯一的變量表示進程用,tlb_gen表示進程的tlb的時間戳。也就是說每個cpu的tlb中最多緩存6個進程的tlb表項,當一個進程被調入時會查找是否有緩存,有的話比較時間戳是否已經變舊,變舊說明進程在其它地方更改了頁表,需要刷新當前cpu的tlb,如果沒有變舊,那切換頁表也不用刷新tlb。如果沒有緩存那就分配一個槽,並始終刷新tlb。在這種設計下也不用給lazy模式的cpu發送ipi,因爲lazy模式運行內核線程,不會訪問用戶空間。有個例外就是進程釋放頁表以後,這時候會給所有相關cpu發送ipi包括lazy模式的cpu,因爲cpu的猜測執行機制還是有可能會訪問用戶態空間即使執行的是內核線程。而頁表中有可能放的是垃圾數據,如果不幸訪問到外設空間的話就會是一場災難,你有可能會碰到無法解釋的io error,或者系統在某個時刻突然crash卻難以找到根源。這個問題一度困擾了我,於是發郵件給社區尋求幫助,作者的解釋很清楚地說明了原因。
https://lkml.org/lkml/2019/5/29/573

 

如果打開PTI的話,那TLB中最多緩存12個頁表上下文,如果每個cpu上活躍進程不超過6個,那進程切換,用戶態內核態切換都不會刷新tlb,極大的優化了性能。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章