天天看點

Remote Memcg 計數

原文連結 Remote memory control-group charging 譯者:棄餘

Memory control groups (以下簡稱 Memcg) 用來跟蹤和限制程序的記憶體使用。通常情況下,我們不希望出現這樣的行為,即歸屬于一個 memcg 的記憶體使用被計數到另一個 memcg 上。然而,Shakeel Butt 在 LSFMM Summit 2019 上提出,這種行為(以下簡稱 remote charging)在很多情況下會發生。Remote charging 通常是個問題,但偶爾也是一個有用的特性。

Remote charging 最常見的場景之一是,由多個 memcg 共享的一頁記憶體被交換出去。當該頁被換回時,它會被計數到起初配置設定它的 memcg,即使這個 memcg 已經很久不用該頁。這可能會導緻令人驚訝的情況,例如一個 memcg 中的 page fault 會導緻另一個 memcg 的記憶體回收甚至 OOM(out of memory)(譯者了解:memcg-1 page fault,請求的頁面是共享頁面,且被換出 -> page(s) swapin -> 請求的頁面起初是 memcg-2 配置設定的,換回時計數到 memcg-2 -> 計數後可能由于 memory.limit/memory.high 等限制觸發記憶體回收,甚至回收失敗導緻 OOM)。Remote charging 還有可能發生在

userfaultfd()

的使用場景中,控制程序(譯者了解:UFFD ioctl 相關程序)所配置設定的記憶體會被計數到缺頁處理程序上。這種行為可以通過

ptrace()

跟蹤程序觀察到,甚至可以顯示調用

get_user_pages_remote

來觀察。有時候,核心空間中配置設定的記憶體也會被 remote charged。

Michal Hocko 特别提問了

userfaultfd()

,想知道控制過程與缺頁處理程序運作在不同 memcg 中的頻率。 Shakeel Butt 回答說他不知道,但是 remote charing 是有記錄的。 Michal Hocko 認為在不同的組中運作通常不是一個好主意,并表示他不願意将代碼複雜化以用于隻是理論發生但在現實世界中不太可能發生的用例。

Shakeel Butt 提到的一個核心用例是當在頁面上觸發寫回時,緩沖區頭(buffer_head)的配置設定。 這可能會在全局記憶體回收過程或者其他路徑上發生。 這些緩沖區頭将被計數到回寫頁面歸屬的 memcg 中,即使該 memcg 與觸發回寫的任務沒有任何關系(譯者了解:memcg-1 觸發 global reclaim,導緻 memcg-2 的頁面被全局回收寫回)。

Remote charging 特殊點在于它繞過了

memory.high

的限制(譯者了解:

memory.high

memory.limit_in_bytes

功能類似,但更為嚴格),該限制不會發生在 remote charged 的記憶體配置設定上。Rik van Riel 提問了這種問題的發生頻率;Shakeel Butt沒有确切的回答,隻是說他已經看到此類現象。Michal Hocko 表示,如果 1% 的記憶體配置設定是以這種方式進行 remote charged,其實真的沒多大影響;某個 memcg 中程序的記憶體配置設定總還是會被計數,并最終觸發限制。但是在記憶體配置設定極不均勻的用例中,這可能是個問題。

某些場景下,remote charging 的用例真實存在。一些使用者希望通過将 VM (virtual machine) 和 VMM (vm monitor) 運作在不同的 memcg 中來分離虛拟化負載。顯然,這麼做的主要目的是為了擷取 VMM 的運作時開銷。目前做法是建立一個 tmpfs 檔案系統,并綁定到自己的 memcg;所有的記憶體配置設定都将計入該 memcg。但是僅有一個小問題:如果 VM 被銷毀(例如被 OOM 殺死),tmpfs 檔案系統會保留,一直占據記憶體。為了解決這個問題,核心添加了比較 hack 的方式,以發送有關 OOM kill 的特殊通知,以便有人可以清理 tmpfs 檔案。

Shakeel Butt 描述了他的新想法:tmpfs 檔案可以附加到一個特殊的虛拟程序中,該程序會被 OOM killer 感覺。當程序被殺死時,檔案将被截斷;它本質上是 OOM-killable tmpfs 檔案。 Johannes Weiner 表示,這種機制過于具體,無法推到 upstream。 不過,Van Riel 建議可以提一個更新檔實作一個新的 tmpfs mount flag,進而推到 upstream。 如果附加到指定挂載點的 memcg 被殺,那麼對應的檔案系統将自動删除其内容。

Hugh Dickins 表示,OOM kill 和 tmpfs 的問題很常見,是以最好在這裡找到某種解決方案。Weiner 說實作它的最佳位置可能是在

oomd

(user-space OOM daemon) 中。 這種政策很難放入核心的 OOM killer 邏輯中,因為核心 OOM killer 主要是為了保護整個系統。 特定資源控制政策的實作也許最好放在使用者空間程序中。

繼續閱讀