詳細用法

DAMON 為不同使用者提供以下介面。

  • DAMON 使用者空間工具。 該工具適用於特權使用者,例如希望使用即插即用、人性化介面的系統管理員。使用者可以使用此工具以人性化的方式使用 DAMON 的主要功能。但它可能不會針對特殊情況進行高度最佳化。更多詳情,請參閱其使用文件

  • sysfs 介面。 該介面適用於希望更最佳化地使用 DAMON 的特權使用者空間程式設計師。透過此介面,使用者可以透過讀寫特殊的 sysfs 檔案來使用 DAMON 的主要功能。因此,您可以編寫和使用您的個性化 DAMON sysfs 包裝程式來代替您讀寫 sysfs 檔案。DAMON 使用者空間工具就是這類程式的一個例子。

  • 核心空間程式設計介面。 該介面適用於核心空間程式設計師。透過此介面,使用者可以透過為您編寫核心空間 DAMON 應用程式,最靈活、最有效地利用 DAMON 的所有功能。您甚至可以為各種地址空間擴充套件 DAMON。詳情請參閱介面文件

sysfs 介面

當定義了 CONFIG_DAMON_SYSFS 時,DAMON sysfs 介面就會構建。它在其 sysfs 目錄 <sysfs>/kernel/mm/damon/ 下建立多個目錄和檔案。您可以透過讀寫該目錄下的檔案來控制 DAMON。

一個簡單的例子是,使用者可以按如下方式監視給定工作負載的虛擬地址空間。

# cd /sys/kernel/mm/damon/admin/
# echo 1 > kdamonds/nr_kdamonds && echo 1 > kdamonds/0/contexts/nr_contexts
# echo vaddr > kdamonds/0/contexts/0/operations
# echo 1 > kdamonds/0/contexts/0/targets/nr_targets
# echo $(pidof <workload>) > kdamonds/0/contexts/0/targets/0/pid_target
# echo on > kdamonds/0/state

檔案層級

DAMON sysfs 介面的檔案層級結構如下所示。在下圖中,父子關係用縮排表示,每個目錄都有 / 字尾,每個目錄中的檔案用逗號(“,”)分隔。

/sys/kernel/mm/damon/admin
│ kdamonds/nr_kdamonds
│ │ 0/state,pid
│ │ │ contexts/nr_contexts
│ │ │ │ 0/avail_operations,operations
│ │ │ │ │ monitoring_attrs/
│ │ │ │ │ │ intervals/sample_us,aggr_us,update_us
│ │ │ │ │ │ │ intervals_goal/access_bp,aggrs,min_sample_us,max_sample_us
│ │ │ │ │ │ nr_regions/min,max
│ │ │ │ │ targets/nr_targets
│ │ │ │ │ │ 0/pid_target
│ │ │ │ │ │ │ regions/nr_regions
│ │ │ │ │ │ │ │ 0/start,end
│ │ │ │ │ │ │ │ ...
│ │ │ │ │ │ ...
│ │ │ │ │ schemes/nr_schemes
│ │ │ │ │ │ 0/action,target_nid,apply_interval_us
│ │ │ │ │ │ │ access_pattern/
│ │ │ │ │ │ │ │ sz/min,max
│ │ │ │ │ │ │ │ nr_accesses/min,max
│ │ │ │ │ │ │ │ age/min,max
│ │ │ │ │ │ │ quotas/ms,bytes,reset_interval_ms,effective_bytes
│ │ │ │ │ │ │ │ weights/sz_permil,nr_accesses_permil,age_permil
│ │ │ │ │ │ │ │ goals/nr_goals
│ │ │ │ │ │ │ │ │ 0/target_metric,target_value,current_value,nid
│ │ │ │ │ │ │ watermarks/metric,interval_us,high,mid,low
│ │ │ │ │ │ │ {core_,ops_,}filters/nr_filters
│ │ │ │ │ │ │ │ 0/type,matching,allow,memcg_path,addr_start,addr_end,target_idx,min,max
│ │ │ │ │ │ │ stats/nr_tried,sz_tried,nr_applied,sz_applied,sz_ops_filter_passed,qt_exceeds
│ │ │ │ │ │ │ tried_regions/total_bytes
│ │ │ │ │ │ │ │ 0/start,end,nr_accesses,age,sz_filter_passed
│ │ │ │ │ │ │ │ ...
│ │ │ │ │ │ ...
│ │ │ │ ...
│ │ ...

