了解性能报告

时间:2018-08-29 00:39:06

标签: linux-kernel scheduling perf

我一直在从事一些对时间敏感的项目。由于时间上一些意外的尖峰,我不得不更深入一些。

场景

我有一个内核模块,该模块固定在CPU内核上。该CPU内核也在内核引导参数的isolcpus中列出。这是我对cmdline中的内核启动参数所做的

intel_iommu=on iommu=pt default_hugepagesz=1G hugepagesz=1G hugepages=1 intel_idle.max_cstate=0 processor.max_cstate=0 nohz_full=7-11 isolcpus=7-11 mce=off rcu_nocbs=7-11 nosoftlockup idle=poll cpuidle.off=1 powersave=off nonmi_ipi nowatchdog

我运行了以下命令(此刻我正在尝试仅分析CPU 8)

sudo ./perf record -e context-switches -a -g --cpu=8 taskset -c 9 ./test.sh

**编辑1-其他信息**

内核版本:4.15.12

我的内核模块每X个时间单位发送一次同步数据包。目前,我已将其配置为每50毫秒发送一次。

在这种情况下,我简化了test.sh。它需要几个参数,但是,此脚本的重要一点是它调用了内核模块。

例如, 我的KM的处理程序为fs。 在此proc fs上触发写事件时,它将创建一个新的Kthread,并将其绑定到CPU(8),并开始每50毫秒生成一个数据包。

为了避免冲突和上下文切换,我已将其移至内核空间。另外,我将脚本的相似性设置为与内核模块不同的CPU。

因此,我观察到的是,发送时间中有一些抖动,可能是由于这些上下文切换造成的。

这是我输入perf report

后的输出
# To display the perf.data header info, please use --header/--header-only options.
#
#
# Total Lost Samples: 0
#
# Samples: 8  of event 'context-switches'
# Event count (approx.): 39
#
# Children      Self  Command      Shared Object     Symbol
# ........  ........  ...........  ................  .................
#
    69.23%    69.23%  :-1          [kernel.vmlinux]  [k] do_task_dead
            |
            ---do_task_dead

    25.64%    25.64%  swapper      [kernel.vmlinux]  [k] schedule_idle
            |
            ---schedule_idle

     2.56%     2.56%  :2100        [kernel.vmlinux]  [k] _cond_resched
            |
            ---_cond_resched

     2.56%     2.56%  kworker/8:1  [kernel.vmlinux]  [k] schedule
            |
            ---schedule

它表示已经有8个上下文切换。另外,我无法理解第一行Command的{​​{1}}列中的:-1实际含义。如果有人能提供我一些指导,让我更深入地研究这个问题,那就太好了。

编辑2-性能脚本报告和cpu_idle分析结果

do_task_dead()

运行power:cpu_idle事件,这是perf脚本的输出

swapper     0 [008] 64409.434193:          1 context-switches:
                  aceea8 schedule_idle (/lib/modules/4.15.12/build/vmlinux)

:-1    -1 [008] 64410.434267:          1 context-switches:
                  2ac066 do_task_dead (/lib/modules/4.15.12/build/vmlinux)

swapper     0 [008] 64410.442240:          1 context-switches:
                  aceea8 schedule_idle (/lib/modules/4.15.12/build/vmlinux)

:29026 29026 [008] 64411.442313:          1 context-switches:
                  acee0d _cond_resched (/lib/modules/4.15.12/build/vmlinux)

kworker/8:1   181 [008] 64411.442318:          1 context-switches:
                  acebf2 schedule (/lib/modules/4.15.12/build/vmlinux)

:-1    -1 [008] 64411.442327:          1 context-switches:
                  2ac066 do_task_dead (/lib/modules/4.15.12/build/vmlinux)

swapper     0 [008] 64411.466238:          8 context-switches:
                  aceea8 schedule_idle (/lib/modules/4.15.12/build/vmlinux)

swapper     0 [008] 64414.538207:         31 context-switches:
                  aceea8 schedule_idle (/lib/modules/4.15.12/build/vmlinux)

swapper 0 [008] 65787.514565: power:cpu_idle: state=4294967295 cpu_id=8 ad3a2f cpu_idle_poll (/lib/modules/4.15.12/build/vmlinux) swapper 0 [008] 65788.514653: power:cpu_idle: state=0 cpu_id=8 ad39d0 cpu_idle_poll (/lib/modules/4.15.12/build/vmlinux) swapper 0 [008] 65788.522618: power:cpu_idle: state=4294967295 cpu_id=8 ad3a2f cpu_idle_poll (/lib/modules/4.15.12/build/vmlinux) swapper 0 [008] 65789.522693: power:cpu_idle: state=0 cpu_id=8 ad39d0 cpu_idle_poll (/lib/modules/4.15.12/build/vmlinux) swapper 0 [008] 65789.546577: power:cpu_idle: state=4294967295 cpu_id=8 ad3a2f cpu_idle_poll (/lib/modules/4.15.12/build/vmlinux) swapper 0 [008] 65790.546648: power:cpu_idle: state=0 cpu_id=8 ad39d0 cpu_idle_poll (/lib/modules/4.15.12/build/vmlinux) swapper 0 [008] 65790.570574: power:cpu_idle: state=4294967295 cpu_id=8 ad3a2f cpu_idle_poll (/lib/modules/4.15.12/build/vmlinux) .... 显示

perf report

谢谢

Coshal。

1 个答案:

答案 0 :(得分:3)

祖兰很亲密,应该遵循他的所有建议。

perf report的手册页中:

{p {1}}输出中的命令列是指从中收集样本的过程。在每个线程/每个进程模式下,这始终是受监视命令的名称。但是在cpu范围模式下,命令可能会有所不同。

由于从perf report命令可以看到per-cpu上下文切换事件,因此perf report命令将开始报告下一个/上一个任务的PID / TID。您可以在这里看到它-

per-cpu context switch records pid/tid

现在值-1表示已死的进程,即该进程已超出僵尸进程的状态。这意味着perf record ... -cpu=8...成员现在指向已经释放的内存,并且不应该取消引用。task_struct方法应该清楚地反映这一点。                                                                                                                                                                                                                This是进程的pid以-1返回并同时在do_task_dead中报告的地方。

对此问题有广泛的discussion。最初,在perf report输出中用于表示该过程状态的值为0,但您可能已经猜到,pid = 0表示 idle thread (空闲线程),因此值为-1使用。