基於 DAMON 的 LRU 列表排序

基於 DAMON 的 LRU 列表排序 (DAMON_LRU_SORT) 是一個靜態核心模組,旨在用於基於資料訪問模式(de)優先順序的主動和輕量級頁面在其 LRU 列表上,以使 LRU 列表成為更值得信賴的資料訪問模式來源。

在何處需要主動 LRU 列表排序?

由於頁面粒度訪問檢查開銷在大型系統上可能很大,因此 LRU 列表通常不會主動排序,而是部分和被動地針對特殊事件進行排序,包括特定使用者請求、系統呼叫和記憶體壓力。因此,有時 LRU 列表並沒有很好地準備好用作某些情況(包括在突然記憶體壓力下回收目標頁面選擇)的可靠訪問模式來源。

由於 DAMON 可以識別最佳精度的訪問模式,同時僅引發使用者指定的開銷範圍,因此主動執行 DAMON_LRU_SORT 可能有助於使 LRU 列表成為更值得信賴的低且可控開銷的訪問模式來源。

它是如何工作的?

DAMON_LRU_SORT 使用 DAMON 查詢熱頁面(顯示高於使用者指定閾值的訪問速率的記憶體區域的頁面)和冷頁面(顯示在超過使用者指定的時間內沒有訪問的記憶體區域的頁面),並優先處理熱頁面,同時降低其 LRU 列表上的冷頁面的優先順序。為了避免它消耗過多的 CPU 用於優先順序排序,可以配置 CPU 時間使用限制。在該限制下,它分別優先處理和降低更多熱頁面和冷頁面的優先順序。系統管理員還可以配置在此方案應在三種記憶體壓力水位線的情況下自動啟用和停用。

其熱/冷閾值和 CPU 配額限制的預設引數經過保守選擇。也就是說,預設引數下的模組可以廣泛使用而不會對常見情況造成損害,同時為在記憶體壓力下具有清晰的熱/冷訪問模式的系統提供一定程度的優勢,同時僅消耗有限的一小部分 CPU 時間。

介面:模組引數

要使用此功能,您應該首先確保您的系統執行在構建了 CONFIG_DAMON_LRU_SORT=y 的核心上。

為了讓系統管理員啟用或停用它並針對給定系統進行調整,DAMON_LRU_SORT 利用了模組引數。也就是說,您可以將 damon_lru_sort.<parameter>=<value> 放在核心啟動命令列上,或將適當的值寫入 /sys/module/damon_lru_sort/parameters/<parameter> 檔案。

以下是每個引數的描述。

enabled

啟用或停用 DAMON_LRU_SORT。

您可以透過將此引數的值設定為 Y 來啟用 DAMON_LRU_SORT。將其設定為 N 會停用 DAMON_LRU_SORT。請注意,由於基於水位線的啟用條件,DAMON_LRU_SORT 可能不會進行真正的監控和 LRU 列表排序。有關此水位線引數,請參閱以下說明。

commit_inputs

使 DAMON_LRU_SORT 再次讀取輸入引數,除了 enabled

預設情況下,DAMON_LRU_SORT 執行時更新的輸入引數不會應用。一旦此引數設定為 Y,DAMON_LRU_SORT 會再次讀取引數的值,除了 enabled。重新讀取完成後,此引數將設定為 N。如果在重新讀取時發現無效引數,DAMON_LRU_SORT 將被停用。

hot_thres_access_freq

用於識別熱記憶體區域的訪問頻率閾值,以千分比表示。

如果記憶體區域以該頻率或更高的頻率被訪問,DAMON_LRU_SORT 會將該區域識別為熱,並在 LRU 列表上將其標記為已訪問,這樣它就不會在記憶體壓力下被回收。預設值為 50%。

cold_min_age

用於識別冷記憶體區域的時間閾值,以微秒為單位。

如果記憶體區域在該時間或更長時間內未被訪問,DAMON_LRU_SORT 會將該區域識別為冷,並在 LRU 列表上將其標記為未訪問,這樣它就可以在記憶體壓力下首先被回收。預設值為 120 秒。

quota_ms

嘗試 LRU 列表排序的時間限制,以毫秒為單位。

DAMON_LRU_SORT 嘗試在時間視窗 (quota_reset_interval_ms) 內僅使用最多此時間來嘗試 LRU 列表排序。這可用於限制 DAMON_LRU_SORT 的 CPU 消耗。如果該值為零,則停用該限制。

預設值為 10 毫秒。

quota_reset_interval_ms

時間配額充電重置間隔,以毫秒為單位。

時間配額 (quota_ms) 的充電重置間隔。也就是說,DAMON_LRU_SORT 不會嘗試在 quota_reset_interval_ms 毫秒內對 LRU 列表進行超過 quota_ms 毫秒或 quota_sz 位元組的排序。

預設值為 1 秒。

wmarks_interval

水位線檢查時間間隔,以微秒為單位。

