ftrace主要是用于调试linux kernel调度相关的一个工具,也可用于分析部分kernel性能问题。

相关ftrace的介绍可以参考:kernel/msm-4.9/Documentation/trace/ftrace.txt 以及同级目录下的其他介绍文件。

kernel.org的ftrace文档也可以参考(信息较多):https://www.kernel.org/doc/html/latest/trace/ftrace.html

谷歌官网的ftrace使用教程(请自带梯子):https://source.android.google.cn/devices/tech/debug/ftrace

IBM developer的blog(介绍每个跟踪器,并且写了如何看ftrace的log,很有用,很有用,很有用):https://www.ibm.com/developerworks/cn/linux/l-cn-ftrace2/index.html

一、trace_event

trace event作为ftrace的一部分,它主要通过已有函数插桩的tracepoint,来跟踪相关事件。

例如,在进程调度关键函数:__schedule()中:

static void __sched notrace __schedule(bool preempt)
{
...
if (likely(prev != next)) {
if (!prev->on_rq)
prev->last_sleep_ts = wallclock; update_task_ravg(prev, rq, PUT_PREV_TASK, wallclock, );
update_task_ravg(next, rq, PICK_NEXT_TASK, wallclock, );
rq->nr_switches++;
rq->curr = next;
++*switch_count; trace_sched_switch(preempt, prev, next);
rq = context_switch(rq, prev, next, cookie); /* unlocks the rq */
} else {
update_task_ravg(prev, rq, TASK_UPDATE, wallclock, );
lockdep_unpin_lock(&rq->lock, cookie);
raw_spin_unlock_irq(&rq->lock);
}
...
}

利用trace event,我们能够监控某些事件,是否发生;或者在某段时间内,发生了什么。

案例:在dim idle下,耗流偏大约10mA。

dim idle是屏幕亮着,但亮度最低,系统进入idle状态,而未进入深度休眠的状态。

1、在抓取了power waveform对比正常的机器,发生耗流波形的bottom与正常的相似。但是耗流bottom很不稳定。

(异常)

(正常)

2、在检查所有外设后,并未发现有明显漏电。

3、此时,就利用ftrace的trace event,抓取在此情况下,系统到底在运行什么。

抓取方法:

Step 

