了解 Linux Perf 调度切换和上下文切换

了解 Linux Perf 调度切换和上下文切换

我一直在尝试在 perf 上启用上下文切换事件,并使用 perf 脚本的 perf.data 转储来调查线程阻塞时间。

到目前为止,唯一两个似乎有用的记录选项是上下文切换和所有计划事件。

这是我在 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;dr,如何通过 perf 脚本的输出在 Linux 上进行阻塞时间调查以及需要在 perf 记录上启用哪些选项?

谢谢。

答案1

我知道这个问题已经很老了(2 月 16 日),但这里有一个回复,以防对其他人有帮助。问题在于您输入了“-F 999”,表示您希望以每秒 999 次的频率对事件进行采样。对于“跟踪”事件,您通常不想进行采样。例如,当我选择 sched:sched_switch 时,我想查看每个上下文切换。如果您输入 -F 999 那么您将获得上下文切换的样本...如果您使用以下内容查看“perf record”cmd 的输出:

perf script --verbose -I --header -i perf.dat -F comm,pid,tid,cpu,time,period,event,trace,ip,sym,dso > perf.txt

那么您会看到“句点”(时间戳和事件名称之间的数字)(通常)不会 == 1。

如果您使用如下所示的“perf record”cmd,您将在“perf script”输出中看到一个周期 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

一个冗长的解释,但基本上是:不要这样做(其中“that”是“-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 事件。

相关内容