等待檢查水位線的最小時間,當 DAMON_LRU_SORT 由於其水位線規則而啟用但未啟用時。預設值為 5 秒。

wmarks_high

高水位線的可用記憶體率(每千)。

如果系統的可用記憶體(以每千位元組的位元組數為單位)高於此值,則 DAMON_LRU_SORT 變為非活動狀態,因此它什麼也不做,只會定期檢查水位線。預設值為 200 (20%)。

wmarks_mid

中間水位線的可用記憶體率(每千)。

如果系統的可用記憶體(以每千位元組的位元組數為單位)介於此值和低水位線之間,則 DAMON_LRU_SORT 變為活動狀態,因此開始監控和 LRU 列表排序。預設值為 150 (15%)。

wmarks_low

低水位線的可用記憶體率(每千)。

如果系統的可用記憶體(以每千位元組的位元組數為單位)低於此值,則 DAMON_LRU_SORT 變為非活動狀態,因此它什麼也不做,只會定期檢查水位線。預設值為 50 (5%)。

sample_interval

監控的取樣間隔,以微秒為單位。

DAMON 用於冷記憶體監控的取樣間隔。有關更多詳細資訊,請參閱 DAMON 文件 (詳細用法)。預設值為 5 毫秒。

aggr_interval

監控的聚合間隔,以微秒為單位。

DAMON 用於冷記憶體監控的聚合間隔。有關更多詳細資訊,請參閱 DAMON 文件 (詳細用法)。預設值為 100 毫秒。

min_nr_regions

最小監控區域數。

DAMON 用於冷記憶體監控的最小監控區域數。這可用於設定監控質量的下限。但是,將其設定得太高可能會導致監控開銷增加。有關更多詳細資訊,請參閱 DAMON 文件 (詳細用法)。預設值為 10。

max_nr_regions

最大監控區域數。

DAMON 用於冷記憶體監控的最大監控區域數。這可用於設定監控開銷的上限。但是,將其設定得太低可能會導致監控質量不佳。有關更多詳細資訊,請參閱 DAMON 文件 (詳細用法)。預設值為 1000。

monitor_region_start

目標記憶體區域的起始物理地址。

DAMON_LRU_SORT 將對其執行工作的記憶體區域的起始物理地址。預設情況下,最大的系統 RAM 用作該區域。

monitor_region_end

目標記憶體區域的結束物理地址。

DAMON_LRU_SORT 將對其執行工作的記憶體區域的結束物理地址。預設情況下,最大的系統 RAM 用作該區域。

kdamond_pid

DAMON 執行緒的 PID。

如果啟用了 DAMON_LRU_SORT,則這成為工作執行緒的 PID。否則,為 -1。

nr_lru_sort_tried_hot_regions

嘗試進行 LRU 排序的熱記憶體區域的數量。

bytes_lru_sort_tried_hot_regions

嘗試進行 LRU 排序的熱記憶體區域的總位元組數。

nr_lru_sorted_hot_regions

成功進行 LRU 排序的熱記憶體區域的數量。

bytes_lru_sorted_hot_regions

成功進行 LRU 排序的熱記憶體區域的總位元組數。

nr_hot_quota_exceeds

熱區域的時間配額限制超過的次數。

nr_lru_sort_tried_cold_regions

嘗試進行 LRU 排序的冷記憶體區域的數量。

bytes_lru_sort_tried_cold_regions

嘗試進行 LRU 排序的冷記憶體區域的總位元組數。

nr_lru_sorted_cold_regions

成功進行 LRU 排序的冷記憶體區域的數量。

bytes_lru_sorted_cold_regions

成功進行 LRU 排序的冷記憶體區域的總位元組數。

nr_cold_quota_exceeds

冷區域的時間配額限制超過的次數。

示例

以下執行時示例命令使 DAMON_LRU_SORT 查詢具有 >= 50% 訪問頻率的記憶體區域並進行 LRU 優先順序排序,同時對 120 秒未訪問的記憶體區域進行 LRU 降級。優先順序排序和降級被限制為僅使用高達 1% 的 CPU 時間來完成,以避免 DAMON_LRU_SORT 消耗過多的 CPU 時間用於(de)優先順序排序。如果系統的可用記憶體率超過 50%,它還會要求 DAMON_LRU_SORT 不執行任何操作,但如果低於 40%,則開始實際工作。如果 DAMON_RECLAIM 沒有取得進展,因此可用記憶體率低於 20%,它會再次要求 DAMON_LRU_SORT 不執行任何操作,這樣我們就可以回退到基於 LRU 列表的頁面粒度回收。

# cd /sys/module/damon_lru_sort/parameters
# echo 500 > hot_thres_access_freq
# echo 120000000 > cold_min_age
# echo 10 > quota_ms
# echo 1000 > quota_reset_interval_ms
# echo 500 > wmarks_high
# echo 400 > wmarks_mid
# echo 200 > wmarks_low
# echo Y > enabled