分享

ftrace说明 – Software System Team: home for the system software team (formerly PLD)

 老匹夫 2014-09-16

介绍 ?

最早ftrace是一个function tracer,仅能够记录内核的函数调用流程。

如今ftrace已经成为一个framework,采用plugin的方式支持开发人员添加更多种类的trace功能。

trace 类型 ?

传统 Tracer

对所有的function进行统计,不同的tracer对应不同的分析策略

  function 		---trace all kernel functions
  function_graph 	---和function类似,但以调用图形式显示
  wakeup_rt    		---针对rt任务的延时(kernel任务)
  wakeup 		---针对非rt任务延时情况
  preemptirqsoff        ---关抢占关中断延时
  preemptoff 		---关抢占延时
  irqsoff 		---关中断延时

Non-Tracer Tracer

在系统特定流程中增加定制化的trace代码

  Max Stack Tracer	---记录一段时间的最大栈深度
  Profiling (branches / unlikely / likely / Functions)  ---分支性能统计分析
  Event tracing		---触发trace的系统特定事件,跟踪event前,需要把current_tracer设置为nop

kernel配置 ?

Kernel hacking 
	--->-*- Debug Filesystem
Kernel hacking
	--->Tracers
        [*] Interrupts-off Latency Tracer		---关中断延时统计
        [*] Scheduling Latency Tracer			---调度延时统计
        -*- Trace process context switches		---进程context切换
        [*] Trace boot initcalls          		---根据__init__  function
        [*] Trace likely/unlikely profiler		---分支性能统计
        [*] Profile all if conditionals			---if分支性能分析
        [*] Trace likely/unlikely instances             ---likely/unlikely分支性能分析
        [*] Trace max stack				---检测最大堆栈
        [-] enable/disable ftrace tracepoints dynamically  ---全部function的消耗较大,某些cpu上会导致系统瘫痪,dynamic function会减缓影响

ftrace initialization ?

mount -t debugfs debugfs /sys/kernel/debug
or
mount -t debugfs debugfs /d/   (if there is a symbol linking named /d to /sys/kernel/debug)

目录说明 ?

available_events			---所有可用的events
available_filter_functions	        ---所有可用的filter_function
available_tracers			---可用的tracers
buffer_size_kb				---保存trace的buffer
current_tracer				---设置或显示当前的tracer
dyn_ftrace_total_info		        ---dyn_ftrace的个数
events					---available_events的具体信息,dir形式
options					---trace_options的具体信息,dir形式
set_event				---设置要监视的event
set_ftrace_filter			---设置跟踪的funtion (dynamic ftrace)
set_ftrace_notrace			---设置不跟踪的funtion (dynamic ftrace)
set_ftrace_pid				---设置要跟踪的单个线程id
set_graph_function			---设置function graph tracer的触发函数
trace					---trace输出
trace_options				---trace显示内容控制
trace_pipe				---pipe形式的trace输出
tracing_cpumask				---设定trace在哪个cpu采集
tracing_enabled				---使能trace
tracing_max_latency			---刚进行过的Tracer统计中,最大的Latency
tracing_on				---trace开始/停止

使用说明 ?

trace

         note: /d is a symbol link to /sys/kernel/debug

	echo 0 > tracing_on
	echo > trace
	echo tracename > /d/tracing/current_tracer
	echo 1 > /d/tracing/tracing_enabled
	echo 1 > tracing_on

event

	echo nop > /d/tracing/current_tracer
	echo 0 > tracing_on
	echo > trace
	echo eventname > set_event	
	echo 1 > /d/tracing/tracing_enabled
	echo 1 > tracing_on

Max Stack Tracer

暂不支持

Profiling

	echo 0 > tracing_on
	echo > trace
	echo branch > current_tracer
	echo 1 > /d/tracing/tracing_enabled
	echo 1 > tracing_on

function_profile

usage:
   echo 1 > function_profile_enabled   ---> 开始统计
   echo 0 > function_profile_enabled   ---> 停止统计

output:
root@android:/sys/kernel/debug/tracing/trace_stat # ls
function0
function1
function2
function3