根目錄

DAMON sysfs 介面的根目錄是 <sysfs>/kernel/mm/damon/,它有一個名為 admin 的目錄。該目錄包含用於特權使用者空間程式控制 DAMON 的檔案。具有 root 許可權的使用者空間工具或守護程序可以使用此目錄。

kdamonds/

admin 目錄下,有一個名為 kdamonds 的目錄,其中包含用於控制 kdamond 的檔案(有關詳細資訊,請參閱設計文件)。最初,此目錄中只有一個檔案 nr_kdamonds。向該檔案寫入一個數字(N)會建立 0N-1 數量的子目錄。每個目錄代表一個 kdamond。

kdamonds/<N>/

在每個 kdamond 目錄中,有兩個檔案(statepid)和一個目錄(contexts)。

如果 kdamond 當前正在執行,讀取 state 將返回 on,如果未執行,則返回 off

使用者可以向 state 檔案寫入以下 kdamond 命令。

  • on: 開始執行。

  • off: 停止執行。

  • commit: 再次讀取 sysfs 檔案中除 state 檔案之外的使用者輸入。

  • update_tuned_intervals: 使用自動調整後的 取樣間隔聚合間隔 更新 kdamond 的 sample_usaggr_us 檔案的內容。更多詳細資訊,請參閱intervals_goal 部分

  • commit_schemes_quota_goals: 讀取基於 DAMON 的操作方案的配額目標

  • update_schemes_stats: 更新 kdamond 的每個基於 DAMON 的操作方案的統計檔案內容。有關統計資訊的詳細資訊,請參閱stats 部分

  • update_schemes_tried_regions: 更新 kdamond 的每個基於 DAMON 的操作方案的已嘗試區域目錄。有關基於 DAMON 的操作方案已嘗試區域目錄的詳細資訊,請參閱tried_regions 部分

  • update_schemes_tried_bytes: 僅更新 .../tried_regions/total_bytes 檔案。

  • clear_schemes_tried_regions: 清除 kdamond 的每個基於 DAMON 的操作方案的已嘗試區域目錄。

  • update_schemes_effective_quotas: 更新 kdamond 的每個基於 DAMON 的操作方案的 effective_bytes 檔案內容。更多詳細資訊,請參閱quotas 目錄

如果狀態為 on,讀取 pid 將顯示 kdamond 執行緒的 pid。

contexts 目錄包含用於控制此 kdamond 將執行的監控上下文的檔案。

kdamonds/<N>/contexts/

最初,此目錄中只有一個檔案 nr_contexts。向該檔案寫入一個數字(N)會建立 0N-1 數量的子目錄。每個目錄代表一個監控上下文(有關詳細資訊,請參閱設計文件)。目前,每個 kdamond 只支援一個上下文,因此只能向該檔案寫入 01

contexts/<N>/

在每個上下文目錄中,有兩個檔案(avail_operationsoperations)和三個目錄(monitoring_attrstargetsschemes)。

DAMON 支援多種型別的監控操作,包括虛擬地址空間和物理地址空間的監控操作。您可以透過讀取 avail_operations 檔案獲取當前執行核心上可用的監控操作集列表。根據核心配置,該檔案將列出不同的可用操作集。有關所有可用操作集及其簡要說明的列表,請參閱設計文件

您可以透過向 avail_operations 檔案中列出的某個關鍵字寫入,並從 operations 檔案中讀取,來設定和獲取 DAMON 將用於該上下文的監控操作型別。

