iT邦幫忙

2021 iThome 鐵人賽

DAY 7
0
Software Development

閱讀 Linux Kernel 文件系列 第 7

# Day 7 Supporting PMUs on RISC-V platforms (三)

今天沒意外的話,會是 Supporting PMUs on RISC-V platforms 的最後一篇,會整理一下,perf 使用情境、RISC-V 架構上的限制、Andes 提出的解決方案、以及目前社群上提出的解決方案!

perf

perf 是一個 profiling 的工具,可分為兩種模式,perf statperf record

  • perf stat:直接測量一個程序 (process) 執行,事件發生 (e.g. context switch、cycle) 的次數。
    • 實作方式,猜想大致上會是,程序開始執行時,紀錄一次目前的計數器數值,結束的時候,再紀錄一次,然後相減計算,這樣即可得到程序執行時,事件發生的次數。
  • perf record:取樣 (sampling) 模式,基本有 2 種取樣方式,第一種在一個程序執行過程,事件每發生 x 次,紀錄一次;第二種,每秒取樣 x 次,下面以第一種取樣方式為例;
    • 實作方式則是在程序開始執行的時候,將計數器設為 MAX - x
    • 等到事件過了 x 次,計數器就會溢位 (overflow),溢位時會發生中斷,而中斷服務程式(interrupt service routine),開始運行
      • 停止計數器
      • 記錄當下的狀態
      • 重新把計數器設為 MAX - x
      • 啟動計數器
    • 繼續執行相同操作,直到程序結束

RISC-V 架構的限制

  • 大致理解 perf 的運作方式,就我們這前兩天的討論下來,RISC-V 指令集架構上的限制,主要在於 perf record
  • perf stat 最基本的功能是可以實作出來的,大致上,在程序開始執行時,讀一次 mcycle,結束時,再讀一次,計算,整個程序所耗費的 cycle 數就計算出來了;
  • perf record 不同,就如同前兩天所提到的:
    • 首先,s mode 下沒有任何寫入 HPM 相關計數器的能力,將計數器設定成某個適當的值 這件事就無法達成;
    • 再來,沒有任何計數器溢位的中斷會發生,所以並沒有能力得知溢位的發生與否
    • 沒有停止/啟動計數器的能力
    • 沒有任何 mode 相關的計數功能,無法支援 perf 跟 mode 相關的功能(e.g. 紀錄 kernel mode 下的某特定事件發生次數)

若要支援 perf record,那麼至少以上提到的這些限制,全部都需要有方法能夠處理。

Andes 的解決方案

在當時 Alan (筆者的團長兼組長) 就有提出相關的解決方案,以解決上面提到的限制。
就結論來說是新增 6 個 m mode 的暫存器:

  • 中斷:mcounterinen(Machine Counter Interrupt Enable)mcounterovf(Machine Counter Overflow)
    • 新增這兩個暫存器,當 perf 啟動時,會先將 mcounterinen 設置為 enable 狀態;
    • 而當計數器溢位發生時,mcounterovf 則會被拉起來
  • 寫入計數器:mcounterwen (Machine Counter-Write-Enable)
    • 當這個暫存器被設為 enable 時,s mode 可以對 HPM 相關的暫存器有寫入的權限
  • 開關計數器以及 mode 選擇:mcountermask_[m|s|u] (Machine Counter Mask for M-/S-/U-mode)
    • 當 mcountermask_[m|s|u] 被設置為 enable,程式執行到相對應的 mode,計數器才會開始運作(e.g. 當mcountermask_m 被設置為 enable,程式運行到 m mode 的時候,計數器才會開始增加)
    • 要關閉計數器,只需要讓 m、s、u 三個的 mcountermask 都被設置為 disable 就可以

這篇提案是目前 Andes 在 RISC-V 平台上支援 perf 的方案,並提出到社群上與大家討論。
(印象中是社群中第一個提出 HPM 相關解決方案的!XD)

社群的現況

