阿里linux內核月報201701

Controlling access to the memory cache
控制對Cache的訪問
cpu對內存的訪問一直以來都會通過L1/L2/L3緩存來加速,我們都知道當你打算嚴肅地去考察性能問題時,各級緩存的命中率一直是一個重要的指標。而一個進程的緩存命中率在很大程度上又和它在各級緩存中所佔的空間大小正相關。由於緩存本身是socket範圍上的共享資源,一個進程的緩存命中率不僅取決於它自己的行爲,同時也受和它共同運行的其他進程影響,這使得工程師們很難將一個特定進程的緩存命中率維持在理想的值上。

Intel自Haswell開始的cpu已經搭載了它們的緩存控制技術。Intel把它稱爲Cache Allocation Technology,縮寫爲CAT。在本屆LinuxCon 2016上,來自Intel的Yu Fenghua向大家彙報了將這一技術集成進Linux內核的進度情況。

那麼CAT具體是怎麼工作的呢?在一個普通的Intel X86 cpu上,對於一個N-way set associative cache(N路組相聯緩存)來說,當一個64B的cache line被帶入LLC時,它的一部分虛擬地址決定了它會被hash到哪個行(或者說set)中,具體的映射算法Intel保密沒有公開。進入一個set之後,放到哪個way(或者說列)上就按照正常的淘汰算法來進行,而在一個開啓了CAT的cpu上,這時會有一個掩碼(Intel稱它爲CBM,Cache Bit Mask)介入,決定這個新cache line只能放到哪幾個way上、只能在哪幾個way的範圍之內進行淘汰。這樣就控制住了一個進程可以污染的cache範圍。爲了使用方便,這個掩碼並不會直接使用,而是通過和一個名爲CLOSID(Class of Service ID)的值聯繫在一起。Intel希望集成這一特性的OS在上下文切換時把新進程對應的CLOSID寫到一個特定的MSR寄存器裏,這樣CAT就流暢地跑起來了。

話雖如此,當Linux集成一個新特性的時候,考慮的可不僅僅是讓它跑起來這麼簡單。硬件廠商對於一個新特性的想法會持續地變化,一個通用操作系統的架構必須能夠在一定範圍內適應這種變化,它既要做好抽象,把細節屏蔽掉,使得這個框架能夠適應不同廠商的相似特性;又不能抽象得太過份,以至於某些特性無法得到支持。在集成CAT這個問題上我們再一次看到了類似的故事上演。最初的一版patch是基於cgroup寫的,經過幾輪review之後,社區的反對意見集成在cgroup這個事情本身– CAT可以有兩種配置風格,一種是像上文說的那樣,以進程或者進程組爲中心配置,這時使用cgroup是沒問題的;另一種是以cpu爲中心配置,即我們指定給某一個cpu分配某些cache,跑在它上邊的東西,不管是進程的用戶態代碼,還是陷入內核後執行的內核代碼,還是中斷處理函數,都遵守相同的分配規則。這時就無法和cgroup協調起來了,因爲整個cgroup的設計都是圍繞着進程視角來實現的。另外,CAT的掩碼作用範圍是在socket級別的,這就意味着操作系統可以允許一個進程跑在不同的socket上時使用不同的掩碼,cgroup抽象由於沒有辦法描述cpu,同樣抑制了這種用法。

放棄cgroup這個抽象之後,又有人提出了ioctl風格的接口,響應者寥寥。大家都不願意再往ioctl這個大雜燴里加東西了。

最新一版的代碼以新提出的kernfs抽象爲基礎,這是一個脫胎於sysfs的新的虛擬文件系統,cat的專屬目錄會出現在/sys/fs/resctrl下。在它之下有三個虛擬文件:tasks、cpus以及schema。tasks文件包含了被schema中的掩碼控制的進程PID。cpus則包含被這些掩碼控制的cpu編號。那麼當一個特定進程跑在一個特定cpu上,而它倆在schema中的配置衝突了該聽誰的呢?目前的策略是以cpu爲中心的配置優先。

Yu Fenghua的演講最後提到了這一新特性具體的配置方法,這可以在patchset中找到;同時他的slides裏也提到了一些性能測試,從中可以看到對於一些cache競爭嚴重的場景CAT確實會有很大作用。

Context information in memory-allocation requests
本文要解決的是內核 api 設計在歷史演進過程中的合理化問題。

大家都知道,內核的內存分配過程中,是要清楚的區分各種不同的情況的,例如:是否內存分配過程中會引起進程切換,大部分的驅動代碼的中斷處理函數中(面試中常問的問題,爲什麼中斷上下文不能發生進程切換?)。所以,linux 內核的做法一直以來也就和我們大多數人在設計 api 的時候一樣,即:加個 flag 吧,於是內核的內存分配函數變成下面的情況:

void *kmalloc(size_t size, gfp_t flags);

具體多少 flag, 看

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