contexts/<N>/monitoring_attrs/

用於指定監控屬性的檔案(包括所需的監控質量和效率)位於 monitoring_attrs 目錄中。具體來說,此目錄中存在兩個目錄:intervalsnr_regions

intervals 目錄下,存在三個檔案,分別用於 DAMON 的取樣間隔(sample_us)、聚合間隔(aggr_us)和更新間隔(update_us)。您可以透過讀寫這些檔案來設定和獲取以微秒為單位的值。

nr_regions 目錄下,存在兩個檔案,分別用於 DAMON 監控區域的下限和上限(minmax),它們控制著監控開銷。您可以透過讀寫這些檔案來設定和獲取這些值。

有關間隔和監控區域範圍的更多詳細資訊,請參閱設計文件(設計)。

contexts/<N>/monitoring_attrs/intervals/intervals_goal/

intervals 目錄下,還存在一個用於 sample_usaggr_us 自動調整的目錄,即 intervals_goal 目錄。在該目錄下,存在四個用於自動調整控制的檔案,即 access_bpaggrsmin_sample_usmax_sample_us。有關調整機制的內部詳情,請參閱該功能的設計文件。讀寫 intervals_goal 目錄下的這四個檔案,將顯示和更新在設計文件中以相同名稱描述的調整引數。調整從使用者設定的 sample_usaggr_us 開始。在向 state 檔案寫入 update_tuned_intervals 後,可以從 sample_usaggr_us 檔案中讀取經過調整的這兩個間隔的當前值。

contexts/<N>/targets/

最初,此目錄中只有一個檔案 nr_targets。向該檔案寫入一個數字(N)會建立 0N-1 數量的子目錄。每個目錄代表一個監控目標。

targets/<N>/

在每個目標目錄中,有一個檔案(pid_target)和一個目錄(regions)。

如果您向 contexts/<N>/operations 寫入 vaddr,則每個目標都應該是一個程序。您可以透過將程序的 pid 寫入 pid_target 檔案來向 DAMON 指定該程序。

targets/<N>/regions

對於 fvaddrpaddr 監控操作集,使用者需要設定監控目標地址範圍。對於 vaddr 操作集,這不是強制性的,但使用者可以選擇將初始監控區域設定為特定的地址範圍。更多詳細資訊,請參閱設計文件

對於此類情況,使用者可以透過向此目錄下的檔案寫入適當的值,明確地設定所需的初始監控目標區域。

最初,此目錄中只有一個檔案 nr_regions。向該檔案寫入一個數字(N)會建立 0N-1 數量的子目錄。每個目錄代表一個初始監控目標區域。

regions/<N>/

在每個區域目錄中,您會找到兩個檔案(startend)。您可以透過分別讀寫這些檔案來設定和獲取初始監控目標區域的起始和結束地址。

每個區域不應與其他區域重疊。目錄 Nend 應等於或小於目錄 N+1start

contexts/<N>/schemes/

用於基於 DAMON 的操作方案(DAMOS)的目錄。使用者可以透過讀寫此目錄下的檔案來獲取和設定方案。

最初,此目錄中只有一個檔案 nr_schemes。向該檔案寫入一個數字(N)會建立 0N-1 數量的子目錄。每個目錄代表一個基於 DAMON 的操作方案。

schemes/<N>/

在每個方案目錄中,存在七個目錄(access_patternquotaswatermarkscore_filtersops_filtersfiltersstatstried_regions)和三個檔案(actiontarget_nidapply_interval)。

action 檔案用於設定和獲取方案的操作。可以寫入和從檔案中讀取的關鍵字及其含義與設計文件中的列表相同。

target_nid 檔案用於設定遷移目標節點,這僅在 actionmigrate_hotmigrate_cold 時才有意義。

apply_interval_us 檔案用於設定和獲取方案以微秒為單位的應用間隔

schemes/<N>/access_pattern/

給定基於 DAMON 的操作方案的目標訪問模式的目錄。