Connect USB and execute below commands one by one , some times all commands in batch may not work due to adb file system issues
Verify Buffer size is reflected as the one that is set adb shell "echo 0 > /sys/kernel/debug/tracing/tracing_on"
adb shell "cat /sys/kernel/debug/tracing/tracing_on"
adb shell "echo 150000 > /sys/kernel/debug/tracing/buffer_size_kb"
adb shell "cat /sys/kernel/debug/tracing/buffer_size_kb" adb shell "echo > /sys/kernel/debug/tracing/set_event"
adb shell cat /sys/kernel/debug/tracing/set_event
adb shell "echo > /sys/kernel/debug/tracing/trace"
adb shell cat /sys/kernel/debug/tracing/trace
adb shell sync Step Enable below trace events adb shell "echo 1 > /sys/kernel/debug/tracing/events/power/cpu_idle/enable"
adb shell "echo 1 > /sys/kernel/debug/tracing/events/power/cpu_frequency/enable"
adb shell "echo 1 > /sys/kernel/debug/tracing/events/power/cpu_frequency_switch_start/enable"
adb shell "echo 1 > /sys/kernel/debug/tracing/events/msm_low_power/*/enable"
adb shell "echo 1 > /sys/kernel/debug/tracing/events/sched/sched_switch/enable"
adb shell "echo 1 > /sys/kernel/debug/tracing/events/sched/sched_wakeup/enable"
adb shell "echo 1 > /sys/kernel/debug/tracing/events/sched/sched_wakeup_new/enable"
adb shell "echo 1 > /sys/kernel/debug/tracing/events/sched/sched_enq_deq_task/enable" adb shell "echo 1 > /sys/kernel/debug/tracing/events/msm_bus/bus_update_request/enable"
adb shell "echo 1 > /sys/kernel/debug/tracing/events/clk/clk_set_rate/enable"
adb shell "echo 1 > /sys/kernel/debug/tracing/events/clk/clk_enable/enable"
adb shell "echo 1 > /sys/kernel/debug/tracing/events/clk/clk_disable/enable"
adb shell "echo 1 > /sys/kernel/debug/tracing/events/power/bw_hwmon_update/enable"
adb shell "echo 1 > /sys/kernel/debug/tracing/events/power/bw_hwmon_meas/enable"
adb shell "echo 1 > /sys/kernel/debug/tracing/events/power/memlat_dev_meas/enable"
adb shell "echo 1 > /sys/kernel/debug/tracing/events/power/memlat_dev_update/enable" adb shell "echo 1 > /sys/kernel/debug/tracing/events/power/cpu_idle/enable"
adb shell "echo 1 > /sys/kernel/debug/tracing/events/power/cpu_frequency/enable"
adb shell "echo 1 > /sys/kernel/debug/tracing/events/power/cpu_frequency_switch_start/enable"
adb shell "echo 1 > /sys/kernel/debug/tracing/events/msm_low_power/*/enable"
adb shell "echo 1 > /sys/kernel/debug/tracing/events/sched/sched_switch/enable"
adb shell "echo 1 > /sys/kernel/debug/tracing/events/sched/sched_wakeup/enable"
adb shell "echo 1 > /sys/kernel/debug/tracing/events/sched/sched_wakeup_new/enable"
adb shell "echo 1 > /sys/kernel/debug/tracing/events/sched/sched_enq_deq_task/enable"
adb shell "echo 1 > /sys/kernel/debug/tracing/events/msm_low_power/cluster_enter/enable"
adb shell "echo 1 > /sys/kernel/debug/tracing/events/msm_low_power/cluster_exit/enable"
adb shell "echo 1 > /sys/kernel/debug/tracing/events/msm_low_power/cluster_pred_hist/enable"
adb shell "echo 1 > /sys/kernel/debug/tracing/events/msm_low_power/cluster_pred_select/enable"
adb shell "echo 1 > /sys/kernel/debug/tracing/events/msm_low_power/cpu_idle_enter/enable"
adb shell "echo 1 > /sys/kernel/debug/tracing/events/msm_low_power/cpu_idle_exit/enable"
adb shell "echo 1 > /sys/kernel/debug/tracing/events/msm_low_power/cpu_power_select/enable"
adb shell "echo 1 > /sys/kernel/debug/tracing/events/msm_low_power/cpu_pred_hist/enable"
adb shell "echo 1 > /sys/kernel/debug/tracing/events/msm_low_power/cpu_pred_select/enable" adb shell "echo 1 > /sys/kernel/debug/tracing/events/kgsl/adreno_cmdbatch_queued/enable"
adb shell "echo 1 > /sys/kernel/debug/tracing/events/kgsl/adreno_cmdbatch_submitted/enable"
adb shell "echo 1 > /sys/kernel/debug/tracing/events/kgsl/adreno_cmdbatch_retired/enable"
adb shell "echo 1 > /sys/kernel/debug/tracing/events/kgsl/kgsl_gpubusy/enable"
adb shell "echo 1 > /sys/kernel/debug/tracing/events/kgsl/kgsl_pwr_request_state/enable"
adb shell "echo 1 > /sys/kernel/debug/tracing/events/kgsl/kgsl_pwr_set_state/enable"
adb shell "echo 1 > /sys/kernel/debug/tracing/events/kgsl/kgsl_pwrstats/enable"
adb shell "echo 1 > /sys/kernel/debug/tracing/events/kgsl/kgsl_buslevel/enable"
adb shell "echo 1 > /sys/kernel/debug/tracing/events/kgsl/kgsl_pwrlevel/enable"
adb shell "echo 1 > /sys/kernel/debug/tracing/events/kgsl/kgsl_clk/enable"
adb shell "echo 1 > /sys/kernel/debug/tracing/events/kgsl/kgsl_bus/enable"
adb shell "echo 1 > /sys/kernel/debug/tracing/events/kgsl/kgsl_rail/enable"
adb shell "echo 1 > /sys/kernel/debug/tracing/events/kgsl/dispatch_queue_context/enable"
adb shell "echo 1 > /sys/kernel/debug/tracing/events/kgsl/kgsl_user_pwrlevel_constraint/enable"
adb shell "echo 1 > /sys/kernel/debug/tracing/events/kgsl/kgsl_clock_throttling/enable"
adb shell "echo 1 > /sys/kernel/debug/tracing/events/kgsl/kgsl_constraint/enable"
adb shell "echo 1 > /sys/kernel/debug/tracing/events/kgsl/adreno_gpu_fault/enable"
adb shell "echo 1 > /sys/kernel/debug/tracing/events/kgsl/adreno_cmdbatch_fault/enable"
adb shell "echo 1 > /sys/kernel/debug/tracing/events/kgsl/adreno_cmdbatch_sync/enable"
adb shell "echo 1 > /sys/kernel/debug/tracing/events/kgsl/kgsl_issueibcmds/enable"
adb shell "echo 1 > /sys/kernel/debug/tracing/events/kgsl/kgsl_context_create/enable"
adb shell "echo 1 > /sys/kernel/debug/tracing/events/kgsl/kgsl_context_destroy/enable"
adb shell "echo 1 > /sys/kernel/debug/tracing/events/kgsl/kgsl_context_detach/enable"
adb shell "echo 1 > /d/tracing/events/msm_bus/bus_update_request/enable"
adb shell "echo 1 > /d/tracing/events/msm_bus/bus_agg_bw/enable" Step Verify the trace events and also remove any previous trace file
adb shell cat /sys/kernel/debug/tracing/set_event
adb shell rm /data/local/trace.txt Step : Start Usecase, Execute below commands with usb and disconnect usb within seconds adb shell
cd /d/tracing
sleep && echo > tracing_on && echo "" > trace && echo > tracing_on && sleep && echo > tracing_on && cat trace > /data/local/trace.txt & Step : After seconds, re-connect usb and pull the trace file adb pull /data/local/trace.txt