提出方案後,社群討論的狀況很是踴躍,而且也有不少不同的廠家 (vendor) 正在準備相關的提案,後來由 Ventana: Greg Favor 提出的提案成為社群青睞的解決方案。

  • 主要也是解決上述的問題,不過這篇提案的解決方法較為全面,而且也不用新增這麼多個暫存器,總共只新增一個 s mode 暫存器
    • 中斷:利用 mhpmevent 的第 63 位元,並且連 H extension 都考慮到了,並在 interrupt 相關的暫存器上新增欄位 (mie/mip/sie/sip 的第 13 位元)
    bit [63]  OF      -  Overflow status and interrupt disable bit that is set when counter overflows
    
    63 位元的 OF 同時代表 overflow interrupt enable/disable 的狀態,
    和是否有 overflow 發生:
    當 overflow 發生時,OF 會被設置成 1;
    而當 overflow interrupt 發生時,會去檢查 OF。
    若這時候 OF 是 0,代表 interrupt 是 enable 的狀態,
    所以會產生 interrupt 並同時把 OF 設成 1;
    若這時候 OF 是 1,代表 interrupt 是 disable 的狀態,
    所以不會產生 interrupt。 
    
    • mode 選擇: 利用 mhpmevent 的 58-62 位元,來限制各個 mode 下,計數器該不該運作
    bit [62]  MINH  - If set, then counting of events in M-mode is inhibited
    bit [61]  SINH  - If set, then counting of events in S/HS-mode is inhibited
    bit [60]  UINH  - If set, then counting of events in U-mode is inhibited
    bit [59]  VSINH - If set, then counting of events in VS-mode is inhibited
    bit [58]  VUINH - If set, then counting of events in VU-mode is inhibited
    
    • 寫入計數器:這部分的話,就比較欠缺,節錄原文如下,結論是可能需要再另外討論,目前沒有訂。XD
    Although one such feature worth highlighting is having a WrEn bit in mhpmevent that allows lower privilege modes that can read the associated hpmcounter CSR (based on the *counteren CSRs) to also be able to write it.  In essence enabling direct S/VS-mode and U/VU-mode write access instead of always requiring OpenSBI calls up to M-mode.  But this feature has had some contention, involves some details to properly support virtualization, and requires allocating a second set of "User-Read-Write" hpmcounter CSR numbers (since the current hpmcounter CSRs are "User-Read-Only").  If there is a broad upwelling of support and justification for this feature, and some party willing to put together a complete spec (including virtualization support), then this could be another fast-track extension.
    
    • 新增了一個 scountovf(Supervisor Count Overflow) 暫存器
      • 這個暫存器存的是各個 mhpmcounter 的第 63 位元,用來快速辨認是哪一個 event 的計數器溢位了

這是目前這個新擴充指令集(sscof)的簡介,而目前 Linux kernel 和 QEMU 都有相關的 patch 正在被 review

後記

  • 有機會能參觀社群裡面的大神們討論真的是個有趣的體驗,而且目前提出來的方法,真的是很厲害簡潔 ((雖然看起來,還是沒有辦法直接對計數器做寫入,不過瑕不掩瑜啦XD
  • 另外是能參與到一個 ISA 規格的制定過程,想想也真是不可思議,臺灣人也是很厲害的!XDD 雖然沒有辦法用我們自家的規格說服大家,不過能這樣和各個資深的架構設計師、軟體設計師一起切磋((受教)),這個過程和努力還是很值得記錄下來的 ((Alan真猛 XD
  • 說實在的,這幾天這樣把看過的東西記錄下來,真的是有更瞭解了一些((雖然還是有很多需要再深入研究的地方 XD
  • 那麼 Supporting PMUs on RISC-V platforms 這系列就到這裡告一個段落啦!感謝各位觀看,我們明天休息一下,接下來應該就是 Cache and TLB Flushing Under Linux 的文件系列囉!

參考資料

perf

RISC-V 限制

Andes' 提案

RISC-V 社群現況


上一篇
# Day 6 Supporting PMUs on RISC-V platforms (二)
下一篇
# Day 8 Why the “volatile” type class should not be used
系列文
閱讀 Linux Kernel 文件30

1 則留言

0
高魁良
iT邦新手 4 級 ‧ 2021-09-17 23:09:45

別再一直捧我了,很害羞R。

其實當時是迴避了參考 nds32 的做法。我當時選擇的是 ppc/tile 系列的比較簡單的做法,而非 nds32/arm 那種 platform_driver 的做法,結果現在也還是要被刪掉了。

話說回來有些歷史共業的現場更妙。我從來沒有想過後來跟 Anup/Greg 他們討論的時候,他們會那麼抗拒 S-mode 可寫入的 M-mode CSR!Anup 是很堅定的拿 H-ext 來回擊,但我們當時還沒有開始考慮虛擬化,當然會覺得說,如果是 M-S-U 的話有何不可?所以有自己的架構師和硬體部門就是可以抄很多不太能夠成為正史的捷徑。

我要留言

立即登入留言