access_pattern 目錄下,存在三個目錄(sznr_accessesage),每個目錄包含兩個檔案(minmax)。您可以透過分別讀寫 sznr_accessesage 目錄下的 minmax 檔案來設定和獲取給定方案的訪問模式。請注意,minmax 構成一個閉區間。

schemes/<N>/quotas/

給定基於 DAMON 的操作方案的配額目錄。

quotas 目錄下,存在四個檔案(msbytesreset_interval_mseffective_bytes)和兩個目錄(weightsgoals)。

您可以透過分別向這三個檔案寫入值,設定以毫秒為單位的時間配額、以位元組為單位的大小配額和以毫秒為單位的重置間隔。然後,DAMON 會嘗試在 reset_interval_ms 內,將 action 應用於 access_pattern 的記憶體區域時,僅使用最多 時間配額 毫秒,且僅應用於最多 bytes 位元組的記憶體區域。將 msbytes 都設定為零會停用配額限制,除非至少設定了一個目標

時間配額在內部轉換為大小配額。在轉換後的大小配額和使用者指定的大小配額之間,較小的一個將被應用。根據使用者指定的目標,有效大小配額會進一步調整。讀取 effective_bytes 將返回當前有效的尺寸配額。該檔案並非即時更新,因此使用者應透過向相關 kdamonds/<N>/state 檔案寫入特殊關鍵字 update_schemes_effective_quotas 來請求 DAMON sysfs 介面更新該檔案的統計內容。

weights 目錄下,存在三個檔案(sz_permilnr_accesses_permilage_permil)。您可以透過向 weights 目錄下的這三個檔案寫入值,以千分之幾的單位設定大小、訪問頻率和年齡的優先順序權重

schemes/<N>/quotas/goals/

給定基於 DAMON 的操作方案的自動配額調整目標目錄。

最初,此目錄中只有一個檔案 nr_goals。向該檔案寫入一個數字(N)會建立 0N-1 數量的子目錄。每個目錄代表一個目標和當前成就。在多個反饋中,使用最佳的一個。

每個目標目錄包含四個檔案,即 target_metrictarget_valuecurrent_valuenid。使用者可以透過讀寫這些檔案來設定和獲取設計文件中指定的配額自動調整目標的四個引數。請注意,使用者還應向 kdamond 目錄state 檔案寫入 commit_schemes_quota_goals 以將反饋傳遞給 DAMON。

schemes/<N>/watermarks/

給定基於 DAMON 的操作方案的水印目錄。

在 watermarks 目錄下,存在五個檔案(metricinterval_ushighmidlow),用於設定度量、度量檢查之間的時間間隔以及三個水印。您可以透過分別向這些檔案寫入來設定和獲取這五個值。

可以寫入 metric 檔案的關鍵字及其含義如下。

  • none: 忽略水印

  • free_mem_rate: 系統的空閒記憶體率(千分之幾)

The interval should written in microseconds unit.

schemes/<N>/{core_,ops_,}filters/

給定基於 DAMON 的操作方案的過濾器目錄。

core_filtersops_filters 目錄分別用於由 DAMON 核心層和操作集層處理的過濾器。filters 目錄可用於安裝過濾器,無論它們由哪個層處理。由 core_filtersops_filters 請求的過濾器將先於 filters 中的過濾器安裝。所有這三個目錄都有相同的檔案。

使用 filters 目錄可能會導致對給定過濾器在目錄檔案下的評估順序的預期有些混亂。因此,建議使用者使用 core_filtersops_filters 目錄。filters 目錄將來可能會被棄用。

最初,該目錄中只有一個檔案 nr_filters。向該檔案寫入一個數字(N)會建立 0N-1 數量的子目錄。每個目錄代表一個過濾器。過濾器按數字順序進行評估。

每個過濾器目錄包含九個檔案,即 typematchingallowmemcg_pathaddr_startaddr_endminmaxtarget_idx。您可以向 type 檔案寫入過濾器的型別。有關可用型別名稱、其含義以及它們在哪個層處理的資訊,請參閱設計文件