4、我们找到了qsee_logger在每60ms,就会运行一次。这个是一个debug qsee的log工具,应该在版本中剔除。

         <idle>-     [] dns3 17167.350289: sched_wakeup: comm=qsee_logger pid= prio= target_cpu=
<idle>- [] dns3 17167.410357: sched_wakeup: comm=qsee_logger pid= prio= target_cpu=
<idle>- [] dns3 17167.470370: sched_wakeup: comm=qsee_logger pid= prio= target_cpu=
<idle>- [] dns3 17167.538874: sched_wakeup: comm=qsee_logger pid= prio= target_cpu=
<idle>- [] dns3 17167.608888: sched_wakeup: comm=qsee_logger pid= prio= target_cpu=
<idle>- [] dns3 17167.671269: sched_wakeup: comm=qsee_logger pid= prio= target_cpu=

5、最后使用performance ROM,验证pass。再安装qsee_logger,又出现bottom耗流不稳定的waveform。但是平均耗流仍然会比之前差的时候好。

所以,得出结论:1. qsee_logger导致bottom耗流不稳定,影响耗流

        2. 非performance ROM也影响了耗流

在此案例中,我们利用了trace event查看了系统非休眠情况下,cpu调度的相关事件,并且找出了qsee_logger影响了底电流的稳定。

二、trace function 和function_graph

需要使用这2个功能,内核配置中需要添加以下内容:CONFIG_DYNAMIC_FTRACE=y、CONFIG_FUNCTION_TRACER=y、CONFIG_IRQSOFF_TRACER=y、CONFIG_FUNCTION_PROFILER=y 和 CONFIG_PREEMPT_TRACER=y

1)trace function可以设定自己需要监测的函数,并且可以打印出其调用栈。

查看tracer,验证是否生效。

cat /d/tracing/available_tracers
blk function_graph preemptirqsoff preemptoff irqsoff function nop

1. 由于编译器有时会对函数进行重命名,因此通过使用以下命令确认(这里用例为:htc_batt_schedule_batt_info_update,看到确实后缀加了.part.8):

cat /d/tracing/available_filter_functions | grep htc_batt_schedule_batt_info_update
htc_batt_schedule_batt_info_update.part.

2. 确认存在之后,将其用作 ftrace 过滤器:

echo htc_batt_schedule_batt_info_update.part. > /d/tracing/set_ftrace_filter

3. 开启函数分析器:

echo function > /d/tracing/current_tracer

4. 开启堆栈跟踪:

echo func_stack_trace > /d/tracing/trace_options

5. 增加缓冲区大小:

echo  > /d/tracing/buffer_size_kb

6. 最后开启抓取,抓完后关闭,并获取记录文件:

echo  > /d/tracing/trace_on
执行复现问题的动作
echo > /d/tracing/trace_on
cat /d/tracing/trace > /data/local/tmp/trace

我们可以从抓取的文件中可以看到什么时刻会调用到监测的函数,并会打印出调用栈:

           <...>-  [] ...  6384.885600: htc_batt_schedule_batt_info_update.part. <-htc_battery_info_update
<...>- [] ... 6384.885612: <stack trace>
=> smb2_batt_get_prop
=> power_supply_get_property
=> status_change_work
=> process_one_work
=> worker_thread
=> kthread
=> ret_from_fork
...
...
kworker/:- [] ... 6395.535869: htc_batt_schedule_batt_info_update.part. <-htc_battery_info_update
kworker/:- [] ... 6395.535880: <stack trace>
=> smb2_usb_set_prop
=> power_supply_set_property
=> dwc3_msm_gadget_vbus_draw
=> dwc3_msm_vbus_draw_work
=> process_one_work
=> worker_thread
=> kthread
=> ret_from_fork

2)function_graph 是将调用栈打印出来,并且会显示每个阶段的运行的用时。这对于分析一些内核造成的卡顿问题有所帮助。

在上面那些config基础上,还需要打开配置:CONFIG_FUNCTION_GRAPH_TRACER=y

1. 设置tracer:

echo function_graph > /d/tracing/current_tracer

2. 最后开启抓取,抓完后关闭,并获取记录文件(设置buffer等和上面类似,不赘述):

echo  > /d/tracing/trace_on
执行复现问题的动作
echo > /d/tracing/trace_on
cat /d/tracing/trace > /data/local/tmp/trace

如下,我们可以看到每天函数的执行用时,这个时间是包含了sleep time的,所以可以用来定位系统延迟发生在哪个函数中。:

# tracer: function_graph
#
# CPU DURATION FUNCTION CALLS
# | | | | | | |
) + 76.615 us | } /* vfs_open */
) 0.156 us | open_check_o_direct();
) | terminate_walk() {
) 0.104 us | drop_links.isra.();
) | dput() {
) | __might_sleep() {
) 0.156 us | ___might_sleep();
) 3.750 us | }
) 0.105 us | __rcu_read_lock();
) 0.156 us | __rcu_read_unlock();
) + 17.396 us | }
) | mntput() {
) | mntput_no_expire() {
) 0.156 us | __rcu_read_lock();
) 0.833 us | preempt_count_add();
) 0.208 us | preempt_count_sub();
) 0.157 us | __rcu_read_unlock();
) + 18.229 us | }
) + 21.875 us | }
) | dput() {
) | __might_sleep() {
) 0.157 us | ___might_sleep();
) 3.854 us | }
) 0.104 us | __rcu_read_lock();
) 0.156 us | __rcu_read_unlock();
) + 15.990 us | }

其中计时前面的符号是一种提醒,让我们能注意到哪些地方的用时比较长,可能存在问题:

  + means that the function exceeded  usecs.
! means that the function exceeded usecs.
# means that the function exceeded usecs.
* means that the function exceeded msecs.
@ means that the function exceeded msecs.
$ means that the function exceeded sec.

3)动态ftrace

由于上面两种方法都会监测很多其他函数,会对系统造成较大负担。所以,需要使用动态过滤监测函数的方式。

如果我们想只跟踪特定函数,可以把需要配置跟踪的函数写入到节点:

echo htc_batt_schedule_batt_info_update.part. > /d/tracing/set_ftrace_filter ------- function tracer
echo htc_batt_schedule_batt_info_update.part. > /d/tracing/set_graph_function ------ function_graph tracer

或者想把一些函数排除在外,可以写入如下节点:

/sys/kernel/debug/tracing/set_ftrace_notrace ------- function tracer
/sys/kernel/debug/tracing/set_graph_notrace ------ function_graph tracer

BTW,trace抓取之后,想再次抓取,默认是会把上次抓取的也包含在内的。所以,如果不需要上一次的信息,需要清空trace之后,重新再开始抓取:

echo '' > /d/tracing/trace 

