頁面分配器

核心頁面分配器服務於所有通用頁面分配請求,例如 kmalloc。 CXL 配置步驟會根據所選的記憶體區域和容量所在的 NUMA 節點 影響頁面分配器的行為。

本節主要關注這些配置如何影響頁面分配器(截至 Linux v6.15),而不是整體頁面分配器行為。

NUMA 節點和記憶體策略

除非任務顯式註冊記憶體策略,否則 Linux 核心的預設記憶體策略是首先從本地 NUMA 節點分配記憶體,並且僅在本地節點受到壓力時才回退到其他節點。

通常,我們期望在單獨的 NUMA 節點上看到本地 DRAM 和 CXL 記憶體,其中 CXL 記憶體是非本地的。 然而,從技術上講,計算節點有可能沒有本地 DRAM,並且 CXL 記憶體是該計算節點的本地容量。

記憶體區域

CXL 容量可以在 ZONE_NORMALZONE_MOVABLE 中上線。

截至 v6.15,頁面分配器首先嚐試從本地節點為分配分配最高可用和相容的 ZONE。

區域不相容的一個例子是嘗試從 ZONE_MOVABLE 提供標記為 GFP_KERNEL 的分配。 核心分配通常是不可遷移的,因此只能從 ZONE_NORMAL 或更低的區域提供服務。

為了簡化這一點,頁面分配器預設會優先選擇 ZONE_MOVABLE 而不是 ZONE_NORMAL,但如果 ZONE_MOVABLE 耗盡,它將回退到從 ZONE_NORMAL 分配。

區域和節點怪癖

讓我們考慮這樣一種配置,其中本地 DRAM 容量主要上線到 ZONE_NORMAL,而沒有 ZONE_MOVABLE 容量。 CXL 容量具有相反的配置 - 全部在 ZONE_MOVABLE 中上線。

在預設分配策略下,頁面分配器將完全跳過 ZONE_MOVABLE 作為有效的分配目標。 這是因為,截至 Linux v6.15,頁面分配器會(大致)執行以下操作

for (each zone in local_node):

  for (each node in fallback_order):

    attempt_allocation(gfp_flags);

由於本地節點沒有 ZONE_MOVABLE,因此 CXL 節點在功能上無法直接分配。 因此,使用 CXL 容量的唯一方法是透過回收路徑中的降級

這種配置還意味著,如果 DRAM 節點具有 ZONE_MOVABLE 容量 - 當該容量耗盡時,頁面分配器實際上會優先選擇 CXL ZONE_MOVABLE 頁面而不是 DRAM ZONE_NORMAL 頁面。

我們可能希望在未來的 Linux 版本中反轉此優先順序。

如果停用降級交換,Linux 將在 DRAM 節點耗盡時開始導致 OOM 崩潰。 有關更多詳細資訊,請參見回收部分。

CGroups 和 CPUSets

最後,假設 CXL 記憶體可以透過頁面分配訪問(即,線上在 ZONE_NORMAL 中),cpusets.mems_allowed 可以被容器使用,以限制該容器中任務對某些 NUMA 節點的訪問。 使用者可能希望在多租戶系統中使用它,其中一些任務不希望使用速度較慢的記憶體。

在回收部分,我們將討論此介面的一些限制,以防止共享資料降級到 CXL 記憶體(如果啟用了降級)。