Perf¶
Perf 事件屬性¶
- 作者:
Andrew Murray <andrew.murray@arm.com>
- 日期:
2019-03-06
exclude_user¶
此屬性排除使用者空間。
使用者空間總是在 EL0 執行,因此此屬性將排除 EL0。
exclude_kernel¶
此屬性排除核心。
核心在有 VHE 的 EL2 以及沒有 VHE 的 EL1 執行。客戶機核心總是在 EL1 執行。
對於主機,此屬性將排除 EL1,並在 VHE 系統上額外排除 EL2。
對於客戶機,此屬性將排除 EL1。請注意,EL2 永遠不會在客戶機中被計數。
exclude_hv¶
此屬性排除 Hypervisor。
對於 VHE 主機,此屬性將被忽略,因為我們認為主機核心就是 Hypervisor。
對於非 VHE 主機,此屬性將排除 EL2,因為我們認為 Hypervisor 是任何在 EL2 執行的程式碼,主要用於客戶機/主機轉換。
對於客戶機,此屬性無效。請注意,EL2 永遠不會在客戶機中被計數。
exclude_host / exclude_guest¶
這些屬性分別排除 KVM 主機和客戶機。
KVM 主機可能在 EL0(使用者空間)、EL1(非 VHE 核心)和 EL2(VHE 核心或非 VHE Hypervisor)執行。
KVM 客戶機可能在 EL0(使用者空間)和 EL1(核心)執行。
由於主機和客戶機之間的異常級別重疊,我們不能完全依賴 PMU 的硬體異常過濾 - 因此我們必須在進入和退出客戶機時啟用/停用計數。這在 VHE 和非 VHE 系統上執行的方式不同。
對於非 VHE 系統,我們為 exclude_host 排除 EL2 - 在進入和退出客戶機時,我們根據 exclude_host 和 exclude_guest 屬性適當地停用/啟用事件。
對於 VHE 系統,我們為 exclude_guest 排除 EL1,併為 exclude_host 排除 EL0 和 EL2。在進入和退出客戶機時,我們根據 exclude_host 和 exclude_guest 屬性適當地修改事件以包含/排除 EL0。
上述宣告也適用於在非 VHE 客戶機中使用這些屬性的情況,但是請注意,EL2 永遠不會在客戶機中被計數。
準確性¶
在非 VHE 主機上,我們會在 EL2 的主機/客戶機轉換的進入/退出時啟用/停用計數器 - 但是,在啟用/停用計數器與進入/退出客戶機之間存在一段時間。 透過為 exclude_host 過濾掉 EL2,我們可以消除計數器在客戶機進入/退出邊界上計數主機事件的情況(當計數客戶機事件時)。 但是,當使用 !exclude_hv 時,在客戶機進入/退出時存在一個小的中斷視窗,在此期間主機事件不會被捕獲。
在 VHE 系統上,不存在中斷視窗。
Perf 使用者空間 PMU 硬體計數器訪問¶
概述¶
perf 使用者空間工具依賴於 PMU 來監視事件。 它在硬體計數器上提供了一個抽象層,因為底層實現是 CPU 相關的。 Arm64 允許使用者空間工具直接訪問儲存硬體計數器值的暫存器。
這專門針對自監控任務,以便透過直接訪問暫存器而不必透過核心來減少開銷。
操作方法¶
重點是 armv8 PMUv3,它確保已啟用對 pmu 暫存器的訪問,並且使用者空間可以訪問相關資訊以便使用它們。
為了訪問硬體計數器,必須首先啟用全域性 sysctl kernel/perf_user_access
echo 1 > /proc/sys/kernel/perf_user_access
必須使用 perf 工具介面開啟事件,並設定 config1:1 attr 位:sys_perf_event_open 系統呼叫返回一個 fd,隨後可以將其與 mmap 系統呼叫一起使用,以便檢索包含有關事件資訊的記憶體頁。 PMU 驅動程式使用此頁向用戶公開硬體計數器的索引和其他必要資料。 使用此索引允許使用者使用 mrs 指令訪問 PMU 暫存器。 只有在序列鎖未更改時,對 PMU 暫存器的訪問才有效。 特別是,每次更改序列鎖時,PMSELR_EL0 暫存器都會歸零。
libperf 中使用 perf_evsel__mmap() 和 perf_evsel__read() 函式支援使用者空間訪問。 有關示例,請參見 tools/lib/perf/tests/test-evsel.c。
關於異構系統¶
在諸如 big.LITTLE 之類的異構系統上,只有在將任務繫結到同構核心子集並透過指定 “type” 屬性開啟相應的 PMU 例項時,才能啟用使用者空間 PMU 計數器訪問。 在這種情況下不支援使用通用事件型別。
請檢視 tools/perf/arch/arm64/tests/user-events.c 以獲取示例。 可以使用 perf 工具執行它,以檢查從使用者空間對暫存器的訪問是否正確。
perf test -v user
關於連結事件和計數器大小¶
使用者可以請求一個 32 位 (config1:0 == 0) 或 64 位 (config1:0 == 1) 計數器以及使用者空間訪問。 如果請求 64 位計數器並且硬體不支援 64 位計數器,則 sys_perf_event_open 系統呼叫將失敗。 連結事件不支援與使用者空間計數器訪問結合使用。 如果在具有 64 位計數器的硬體上請求 32 位計數器,則使用者空間必須將從計數器讀取的高 32 位視為 UNKNOWN。 使用者頁面中的 “pmc_width” 欄位將指示計數器的有效寬度,應使用該欄位根據需要遮蔽高位。
事件計數閾值¶
概述¶
FEAT_PMUv3_TH (Armv8.8) 允許 PMU 計數器僅在事件的計數滿足指定的閾值條件時才遞增。 例如,如果 threshold_compare 設定為 2(“大於或等於”),並且閾值設定為 2,則 PMU 計數器現在僅在事件先前會在單個處理器週期內將 PMU 計數器遞增 2 或更多時才遞增。
要在透過閾值條件後遞增 1,而不是該週期中的事件數,請將 “threshold_count” 選項新增到命令列。
操作方法¶
這些是用於控制該功能的引數
引數 |
描述 |
|---|---|
threshold |
用於對事件進行閾值化的值。 值為 0 表示停用閾值化,其他引數無效。 |
threshold_compare |
要使用的比較函式,支援以下值
0:不等於
1:等於
2:大於或等於
3:小於
|
threshold_count |
如果設定了此值,則在透過閾值條件後按 1 計數,而不是此週期中事件的值。 |
可以為每個事件提供 threshold、threshold_compare 和 threshold_count 值,例如
perf stat -e stall_slot/threshold=2,threshold_compare=2/ \
-e dtlb_walk/threshold=10,threshold_compare=3,threshold_count/
在此示例中,stall_slot 事件將在每次發生 2 個或更多 stall 的週期中計數 2 或更多。 dtlb_walk 將在每次 dtlb walk 數量小於 10 的週期中計數 1。
可以從每個 PMU 的 caps 讀取支援的最大閾值,例如
cat /sys/bus/event_source/devices/armv8_pmuv3/caps/threshold_max
0x000000ff
如果給定的值高於此值,則開啟事件將導致錯誤。 可能的最高最大值為 4095,因為 threshold 的 config 欄位限制為 12 位,並且 Perf 工具將拒絕解析更高的值。
如果 PMU 不支援 FEAT_PMUv3_TH,則 threshold_max 將讀取為 0,並且嘗試設定閾值也會導致錯誤。 即使主機在具有該功能的硬體上執行,threshold_max 也將在 aarch32 客戶機上讀取為 0。