使用RCU_CPU_STALL_CPUTIME
=====================
在編譯內核時打開CONFIG_RCU_CPU_STALL_CPUTIME=y
或者在啟動參數中增加
rcupdate.rcu_cpu_stall_cputime=1
, 這樣在發生RCU STALL告警時就會有下面附加信息:
rcu: hardirqs softirqs csw/systemrcu: number: 624 45 0rcu: cputime: 69 1 2425 ==> 2500(ms)
這樣統計信息是在采樣周期中收集的。其中number
行分別是發生stalled的cpu上的硬中斷,軟中斷,和上下文的切換次數
cputime
行的前三列分別是硬中斷,軟中斷和任務消耗的cpu時間,單位為ms.最后一個數字是統計的周期時間(ms).
因為用戶態的任務通常不會引起RCU CPU stalls,所以任務通常是內核任務,這也是為什么只統計system cpu的原因.
采樣周期如下圖所示::
|<------------first timeout---------->|<-----second timeout----->||<--half timeout-->|<--half timeout-->| || |<--first period-->| || |<-----------second sampling period---------->|| | | |snapshot time point 1st-stall 2nd-stall
下面展示4種典型的場景:
- 有關閉中斷后的CPU循環
rcu: hardirqs softirqs csw/systemrcu: number: 0 0 0rcu: cputime: 0 0 0 ==> 2500(ms)
因為中斷被關閉,因此沒有中斷和上下文切換。同時cpu time是在中斷處理中統計的,所以也是0.
這處場景通常還會有 "(0 ticks this GP)"
打印出來.
-
有關閉下半部后的CPU循環.
這種情況和第1種情況類似,但是硬中斷和上下文切換是有統計的:
rcu: hardirqs softirqs csw/systemrcu: number: 624 0 0rcu: cputime: 49 0 2446 ==> 2500(ms)
softirqs是0說明軟中斷被禁用,通常通過local_bh_disable()
.
-
有關閉搶占情況下的CPU循環.
這種情況下,只有上下文切換次數為0:
rcu: hardirqs softirqs csw/systemrcu: number: 624 45 0rcu: cputime: 69 1 2425 ==> 2500(ms)
- 沒有循環操作,但是有大量的硬件和軟中斷.
rcu: hardirqs softirqs csw/systemrcu: number: xx xx 0rcu: cputime: xx xx 0 ==> 2500(ms)
這種情況下,硬中斷和軟中斷不為0,但是上下文切換次數和sys cpu時間為0
軟中斷也有可能為0,比如在硬中斷處理里有cpu spinning.
如果遇到此種情況的CPU stall. 可以進一步查看/proc/interrupts或者通過代碼trace每種中斷,可以參考show_interrupts()
.