Ftrace的部分使用方法的更多相关文章

  1. javaSE27天复习总结

    JAVA学习总结    2 第一天    2 1:计算机概述(了解)    2 (1)计算机    2 (2)计算机硬件    2 (3)计算机软件    2 (4)软件开发(理解)    2 (5) ...

  2. Linux内核调试方法总结之ftrace

    ftrace [用途] ftrace包含一系列跟踪器,用于不同的场合,比如跟踪内核函数调用(function tracer).跟踪上下文切换(sched_switch tracer).查看中断被关闭的 ...

  3. ftrace 使用方法

    1. 追蹤Kernel function (以schedule()示範) 先至 /sys/kernel/debug/tracing# cat available_tracers 確定有無 函式追蹤器( ...

  4. LISA介绍及其使用方法

    LISA是ARM公司开发的一款开源工具.在内核开发过程中,苦于无法针对修改内容进行一些量化或者可视化结果的测量,而无感.LISA对于模型调优,回归测试都有较强的支持. 什么是LISA? LISA是Li ...

  5. ftrace的使用【转】

    转自:http://blog.csdn.net/cybertan/article/details/8258394 This article explains how to set up ftrace ...

  6. 利用ftrace跟踪内核static tracepoint——实例writeback event

    摘要:和很多linux内核子系统一样,static tracepoint有很多层次,其中某个层次都展示给不同层次的开发者来满足他们的不同需求.关于linux tracepoint的详细信息,我们可以在 ...

  7. ftrace利器之trace-cmd和kernelshark

    关键词:ftrace.trace-cmd.kernelshark. trace-cmd是设置读取ftrace的命令行工具,kernelshark既可以记录数据,也可以图形化分析结果. trace-cm ...

  8. 利用ftrace跟踪内核static tracepoint

    摘要:和很多linux内核子系统一样,static tracepoint有很多层次,其中某个层次都展示给不同层次的开发者来满足他们的不同需求.关于linux tracepoint的详细信息,我们可以在 ...

  9. 【转】ftrace 简介

    ftrace 简介 ftrace 的作用是帮助开发人员了解 Linux 内核的运行时行为,以便进行故障调试或性能分析. 最早 ftrace 是一个 function tracer,仅能够记录内核的函数 ...

随机推荐

  1. 【Kafka】CAP理论以及CAP定律

    目录 CAP理论 概述 Consistency Availability Partition Tolerance CAP理论 概述 1988年,加州大学计算机科学家Eric Brewer 提出了分布式 ...

  2. 设计者模式之GOF23命令模式

    命令模式Command 将一个请求封装为一个对象,从而使我们可用不同的请求对客户参数化:对请求排队或者记录请求日志,以及支持可撤销的操作.也称之为:动作Action模式,事务transaction模式 ...

  3. 工作总结1-----String.format的使用

    以前在开发项目中,输入信息常使用的方法:"XXXXXXX"+a+"XXXXXXXXXXX"+b;,这种方式不仅不美观而且不易维护! String中的format ...

  4. 基于Vue搭建自己的组件库(1)

    本项目演示地址:https://husilang.github.io/zm-ui 项目参考文章:从零开始搭建Vue组件库 VV-UI 项目的初衷是学习怎么封装一个基于Vue的UI组件库,顺便记录每个步 ...

  5. filebeat-kafka:WARN producer/broker/0 maximum request accumulated, waiting for space

    You need to configure 3 things: Brokers Filebeat kafka output Consumer Here a example (change paths ...

  6. git init 后关联github仓库是发生错误:

    : failed to push some refs to 'git@github.com:AlanKnightly/reactC.git'hint: Updates were rejected be ...

  7. mysql小白系列_12 sysbench

    压测 1.查看机器负载load top - load average 1m 5m 15m cat /proc/loadavg 与CPU个数有关,1个load表示1个CPUcat /proc/cpuin ...

  8. 判断数组的方法/判断JS数据类型的四种方法

    参考文: 以下 3 个判断数组的方法,请分别介绍它们之间的区别和优劣Object.prototype.toString.call() . instanceof 以及 Array.isArray() h ...

  9. Flask开发技巧之异常处理

    Flask开发技巧之异常处理 目录 Flask开发技巧之异常处理 1.Flask内置异常处理 2.HTTPException类分析 3.自定义异常处理类 4.方便的定义自己的错误类 5.注意事项 本人 ...

  10. Spring 由构造函数自动装配

    Spring 由构造函数自动装配,这种模式与 byType 非常相似,但它应用于构造器参数. Spring 容器看作 beans,在 XML 配置文件中 beans 的 autowire 属性设置为 ...