對於 memcg 型別,您可以透過將記憶體 cgroup 從 cgroups 掛載點的路徑寫入 memcg_path 檔案來指定感興趣的記憶體 cgroup。對於 addr 型別,您可以分別向 addr_startaddr_end 檔案指定範圍的起始和結束地址(開區間)。對於 hugepage_size 型別,您可以分別向 minmax 檔案指定範圍的最小和最大大小(閉區間)。對於 target 型別,您可以向 target_idx 檔案指定 DAMON 上下文監控目標列表中的目標索引。

您可以向 matching 檔案寫入 YN,以指定過濾器是否針對與 type 匹配的記憶體。您可以向 allow 檔案寫入 YN,以指定是否允許對滿足 typematching 的記憶體應用操作。

例如,下面將 DAMOS 操作限制為僅應用於除 /having_care_already 之外的所有記憶體 cgroup 的非匿名頁。

# cd ops_filters/0/
# echo 2 > nr_filters
# # disallow anonymous pages
echo anon > 0/type
echo Y > 0/matching
echo N > 0/allow
# # further filter out all cgroups except one at '/having_care_already'
echo memcg > 1/type
echo /having_care_already > 1/memcg_path
echo Y > 1/matching
echo N > 1/allow

有關 DAMOS 過濾器設計文件的更多詳細資訊,包括不同 allow 的多個過濾器如何工作、何時支援每個過濾器以及統計資訊的差異,請參閱DAMOS 過濾器設計文件

schemes/<N>/stats/

DAMON 會計算每個方案的統計資料。這些統計資料可用於方案的線上分析或調整。有關統計資料的更多詳細資訊,請參閱設計文件

可以透過分別讀取 stats 目錄下的檔案(nr_triedsz_triednr_appliedsz_appliedsz_ops_filter_passedqt_exceeds)來檢索統計資訊。這些檔案並非即時更新,因此您應透過向相關的 kdamonds/<N>/state 檔案寫入特殊關鍵字 update_schemes_stats,來請求 DAMON sysfs 介面更新這些檔案的內容以獲取統計資訊。

schemes/<N>/tried_regions/

此目錄最初有一個檔案 total_bytes

當特殊關鍵字 update_schemes_tried_regions 被寫入相關的 kdamonds/<N>/state 檔案時,DAMON 會更新 total_bytes 檔案,使其讀取時返回方案嘗試區域的總大小,並在此目錄下建立從 0 開始的整數命名的目錄。在相應方案的下一個應用間隔期間,每個目錄都包含檔案,這些檔案暴露了相應方案的 action 在此目錄下嘗試應用於的每個記憶體區域的詳細資訊。這些資訊包括區域的地址範圍、nr_accessesage

向相關的 kdamonds/<N>/state 檔案寫入 update_schemes_tried_bytes 將僅更新 total_bytes 檔案,而不會建立子目錄。

當另一個特殊關鍵字 clear_schemes_tried_regions 被寫入相關的 kdamonds/<N>/state 檔案時,這些目錄將被刪除。

此目錄的預期用途是調查方案的行為,以及類查詢的有效資料訪問監控結果檢索。特別是對於後一種用例,使用者可以將 action 設定為 stat,並將 access pattern 設定為他們想要查詢的感興趣模式。

tried_regions/<N>/

在每個區域目錄中,您會找到五個檔案(startendnr_accessesagesz_filter_passed)。讀取這些檔案將顯示相應基於 DAMON 的操作方案 action 嘗試應用的區域屬性。

示例

