了解 Linux Perf sched-switch 和 context-switches
我一直在嘗試在 perf 上啟用上下文切換事件,並使用 perf.data 中的 perf 腳本轉儲來調查執行緒阻塞時間。
到目前為止,似乎有幫助的僅有的兩個記錄選項是上下文切換和所有 sched 事件。
這是我在 perf 上執行的命令:
perf record -g -a -F 999 -e cpu-clock,sched:sched_stat_sleep,sched:sched_switch,sched:sched_process_exit,context-switches
但是,兩者似乎都不完整,通常 sched_switch 事件看起來像這樣:
comm1 0/0 [000] 0.0: 1 sched:sched_switch: prev_comm=comm1 prev_pid=0 prev_prio=0 prev_state=S ==> next_comm=comm2 next_pid=1 next_prio=1 stacktrace...
據我了解,prev_comm 始終是要被阻塞的執行緒,而 next_comm 是要被解除阻塞的執行緒。這是一個正確的假設嗎?如果是這樣,我似乎無法獲得有關事件的完整數據,因為有許多執行緒在 prev_comm 上被阻塞,但似乎從未獲得相應的 next_comm。
啟用上下文切換似乎沒有多大作用,因為沒有關於執行緒被阻塞或解除阻塞的資訊(除非我完全遺漏了一些東西,我希望能解釋一下它們是如何工作的)。
典型的上下文切換事件如下所示:
comm1 0/0 [000] 0.0: 1 context-switch: stacktrace...
tl;博士,我如何通過 perf 腳本的輸出在 linux 上進行阻塞時間調查,以及需要在 perf 記錄上啟用哪些選項?
謝謝。
我知道這個問題已經很老了(2 月 16 日),但這裡有一個回复,以防它幫助別人。問題是您輸入了“-F 999”,表明您希望以每秒 999 次的頻率對事件進行採樣。對於“跟踪”事件,您通常不想進行採樣。例如,當我選擇 sched:sched_switch 時,我想查看每個上下文切換。如果您輸入 -F 999 那麼您將獲得上下文切換的樣本…如果您查看“性能記錄”cmd 的輸出,例如:
perf script --verbose -I --header -i perf.dat -F comm,pid,tid,cpu,time,period,event,trace,ip,sym,dso > perf.txt
那麼您會看到“句點”(時間戳和事件名稱之間的數字)不會(通常)是 == 1。
如果您使用如下所示的“性能記錄”cmd,您將在“性能腳本”輸出中看到一個 1 的句點,例如:
Binder:695_5 695/2077 [000] 16231.700440: 1 sched:sched_switch: prev_comm=Binder:695_5 prev_pid=2077 prev_prio=120 prev_state=S ==> next_comm=kworker/u16:17 next_pid=7665 next_prio=120
一個冗長的解釋,但基本上:不要那樣做(“那個”是“-F 999”)。
如果您只是執行以下操作:
perf record -a -g -e sched:sched_switch -e sched:sched_blocked_reason -e sched:sched_stat_sleep -e sched:sched_stat_wait sleep 5
然後輸出將顯示每個上下文切換以及每個事件的呼叫堆棧。你可能需要這樣做:
echo 1 > /proc/sys/kernel/sched_schedstats
獲取 sched_stat 事件。