root@android:/sys/kernel/debug/tracing/trace_stat # cat function0
  Function                               Hit    Time            Avg             s^2
  --------                               ---    ----            ---             ---
  __schedule                          242056    4407687818 us     18209.37 us     44942531 us
  schedule                            237186    4406753390 us     18579.31 us     39064941 us
  poll_schedule_timeout               110877    2338559630 us     21091.47 us     150541881 us
  schedule_hrtimeout_range            109471    2338533225 us     21362.12 us     146683831 us
  schedule_hrtimeout_range_clock      109471    2338505455 us     21361.87 us     146683357 us
  do_sys_poll                         202048    2055973654 us     10175.66 us     65412798 us

trace 输出标识说明 ?

irqs-off:

	'd'  --- 关闭中断, 
	'.'  --- 没关闭中断,
	'X'  --- 当前体系不支持识别irqflag

need-resched:

	'N'  --- need_resched被设置, 
	'.'  --- need_resched未设置,

hardirq/softirq:

	'H'  --- 软中断过程中发生的硬中断.
	'h'  --- 硬中断
	's'  --- 软中断
	'.'  --- 进程上下文

delay:

	'!'  --- 大于preempt_mark_thresh (default 100us)
	'+'  --- 1us
	' '  --- 小于或等于1us.

示例 ?

查看中断情况 ?

current_tracer: nop

set_event:irq

#
#                              _-----=> irqs-off
#                             / _----=> need-resched
#                            | / _---=> hardirq/softirq
#                            || / _--=> preempt-depth
#                            ||| /     delay
#           TASK-PID   CPU#  ||||    TIMESTAMP  FUNCTION
#              | |       |   ||||       |         |
          <idle>-0     [000] d.h2 13868.971337: irq_handler_exit: irq=87 ret=unhandled
          <idle>-0     [000] d.h2 13868.971342: irq_handler_entry: irq=87 name=dwc_otg
          <idle>-0     [000] dNh2 13868.971358: irq_handler_exit: irq=87 ret=handled
          <idle>-0     [000] dNh2 13868.971364: irq_handler_entry: irq=87 name=dwc_otg_hcd:usb1
          <idle>-0     [000] dNh2 13868.971368: irq_handler_exit: irq=87 ret=unhandled
          <idle>-0     [000] d.h3 13868.971482: irq_handler_entry: irq=87 name=dwc_otg
          <idle>-0     [000] d.h3 13868.971486: irq_handler_exit: irq=87 ret=unhandled
          <idle>-0     [000] d.h3 13868.971491: irq_handler_entry: irq=87 name=dwc_otg
          ...

查看调度 ?

current_tracer: nop

set_event:sched

#                              _-----=> irqs-off
#                             / _----=> need-resched
#                            | / _---=> hardirq/softirq
#                            || / _--=> preempt-depth
#                            ||| /     delay
#           TASK-PID   CPU#  ||||    TIMESTAMP  FUNCTION
#              | |       |   ||||       |         |
            adbd-379   [000] d..3 14010.891592: sched_switch: prev_comm=adbd prev_pid=379 prev_prio=120 prev_state=S ==> next_comm=adbd next_pid=375 next_prio=120
            adbd-375   [000] d..3 14010.891696: sched_stat_runtime: comm=adbd pid=375 runtime=114856 [ns] vruntime=171426970635 [ns]
            adbd-375   [000] d..3 14010.891703: sched_switch: prev_comm=adbd prev_pid=375 prev_prio=120 prev_state=S ==> next_comm=swapper/0 next_pid=0 next_prio=120
          <idle>-0     [000] d.h4 14010.891902: sched_wakeup: comm=engpcclient pid=374 prio=100 success=1 target_cpu=000
          <idle>-0     [000] d..3 14010.892013: sched_switch: prev_comm=swapper/0 prev_pid=0 prev_prio=120 prev_state=R ==> next_comm=engpcclient next_pid=374 next_prio=100
     engpcclient-374   [000] d..3 14010.892081: sched_stat_runtime: comm=engpcclient pid=374 runtime=179336 [ns] vruntime=171423775993 [ns]
     engpcclient-374   [000] d..3 14010.892088: sched_switch: prev_comm=engpcclient prev_pid=374 prev_prio=100 prev_state=S ==> next_comm=swapper/0 next_pid=0 next_prio=120
     ...

查看延时情况 ?

current_tracer:wakeup

set_event:

# tracer: wakeup
#
# wakeup latency trace v1.1.5 on 3.4.5-00014-g6b067cd
# --------------------------------------------------------------------
# latency: 14558 us, #245/1075250, CPU#1 | (M:preempt VP:0, KP:0, SP:0 HP:0 #P:1)
#    -----------------
#    | task: WindowManagerPo-440 (uid:1000 nice:-2 policy:0 rt_prio:0)
#    -----------------
#  => started at: add_preempt_count
#  => ended at:   stop_critical_timings
#
#
#                  _------=> CPU#            
#                 / _-----=> irqs-off        
#                | / _----=> need-resched    
#                || / _---=> hardirq/softirq 
#                ||| / _--=> preempt-depth   
#                |||| /     delay             
#  cmd     pid   ||||| time  |   caller      
#     \   /      |||||  \    |   /           
Compiler-416     0d..4    1us+:    416:120:R   + [001]   440:118:R WindowManagerPo
Compiler-416     0d..4    6us!: probe_wakeup <-probe_wakeup
##### CPU 1 buffer started ####
kworker/-32613   1d..1 12460us+: serial_sprd_console_putchar <-uart_console_write
kworker/-32613   1d..1 12545us+: serial_sprd_console_putchar <-uart_console_write
kworker/-32613   1d..1 12632us+: serial_sprd_console_putchar <-uart_console_write
kworker/-32613   1d..1 12719us+: serial_sprd_console_putchar <-uart_console_write
kworker/-32613   1d..1 12807us+: serial_sprd_console_putchar <-uart_console_write
...
kworker/-32613   1d..1 13936us!: serial_sprd_console_putchar <-uart_console_write
kworker/-32613   1d..1 14110us : _raw_spin_unlock <-serial_sprd_console_write
kworker/-32613   1d..1 14112us+: sub_preempt_count <-_raw_spin_unlock
kworker/-32613   1d... 14114us+: ram_console_write <-__call_console_drivers
kworker/-32613   1d... 14181us+: _call_console_drivers <-console_unlock
kworker/-32613   1d... 14183us : _raw_spin_lock_irqsave <-console_unlock
kworker/-32613   1d... 14184us : __raw_spin_lock_irqsave <-_raw_spin_lock_irqsave
kworker/-32613   1d... 14186us+: add_preempt_count <-__raw_spin_lock_irqsave
kworker/-32613   1d..1 14188us : _raw_spin_unlock <-console_unlock
...

动态ftrace ?

current_tracer: function

set_ftrace_filter: 'hrtimer_*'

set_event:

 tracer: function
#
# entries-in-buffer/entries-written: 238/17293   #P:1
#
#                              _-----=> irqs-off
#                             / _----=> need-resched
#                            | / _---=> hardirq/softirq
#                            || / _--=> preempt-depth
#                            ||| /     delay
#           TASK-PID   CPU#  ||||    TIMESTAMP  FUNCTION
#              | |       |   ||||       |         |
          <idle>-0     [000] d..2 68326.255274: hrtimer_force_reprogram <-__remove_hrtimer
          <idle>-0     [000] d.h1 68326.263364: hrtimer_interrupt <-__gptimer_interrupt
          <idle>-0     [000] d.h1 68326.263372: hrtimer_wakeup <-__run_hrtimer
          <idle>-0     [000] dN.1 68326.263402: hrtimer_cancel <-tick_nohz_idle_exit
          <idle>-0     [000] dN.1 68326.263405: hrtimer_try_to_cancel <-hrtimer_cancel
          <idle>-0     [000] dN.2 68326.263409: hrtimer_force_reprogram <-__remove_hrtimer
          <idle>-0     [000] dN.1 68326.263451: hrtimer_forward <-tick_nohz_idle_exit
          <idle>-0     [000] dN.1 68326.263455: hrtimer_start_range_ns <-tick_nohz_idle_exit
     engpcclient-374   [000] .... 68326.263527: hrtimer_cancel <-do_nanosleep
     engpcclient-374   [000] .... 68326.263530: hrtimer_try_to_cancel <-hrtimer_cancel
     ...

查看block设备 ?

current_tracer: nop

set_event:block