以下命令應用了一個方案,該方案表示:“如果記憶體區域的大小在 [4KiB, 8KiB] 之間,並且在 [10, 20] 的聚合間隔內,每聚合間隔的訪問次數在 [0, 5] 之間,則將該區域換出。對於換出操作,每秒僅使用最多 10 毫秒,並且每秒換出不超過 1GiB 的記憶體。在此限制下,優先換出年齡較長的記憶體區域。此外,每 5 秒檢查一次系統的空閒記憶體率,當空閒記憶體率低於 50% 時開始監控和換出,但如果空閒記憶體率大於 60% 或低於 30% 則停止。”

# cd <sysfs>/kernel/mm/damon/admin
# # populate directories
# echo 1 > kdamonds/nr_kdamonds; echo 1 > kdamonds/0/contexts/nr_contexts;
# echo 1 > kdamonds/0/contexts/0/schemes/nr_schemes
# cd kdamonds/0/contexts/0/schemes/0
# # set the basic access pattern and the action
# echo 4096 > access_pattern/sz/min
# echo 8192 > access_pattern/sz/max
# echo 0 > access_pattern/nr_accesses/min
# echo 5 > access_pattern/nr_accesses/max
# echo 10 > access_pattern/age/min
# echo 20 > access_pattern/age/max
# echo pageout > action
# # set quotas
# echo 10 > quotas/ms
# echo $((1024*1024*1024)) > quotas/bytes
# echo 1000 > quotas/reset_interval_ms
# # set watermark
# echo free_mem_rate > watermarks/metric
# echo 5000000 > watermarks/interval_us
# echo 600 > watermarks/high
# echo 500 > watermarks/mid
# echo 300 > watermarks/low

請注意,強烈建議使用像 damo 這樣的使用者空間工具,而不是如上所述手動讀寫檔案。上述內容僅為一個示例。

監控結果的跟蹤點

使用者可以透過 tried_regions 獲取監控結果。此介面對於獲取快照很有用,但對於完整記錄所有監控結果可能效率不高。為此,提供了兩個跟蹤點,即 damon:damon_aggregateddamon:damos_before_applydamon:damon_aggregated 提供完整的監控結果,而 damon:damos_before_apply 提供每個基於 DAMON 的操作方案(DAMOS)將要應用的區域的監控結果。因此,damon:damos_before_apply 對於記錄 DAMOS 的內部行為,或基於 DAMOS 目標訪問模式的類查詢的高效監控結果記錄更有用。

當監控開啟時,您可以使用支援跟蹤點的工具(如 perf)記錄跟蹤點事件並顯示結果。例如

# echo on > kdamonds/0/state
# perf record -e damon:damon_aggregated &
# sleep 5
# kill 9 $(pidof perf)
# echo off > kdamonds/0/state
# perf script
kdamond.0 46568 [027] 79357.842179: damon:damon_aggregated: target_id=0 nr_regions=11 122509119488-135708762112: 0 864
[...]

perf 指令碼輸出的每一行代表一個監控區域。前五個欄位與其他跟蹤點輸出通常相同。第六個欄位(target_id=X)顯示該區域監控目標的 ID。第七個欄位(nr_regions=X)顯示該目標的監控區域總數。第八個欄位(X-Y:)顯示該區域的起始(X)和結束(Y)地址(以位元組為單位)。第九個欄位(X)顯示該區域的 nr_accesses(有關計數器的更多詳細資訊,請參閱設計文件)。最後,第十個欄位(X)顯示該區域的 age(有關計數器的更多詳細資訊,請參閱設計文件)。

如果事件是 damon:damos_beofre_apply,則 perf script 輸出將大致如下所示

kdamond.0 47293 [000] 80801.060214: damon:damos_before_apply: ctx_idx=0 scheme_idx=0 target_idx=0 nr_regions=11 121932607488-135128711168: 0 136
[...]

輸出的每一行代表一個監控區域,即在跟蹤時刻即將應用每個基於 DAMON 的操作方案的區域。前五個欄位照常。除了 damon_aggregated 跟蹤點的輸出外,它還顯示方案在上下文的 kdamond 上下文列表中的 DAMON 上下文索引(ctx_idx=X),以及方案在上下文方案列表中的索引(scheme_idx=X)。