簡介
本文将通過以 X86 為例子介紹硬體 PMU 如何為 linux kernel perf_event 子系統提供硬體性能采集功能
了解硬體
MSR (Model Specify Register)
可以了解為CPU硬體的專用寄存器,下述的所有寄存器都是這個類型
彙編指令 rdmsr/wrmsr
wrmsr 0x38d 1234 # addr value
如果是 pmc 還可以用 rdpmc 指令
rdpmc [0~7] # input ECX output EDX:EAX
在硬體 pmu 的操作過程中大多類似以下模式
- 寫入 pmc 對應的狀态 msr,決定要打開哪個硬體事件
- 通過讀取 pmc 擷取之前定義的硬體事件數值
PMCx 與 PERFEVTSELx
通用事件寄存器,成對出現,由 PERFEVTSEL 配置事件,PMC 讀取事件數值。在現代 x86 産品中被稱之為通用 pmu 裝置,一般為4個,如果關閉虛拟化可以使用8個
FIXED_CTRx 與 FIXED_CTR_CTRL
專用寄存器,通過唯一的 FIXED_CTR_CTRL 來開啟對應的 FIXED_CTRx。無事件控制,每個 FIXED_CTRx 隻能記錄對應的硬體事件
RDT (Resource Direct Tech) 是一種全新的性能采集方式,有點與上述兩種寄存器有所不同,但是在軟體接口上會更簡潔。支援 L3 cache 相關資源使用計數
它的操作過程不用定義事件類型,隻要以下步驟
- 通過 PQR_ASSOC msr寄存器寫入 rmid 就已經開始統計相關事件的計數
- 通過QM_EVTSEL 輸入要讀取的事件 id 和 rmid
- 最後通過 QM_CTR 即可獲得資料
可以看出它不再以單獨的CPU為次元,使用者可以自定義 rmid,可以用 task,也可以用 cpuid,甚至多者混合
操作
linux 系統提供了 msr 核心子產品,允許使用者可以在使用者态直接操作 msr
ls /dev/cpu/0/msr
msr 都是 per-cpu 的裝置,是以需要指定具體 cpu。 通過 lseek 來定位 msr,通過 write/read 來讀寫
通過這種方式來擷取 cpu 性能是 bypass 核心,同樣無法利用到 perf_event 子系統提供的一系列功能,比如關聯某個 task, cgroup,也無法在有限的 pmu 個數中産生分時複用
總結
硬體 PMU 的實作就是提供了一系列的可操作 MSR, 通過 MSR 操作可以靈活定義要監控的内容,但是 linux kernel 中通過實作 perf_event 子系統對使用者态提供了一套簡潔通用的操作界面
其他
PERF_EVENT 系列文章