#                              _-----=> irqs-off
#                             / _----=> need-resched
#                            | / _---=> hardirq/softirq
#                            || / _--=> preempt-depth
#                            ||| /     delay
#           TASK-PID   CPU#  ||||    TIMESTAMP  FUNCTION
#              | |       |   ||||       |         |
     flush-179:0-364   [000] ...1 69812.711927: block_bio_remap: 179,0 W 3449337 + 8 <- (179,25) 285168
     flush-179:0-364   [000] ...1 69812.711946: block_bio_queue: 179,0 W 3449337 + 8 [flush-179:0]
     flush-179:0-364   [000] ...1 69812.711981: block_getrq: 179,0 W 3449337 + 8 [flush-179:0]
     flush-179:0-364   [000] ...1 69812.711992: block_plug: [flush-179:0]
     flush-179:0-364   [000] d..2 69812.712024: block_rq_insert: 179,0 W 0 () 3449337 + 8 [flush-179:0]
     flush-179:0-364   [000] dN.2 69812.712071: block_unplug: [flush-179:0] 1
         mmcqd/0-99    [000] d..2 69812.712115: block_rq_issue: 179,0 W 0 () 3449337 + 8 [mmcqd/0]
     flush-179:0-364   [000] ...1 69812.725229: block_bio_remap: 179,0 W 3444665 + 8 <- (179,25) 280496
     flush-179:0-364   [000] ...1 69812.725235: block_bio_queue: 179,0 W 3444665 + 8 [flush-179:0]
     flush-179:0-364   [000] ...1 69812.725252: block_getrq: 179,0 W 3444665 + 8 [flush-179:0]
     flush-179:0-364   [000] ...1 69812.725257: block_plug: [flush-179:0]
     flush-179:0-364   [000] d..2 69812.725280: block_rq_insert: 179,0 W 0 () 3444665 + 8 [flush-179:0]
     flush-179:0-364   [000] d..2 69812.725289: block_unplug: [flush-179:0] 1
         mmcqd/0-99    [000] d..2 69812.730878: block_rq_issue: 179,0 W 0 () 3444665 + 8 [mmcqd/0]
     ...

查看signal ?

current_tracer: nop

set_event:signal

#                              _-----=> irqs-off
#                             / _----=> need-resched
#                            | / _---=> hardirq/softirq
#                            || / _--=> preempt-depth
#                            ||| /     delay
#           TASK-PID   CPU#  ||||    TIMESTAMP  FUNCTION
#              | |       |   ||||       |         |
           <...>-5493  [000] dN.3 70613.830631: signal_generate: sig=17 errno=0 code=262145 comm=sh pid=3404 grp=1 res=0
              sh-3404  [000] d..2 70613.830667: signal_deliver: sig=17 errno=0 code=262145 sa_handler=b6f2b105 sa_flags=0
           <...>-5494  [000] dN.3 70616.399782: signal_generate: sig=17 errno=0 code=262145 comm=sh pid=3404 grp=1 res=0
              sh-3404  [000] d..2 70616.399818: signal_deliver: sig=17 errno=0 code=262145 sa_handler=b6f2b105 sa_flags=0
           <...>-5496  [000] dN.3 70618.357072: signal_generate: sig=17 errno=0 code=262145 comm=sh pid=5495 grp=1 res=0
           <...>-5495  [000] d..2 70618.357123: signal_deliver: sig=17 errno=0 code=262145 sa_handler=b6f87105 sa_flags=0
           <...>-5495  [000] d..3 70618.357885: signal_generate: sig=17 errno=0 code=262145 comm=slog pid=165 grp=1 res=1
           <...>-5500  [000] dN.3 70623.375711: signal_generate: sig=17 errno=0 code=262145 comm=sh pid=5499 grp=1 res=0
           ...

查看branch ?

current_tracer: bransh

set_event:

# TASK-PID CPU# TIMESTAMP CORRECT FUNC:FILE:LINE

# | | | | | |

<idle>-0 [000] 55415.397835: [ ok ] read_seqretry:seqlock.h:110
<idle>-0 [000] 55415.397848: [ ok ] native_sched_clock:tsc.c:55
<idle>-0 [000] 55415.397859: [ ok ] native_sched_clock:tsc.c:55
...
<idle>-0 [000] 55415.398682: [ ok ] __local_bh_enable:softirq.c:138
<idle>-0 [000] 55415.398695: [ ok ] update_wall_time:timekeeping.c:789
<idle>-0 [000] 55415.398710: [ MISS ] timekeeping_adjust:timekeeping.c:711
<idle>-0 [000] 55415.398725: [ ok ] update_wall_time:timekeeping.c:839 

案例 ?

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多