【原創】Ftrace的配置和使用


【原創】Ftrace的配置和使用

Ftrace是Linux Kernel的官方tracing系統,支持Function trace、靜態tracepoint、動態Tracepoint的跟蹤,還提供各種Tracer,用於統計最大irq延遲、最大函數調用棧大小、調度事件等。

Ftrace還提供了強大的過濾、快照snapshot、實例(instance)等功能,可以靈活配置。

內核配置Ftrace后,如果功能不打開,對性能幾乎沒有影響。打開事件記錄后,由於是在percpu buffer中記錄log,各CPU無需同步,引入的負載不大,非常適合在性能敏感的場景中使用。

相比kernle的log_bufdynamic_debug機制,Ftrace的buffer大小可以靈活配置,可以生成快照,也有一定的優勢。

ftrace功能比較多,但是歸類整理以后主要使用場景也就是常見的幾種,如果能按本文的說明操作一遍,就能快速上手了。

trace log格式,詳細文檔參看kernel/Documentation/trace/ftrace.txt

關鍵信息:

  • cmd: 執行程序名

  • pid:進程pid

  • CPU#: CPU id

  • irqs-off:當前CPU中斷是否是關閉狀態

  • need-reschedTIF_NEED_RESCHEDTIF_NEED_RESCHED的設置狀態

  • hardirq/softirq: 中斷處理上下文狀態

  • preempt-depth:preempt_disabled的深度

     
    # tracer: irqsoff
    #
    # irqsoff latency trace v1.1.5 on 3.8.0-test+
    # --------------------------------------------------------------------
    # latency: 259 us, #4/4, CPU#2 | (M:preempt VP:0, KP:0, SP:0 HP:0 #P:4)
    #    -----------------
    #    | task: ps-6143 (uid:0 nice:0 policy:0 rt_prio:0)
    #    -----------------
    #  => started at: __lock_task_sighand
    #  => ended at:   _raw_spin_unlock_irqrestore
    #
    #
    #                  _------=> CPU#
    #                 / _-----=> irqs-off
    #                | / _----=> need-resched
    #                || / _---=> hardirq/softirq
    #                ||| / _--=> preempt-depth
    #                |||| /     delay
    #  cmd     pid   ||||| time  |   caller
    #     \   /      |||||  \    |   /
          ps-6143    2d...    0us!: trace_hardirqs_off <-__lock_task_sighand
          ps-6143    2d..1  259us+: trace_hardirqs_on <-_raw_spin_unlock_irqrestore
          ps-6143    2d..1  263us+: time_hardirqs_on <-_raw_spin_unlock_irqrestore
          ps-6143    2d..1  306us : <stack trace>
     => trace_hardirqs_on_caller
     => trace_hardirqs_on
     => _raw_spin_unlock_irqrestore
     => do_task_stat
     => proc_tgid_stat
     => proc_single_show
     => seq_read
     => vfs_read
     => sys_read
     => system_call_fastpath
    

1. Ftrace的配置

Ftrace的相關配置如下

# 體系結構相關的實現
CONFIG_HAVE_FUNCTION_TRACER=y
CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
CONFIG_HAVE_DYNAMIC_FTRACE=y
CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
CONFIG_HAVE_SYSCALL_TRACEPOINTS=y
CONFIG_HAVE_ARCH_TRACEHOOK=y

# Function Trace
CONFIG_FTRACE=y
CONFIG_FUNCTION_TRACER=y
CONFIG_FUNCTION_GRAPH_TRACER=y
CONFIG_DYNAMIC_FTRACE=y # 打開DYANMIC_FTRACE后性能開銷可忽略

# 各種tracer的支持
CONFIG_GENERIC_TRACER=y
CONFIG_NOP_TRACER=y
CONFIG_STACK_TRACER=y
CONFIG_IRQSOFF_TRACER=y
CONFIG_PREEMPT_TRACER=y
CONFIG_SCHED_TRACER=y
CONFIG_CONTEXT_SWITCH_TRACER=y
CONFIG_TRACER_SNAPSHOT=y
CONFIG_TRACER_SNAPSHOT_PER_CPU_SWAP=y

# 靜態Trace events
CONFIG_TRACEPOINTS=y
CONFIG_EVENT_TRACING=y
CONFIG_TRACING_SUPPORT=y
CONFIG_TRACING=y

# 動態Trace events
CONFIG_PROBE_EVENTS=y
CONFIG_KPROBE_EVENTS=y
CONFIG_UPROBE_EVENTS=y

# 其它相關配置
CONFIG_TRACE_CLOCK=y
CONFIG_STACKTRACE_SUPPORT=y
CONFIG_STACKTRACE=y
CONFIG_TRACE_IRQFLAGS_SUPPORT=y
CONFIG_TRACE_IRQFLAGS=y
CONFIG_SYSCTL_EXCEPTION_TRACE=y
CONFIG_TRACER_MAX_TRACE=y
CONFIG_FTRACE_SYSCALLS=y
CONFIG_BLK_DEV_IO_TRACE=y

2. Tracefs的使用

Ftrace實現了一個tracefs的內存文件系統,默認掛載在/sys/kernel/debug/tracing/目錄下。

本節把該目錄下的文件和目錄分組歸類,做詳細介紹。

另外可以參看kernel源碼下的 Documentation/trace/ftrace.txt,這個是ftrace的官方使用文檔,介紹比較詳細。

2.1 README

  • README

    README是tracefs的一個簡要說明文檔,可以cat 查看

    # cat README 
    tracing mini-HOWTO:
    
    # echo 0 > tracing_on : quick way to disable tracing
    # echo 1 > tracing_on : quick way to re-enable tracing
    
     Important files:
      trace                 - The static contents of the buffer
                              To clear the buffer write into this file: echo > trace
      trace_pipe            - A consuming read to see the contents of the buffer
      current_tracer        - function and latency tracers
      available_tracers     - list of configured tracers for current_tracer
      buffer_size_kb        - view and modify size of per cpu buffer
      buffer_total_size_kb  - view total size of all cpu buffers
    
      trace_clock           -change the clock used to order events
           local:   Per cpu clock but may not be synced across CPUs
          global:   Synced across CPUs but slows tracing down.
         counter:   Not a clock, but just an increment
          uptime:   Jiffy counter from time of boot
            perf:   Same clock that perf events use
    
      trace_marker          - Writes into this file writes into the kernel buffer
    
      trace_marker_raw      - Writes into this file writes binary data into the kernel buffer
      tracing_cpumask       - Limit which CPUs to trace
      instances             - Make sub-buffers with: mkdir instances/foo
                              Remove sub-buffer with rmdir
      trace_options         - Set format or modify how tracing happens
                              Disable an option by adding a suffix 'no' to the option name
      saved_cmdlines_size   - echo command number in here to store comm-pid list
    
      available_filter_functions - list of functions that can be filtered on
      set_ftrace_filter     - echo function name in here to only trace these functions
                 accepts: func_full_name or glob-matching-pattern
                 modules: Can select a group via module
                  Format: :mod:<module-name>
                 example: echo :mod:ext3 > set_ftrace_filter
                triggers: a command to perform when function is hit
                  Format: <function>:<trigger>[:count]
                 trigger: traceon, traceoff
                          enable_event:<system>:<event>
                          disable_event:<system>:<event>
                          stacktrace
                          snapshot
                          dump
                          cpudump
                 example: echo do_fault:traceoff > set_ftrace_filter
                          echo do_trap:traceoff:3 > set_ftrace_filter
                 The first one will disable tracing every time do_fault is hit
                 The second will disable tracing at most 3 times when do_trap is hit
                   The first time do trap is hit and it disables tracing, the
                   counter will decrement to 2. If tracing is already disabled,
                   the counter will not decrement. It only decrements when the
                   trigger did work
                 To remove trigger without count:
                   echo '!<function>:<trigger> > set_ftrace_filter
                 To remove trigger with a count:
                   echo '!<function>:<trigger>:0 > set_ftrace_filter
      set_ftrace_notrace    - echo function name in here to never trace.
                accepts: func_full_name, *func_end, func_begin*, *func_middle*
                modules: Can select a group via module command :mod:
                Does not accept triggers
      set_ftrace_pid        - Write pid(s) to only function trace those pids (function)
      snapshot              - Like 'trace' but shows the content of the static
                              snapshot buffer. Read the contents for more information
      stack_trace           - Shows the max stack trace when active
      stack_max_size        - Shows current max stack size that was traced
                              Write into this file to reset the max size (trigger a  new trace)
      stack_trace_filter    - Like set_ftrace_filter but limits what stack_trace traces
      kprobe_events         - Add/remove/show the kernel dynamic events
                              Write into this file to define/undefine new trace events.
      uprobe_events         - Add/remove/show the userspace dynamic events
                              Write into this file to define/undefine new trace events.
              accepts: event-definitions (one definition per line)
               Format: p[:[<group>/]<event>] <place> [<args>]
                       r[maxactive][:[<group>/]<event>] <place> [<args>]
                       -:[<group>/]<event>
                place: [<module>:]<symbol>[+<offset>]|<memaddr>
    place (kretprobe): [<module>:]<symbol>[+<offset>]|<memaddr>
                place: <path>:<offset>
                 args: <name>=fetcharg[:type]
             fetcharg: %<register>, @<address>, @<symbol>[+|-<offset>],
                       $stack<index>, $stack, $retval, $comm
                 type: s8/16/32/64, u8/16/32/64, x8/16/32/64, string,
                       b<bit-width>@<bit-offset>/<container-size>
      events/               - Directory containing all trace event subsystems:
          enable            - Write 0/1 to enable/disable tracing of all events
      events/<system>/      - Directory containing all trace events for <system>:
          enable            - Write 0/1 to enable/disable tracing of all <system> events
          filter            - If set, only events passing filter are traced
      events/<system>/<event>/      - Directory containing control files for
                              <event>:
          enable            - Write 0/1 to enable/disable tracing of <event>
          filter            - If set, only events passing filter are traced
          trigger           - If set, a command to perform when event is hit
                Format: <trigger>[:count][if <filter>]
               trigger: traceon, traceoff
                        enable_event:<system>:<event>
                        disable_event:<system>:<event>
                        stacktrace
                        snapshot
               example: echo traceoff > events/block/block_unplug/trigger
                        echo traceoff:3 > events/block/block_unplug/trigger
                        echo 'enable_event:kmem:kmalloc:3 if nr_rq > 1' > \
                              events/block/block_unplug/trigger
               The first disables tracing every time block_unplug is hit.
               The second disables tracing the first 3 times block_unplug is hit.
               The third enables the kmalloc event the first 3 times block_unplug
                 is hit and has value of greater than 1 for the 'nr_rq' event field.
               Like function triggers, the counter is only decremented if it
                enabled or disabled tracing.
               To remove a trigger without a count:
                 echo '!<trigger> > <system>/<event>/trigger
               To remove a trigger with a count:
                 echo '!<trigger>:0 > <system>/<event>/trigger
               Filters can be ignored when removing a trigger.
    

2.2 Trace buffer的設置和顯示

  • buffer_size_kb
  • buffer_total_size_kb
  • free_buffer

這三個文件用來對trace buffer分配、釋放和查詢。 Ftrace每個CPU都有一個對應的buffer,buffer_size_kb設置的是每個CPU上buffer的大小。

比如這里設置buffer_size_kb為100,000KB,對於4核處理器,實際是分配400MB。

free_buffers用於釋放buffer。

# echo 100000 > buffer_size_kb
# cat buffer_total_size_kb 
400000
# echo 1 > free_buffer
# cat buffer_size_kb 
0
# cat buffer_total_size_kb 
0
  • trace
  • trace_pipe
  • snapshot
  • trace_marker
  • trace_marker_raw
  • per_cpu/

這幾個文件是對trace buffer的導出和插入功能。

trace是靜態buffer,每次cat后log還保存在buffer中;echo > trace 可以清空buffer。

trace_pipe是消耗性的,cat一次后buffer會清空,可用於持續導出trace log:

cat trace_pipe > /tmp/trace.out &

snapshot可以獲得當前的一個trace buffer的備份,方便保存某個時間點的buffer 內容,不影響原trace buffer的記錄。

trace_marker 可以用來把用戶層的log插入trace buffer,可以實現用戶層和kernel的的trace log的同步,這是個很方便的功能,Android的Systrace就使用這個功能導出用戶層trace log。

trace_marker_raw 是用來寫入二進制數據的。

per_cpu是個目錄,可以對每隔cpu的buffer size進行設置,和查看trace內容

root:/sys/kernel/debug/tracing# cat trace
# tracer: irqsoff
#
# irqsoff latency trace v1.1.5 on 4.14.74
# --------------------------------------------------------------------
# latency: 3305 us, #18446744073709432385/46979595, CPU#3 | (M:preempt VP:0, KP:0, SP:0 HP:0 #P:4)
#    -----------------
#    | task: kworker/3:1-63 (uid:0 nice:0 policy:0 rt_prio:0)
#    -----------------
#  => started at: drain_pages
#  => ended at:   drain_pages
#
#
#                  _------=> CPU#            
#                 / _-----=> irqs-off        
#                | / _----=> need-resched    
#                || / _---=> hardirq/softirq 
#                ||| / _--=> preempt-depth   
#                |||| /     delay            
#  cmd     pid   ||||| time  |   caller      
#     \   /      |||||  \    |   /         
kworker/-63      3d..3 3082us : get_pfnblock_flags_mask <-free_pcppages_bulk
kworker/-63      3d..3 3083us : __mod_zone_page_state <-free_pcppages_bulk
kworker/-63      3d..3 3084us : pfn_valid <-free_pcppages_bulk
kworker/-63      3d..3 3085us : memblock_is_map_memory <-pfn_valid
kworker/-63      3d..3 3086us : pfn_valid <-free_pcppages_bulk
kworker/-63      3d..3 3087us : memblock_is_map_memory <-pfn_valid
...
kworker/-32073   2dn.1 3655us : <stack trace>
 => drain_local_pages_wq
 => process_one_work
 => worker_thread
 => kthread
 => ret_from_fork

root:/sys/kernel/debug/tracing# echo 1111111111111111111111 > trace_marker
root:/sys/kernel/debug/tracing# cat trace
# tracer: nop
#
#                              _-----=> irqs-off
#                             / _----=> need-resched
#                            | / _---=> hardirq/softirq
#                            || / _--=> preempt-depth
#                            ||| /     delay
#           TASK-PID   CPU#  ||||    TIMESTAMP  FUNCTION
#              | |       |   ||||       |         |
              sh-1516  [003] .... 16131.075350: tracing_mark_write: 1111111111111111111111

root:/sys/kernel/debug/tracing# cat snapshot 
# tracer: nop
#
#
# * Snapshot is freed *
#
# Snapshot commands:
# echo 0 > snapshot : Clears and frees snapshot buffer
# echo 1 > snapshot : Allocates snapshot buffer, if not already allocated.
#                      Takes a snapshot of the main buffer.
# echo 2 > snapshot : Clears snapshot buffer (but does not allocate or free)
#                      (Doesn't have to be '2' works with any number that
#                       is not a '0' or '1')
root:/sys/kernel/debug/tracing# echo 1 > snapshot 
root:/sys/kernel/debug/tracing# cat snapshot 
# tracer: nop
#
#                              _-----=> irqs-off
#                             / _----=> need-resched
#                            | / _---=> hardirq/softirq
#                            || / _--=> preempt-depth
#                            ||| /     delay
#           TASK-PID   CPU#  ||||    TIMESTAMP  FUNCTION
#              | |       |   ||||       |         |
              sh-1516  [003] .... 16131.075350: tracing_mark_write: 1111111111111111111111

root:/sys/kernel/debug/tracing# echo > trace 可以請空buffer
root:/sys/kernel/debug/tracing# ls per_cpu/ -R
per_cpu/:
cpu0  cpu1  cpu2  cpu3

per_cpu/cpu0:
buffer_size_kb  snapshot        snapshot_raw    stats           trace           trace_pipe      trace_pipe_raw

per_cpu/cpu1:
buffer_size_kb  snapshot        snapshot_raw    stats           trace           trace_pipe      trace_pipe_raw

2.3 trace 的控制

  • tracing_on
  • tracing_cpumask
  • trace_clock
  • trace_options
  • options/

tracing_on是 trace的總開關,配置好以后 echo 1 > tracing_on 才開始記錄。

許多配置需要關閉tracing才能設置,需要先 echo 0 > tracing_on

tracing_cpumask 是打開每個CPU的bitmap,比如默認是0xf。如果設置成0x3,就只trace CPU0和1。

trace_clock用於選擇使用哪個時鍾,這個會影響trace long中時間戳的打印,默認使用local的。

trace_options可以用來設置和查詢trace log的輸出選項,echo xxx > trace_options 就是打開xxx選項,echo noxxx > trace_options 就是關閉該選項。

options/目錄下對每個選項有單獨的文件,可以通過echo 1 或者0 來打開或關閉。

root:/sys/kernel/debug/tracing# echo 1 > tracing_on 
root:/sys/kernel/debug/tracing# cat tracing_cpumask 
f
root:/sys/kernel/debug/tracing# echo 1 > tracing_cpumask 
root:/sys/kernel/debug/tracing# cat tracing_cpumask 
1
root:/sys/kernel/debug/tracing# cat trace_options 
print-parent
nosym-offset
nosym-addr
noverbose
noraw
root:/sys/kernel/debug/tracing# echo noprint-parent > trace_options 
root:/sys/kernel/debug/tracing# cat trace_options 
noprint-parent
nosym-offset
nosym-addr
noverbose
noraw
nohex
root:/sys/kernel/debug/tracing# cat options/print-parent 
0
root:/sys/kernel/debug/tracing# echo 1 > options/print-parent 
root:/sys/kernel/debug/tracing# cat options/print-parent 
1

root:/sys/kernel/debug/tracing# echots_temp_read > set_ftrace_filter 
root:/sys/kernel/debug/tracing# echo function > current_tracer 
root:/sys/kernel/debug/tracing# echo func_stack_trace > trace_options 
root:/sys/kernel/debug/tracing# echo 1 > tracing_on 

root:/sys/kernel/debug/tracing# cat trace
# tracer: function
#
#                              _-----=> irqs-off
#                             / _----=> need-resched
#                            | / _---=> hardirq/softirq
#                            || / _--=> preempt-depth
#                            ||| /     delay
#           TASK-PID   CPU#  ||||    TIMESTAMP  FUNCTION
#              | |       |   ||||       |         |
     kworker/1:0-13974 [001] ...1 44214.144716:ts_temp_read <-hwmon_thermal_get_temp
     kworker/1:0-13974 [001] ...1 44244.864751:ts_temp_read <-hwmon_thermal_get_temp
     kworker/1:0-13974 [001] ...1 44244.864758: <stack trace>
 => of_thermal_get_temp
 => thermal_zone_get_temp
 => thermal_zone_device_update.part.12
 => thermal_zone_device_check
 => process_one_work
 => worker_thread
 => kthread
 => ret_from_fork
     kworker/1:0-13974 [001] ...1 44245.888747:ts_temp_read <-hwmon_thermal_get_temp
     kworker/1:0-13974 [001] ...1 44245.888755: <stack trace>
 => of_thermal_get_temp
 => thermal_zone_get_temp
 => thermal_zone_device_update.part.12
 => thermal_zone_device_check
 => process_one_work
 => worker_thread
 => kthread
 => ret_from_fork
     kworker/1:0-13974 [001] ...1 44246.912716:ts_temp_read <-hwmon_thermal_get_temp
     kworker/1:0-13974 [001] ...1 44246.912724: <stack trace>
 => of_thermal_get_temp
 => thermal_zone_get_temp
 => thermal_zone_device_update.part.12
 => thermal_zone_device_check
 => process_one_work
 => worker_thread
 => kthread
 => ret_from_fork

2.4. Tracer 的設置

  • available_tracers
  • current_tracer
  • tracing_thresh
  • tracing_max_latency

available_tracers顯示目前支持的tracer,current_tracer用於設置當前使用的tracer

目前支持的tracer如下:

  • blk:block tracer,主要用於blktrace 應用程序
  • function: 跟蹤函數調用,默認跟蹤所有函數,如果設置set_ftrace_filter, 則跟蹤過濾的函數
  • function_graph:同function,但是打印帶縮進的函數調用關系
  • wakeup_dl: dealine調度的最大長wakeup latency
  • wakeup_rt: rt調度的最大wakeup latency
  • wakeup: 普通調度的的最大wakeup latency
  • preemptirqsoff:關搶占或關irq的最大lantency,也稱最大調度latency
  • preemptoff: 關搶占的最大latency
  • irqsoff: 關中斷的最大lantecy
  • nop:空tracer

另外function和function_graph即使不打開,實際也會記錄每個函數的調用過程,在打印其它trace log中許多都要顯示函數調用關系。

默認只顯示parent的調用關系,可以通過echo display-graph > trace_options 設置顯示function_graph

blk tracer比較特別,需要設置/sys/block/xxx/trace/enable 才工作,可參考https://lwn.net/Articles/315508/

root:/sys/kernel/debug/tracing# echo function > current_tracer 
root:/sys/kernel/debug/tracing# cat trace
# tracer: function
#
#                              _-----=> irqs-off
#                             / _----=> need-resched
#                            | / _---=> hardirq/softirq
#                            || / _--=> preempt-depth
#                            ||| /     delay
#           TASK-PID   CPU#  ||||    TIMESTAMP  FUNCTION
#              | |       |   ||||       |         |
          <idle>-0     [001] dn.3   378.235883: preempt_count_add <-prandom_u32
          <idle>-0     [001] dn.4   378.235885: preempt_count_sub <-prandom_u32
          <idle>-0     [001] dn.3   378.235887: update_rq_clock <-__schedule
          <idle>-0     [001] dn.3   378.235889: pick_next_task_fair <-__schedule
          <idle>-0     [001] dn.3   378.235891: put_prev_task_idle <-pick_next_task_fair
          <idle>-0     [001] dn.3   378.235893: pick_next_entity <-pick_next_task_fair
          <idle>-0     [001] dn.3   378.235894: clear_buddies <-pick_next_entity
          <idle>-0     [001] dn.3   378.235896: set_next_entity <-pick_next_task_fair
          <idle>-0     [001] dn.3   378.235898: __update_load_avg_se.isra.3 <-set_next_entity
          <idle>-0     [001] dn.3   378.235900: decay_load <-__update_load_avg_se.isra.3
          <idle>-0     [001] dn.3   378.235902: decay_load <-__update_load_avg_se.isra.3
          <idle>-0     [001] dn.3   378.235903: __accumulate_pelt_segments <-__update_load_avg_se.isra.3
          <idle>-0     [001] dn.3   378.235905: __update_load_avg_cfs_rq.isra.4 <-set_next_entity
          <idle>-0     [001] d..3   378.235910: fpsimd_thread_switch <-__switch_to
          <idle>-0     [001] d..3   378.235912: hw_breakpoint_thread_switch <-__switch_to
          <idle>-0     [001] d..3   378.235914: uao_thread_switch <-__switch_to
    kworker/u8:0-9166  [001] d..3   378.235916: finish_task_switch <-__schedule
    kworker/u8:0-9166  [001] d..3   378.235919: _raw_spin_unlock_irq <-finish_task_switch
    kworker/u8:0-9166  [001] d..3   378.235921: do_raw_spin_unlock <-_raw_spin_unlock_irq
    kworker/u8:0-9166  [001] ...3   378.235923: preempt_count_sub <-_raw_spin_unlock_irq
    kworker/u8:0-9166  [001] ...2   378.235925: preempt_count_sub <-schedule
    kworker/u8:0-9166  [001] ...1   378.235927: _raw_spin_lock_irq <-worker_thread
    kworker/u8:0-9166  [001] d..1   378.235929: preempt_count_add <-_raw_spin_lock_irq
    kworker/u8:0-9166  [001] d..2   378.235931: preempt_count_add.part.2 <-preempt_count_add
    kworker/u8:0-9166  [001] d..2   378.235933: do_raw_spin_lock <-_raw_spin_lock_irq
    kworker/u8:0-9166  [001] d..2   378.235935: process_one_work <-worker_thread
    kworker/u8:0-9166  [001] d..2   378.235938: set_work_pool_and_clear_pending <-process_one_work
    kworker/u8:0-9166  [001] d..2   378.235939: _raw_spin_unlock_irq <-process_one_work
    kworker/u8:0-9166  [001] d..2   378.235941: do_raw_spin_unlock <-_raw_spin_unlock_irq
    kworker/u8:0-9166  [001] ...2   378.235943: preempt_count_sub <-_raw_spin_unlock_irq
    kworker/u8:0-9166  [001] ...1   378.235948: flush_to_ldisc <-process_one_work
    kworker/u8:0-9166  [001] ...1   378.235950: mutex_lock_nested <-flush_to_ldisc

root:/sys/kernel/debug/tracing# echo function_graph > current_tracer 
root:/sys/kernel/debug/tracing# echo preempt_count_add > set_ftrace_filter
root:/sys/kernel/debug/tracing# echo  > trace
root:/sys/kernel/debug/tracing# cat trace
# tracer: function
#
#                              _-----=> irqs-off
#                             / _----=> need-resched
#                            | / _---=> hardirq/softirq
#                            || / _--=> preempt-depth
#                            ||| /     delay
#           TASK-PID   CPU#  ||||    TIMESTAMP  FUNCTION
#              | |       |   ||||       |         |
              sh-1512  [003] ...1   433.935445: preempt_count_add <-_raw_spin_lock
              sh-1512  [003] ...1   433.935452: preempt_count_add <-__mnt_drop_write
              sh-1512  [003] ...2   433.935454: preempt_count_add <-__mnt_drop_write
              sh-1512  [003] ...1   433.935457: preempt_count_add <-__sb_end_write
              sh-1512  [003] ...1   433.935460: preempt_count_add <-_raw_spin_lock
              sh-1512  [003] ...1   433.935465: preempt_count_add <-mntput_no_expire
              sh-1512  [003] ...1   433.935469: preempt_count_add <-__fd_install
              sh-1512  [003] ...1   433.935473: preempt_count_add <-kmem_cache_free
              sh-1512  [003] ...1   433.935481: preempt_count_add <-_raw_spin_lock
              sh-1512  [003] ...1   433.935485: preempt_count_add <-__fd_install
              sh-1512  [003] ...1   433.935491: preempt_count_add <-_raw_spin_lock
              sh-1512  [003] ...1   433.935498: preempt_count_add <-_raw_spin_lock

root:/sys/kernel/debug/tracing# echo > set_ftrace_filter 
root:/sys/kernel/debug/tracing# 
root:/sys/kernel/debug/tracing# echo > trace
root:/sys/kernel/debug/tracing# cat trace
# tracer: function_graph
#
# CPU  DURATION                  FUNCTION CALLS
# |     |   |                     |   |   |   |
 1)   0.166 us    |        } /* __msecs_to_jiffies */
 1)   0.167 us    |        __rcu_read_unlock();
 1)   7.416 us    |      } /* pick_next_task_fair */
 1)               |      pick_next_task_idle() {
 1)               |        put_prev_task_fair() {
 1)   0.250 us    |          put_prev_entity();
 1)   2.167 us    |        }
 1)   4.000 us    |      }
 1)   0.208 us    |      fpsimd_thread_switch();
 1)   0.209 us    |      hw_breakpoint_thread_switch();
 1)   0.167 us    |      uao_thread_switch();
 ------------------------------------------
 1)   rcu_pre-8    =>    <idle>-0   
 ------------------------------------------

 1)               |      finish_task_switch() {
 1)               |        _raw_spin_unlock_irq() {
 1)   0.208 us    |          do_raw_spin_unlock();
 1)   0.209 us    |          preempt_count_sub();
 1)   4.167 us    |        }
 1)   6.500 us    |      }
 1) ! 269.166 us  |    } /* schedule_idle */
 1) # 3218.375 us |  } /* do_idle */
 1)               |  do_idle() {
 1)               |    quiet_vmstat() {
 1)               |      need_update() {
 1)   0.208 us    |        first_online_pgdat();
 1)   0.208 us    |        next_zone();
 1)   0.167 us    |        next_zone();
 1)   0.208 us    |        next_zone();
 1)   7.959 us    |      }
 1)   9.792 us    |    }

root:/sys/kernel/debug/tracing# echo wakeup > current_tracer 
root:/sys/kernel/debug/tracing# echo > trace
root:/sys/kernel/debug/tracing# cat trace
# tracer: wakeup
#
# wakeup latency trace v1.1.5 on 4.14.74
# --------------------------------------------------------------------
# latency: 9427 us, #4517/4517, CPU#0 | (M:preempt VP:0, KP:0, SP:0 HP:0 #P:4)
#    -----------------
#    | task: isp_evt0-16588 (uid:0 nice:0 policy:1 rt_prio:99)
#    -----------------
#
#                  _------=> CPU#            
#                 / _-----=> irqs-off        
#                | / _----=> need-resched    
#                || / _---=> hardirq/softirq 
#                ||| / _--=> preempt-depth   
#                |||| /     delay            
#  cmd     pid   ||||| time  |   caller      
#     \   /      |||||  \    |   /         
xxx_test-16618   3d..4    0us :  16618:120:R   + [000] 16588:  0:R yyy_zzz0
xxx_test-16618   3d..4    2us : try_to_wake_up <-wake_up_process
yyy_zzz0-16588   0d..3    6us : preempt_count_add <-prandom_u32
yyy_zzz0-16588   0d..4    7us : preempt_count_sub <-prandom_u32
yyy_zzz0-16588   0d..3    8us : update_rq_clock <-__schedule
yyy_zzz0-16588   0d..3   10us : pick_next_task_stop <-__schedule
yyy_zzz0-16588   0d..3   11us : pick_next_task_dl <-__schedule
yyy_zzz0-16588   0d..3   13us : pick_next_task_rt <-__schedule
yyy_zzz0-16588   0d..3   14us : update_curr_rt <-pick_next_task_rt
yyy_zzz0-16588   0d..3   16us : dbs_update_util_handler <-update_curr_rt
yyy_zzz0-16588   0d..3   17us : cpuacct_charge <-update_curr_rt
yyy_zzz0-16588   0d..3   18us : __rcu_read_lock <-cpuacct_charge

root:/sys/kernel/debug/tracing# echo preemptirqsoff > current_tracer 
root:/sys/kernel/debug/tracing# echo display-graph > trace_options 
root:/sys/kernel/debug/tracing# cat trace
# tracer: preemptirqsoff
#
# preemptirqsoff latency trace v1.1.5 on 4.14.74
# --------------------------------------------------------------------
# latency: 4920 us, #5233/5233, CPU#1 | (M:preempt VP:0, KP:0, SP:0 HP:0 #P:4)
#    -----------------
#    | task: ls-22713 (uid:0 nice:0 policy:0 rt_prio:0)
#    -----------------
#  => started at: preempt_count_add
#  => ended at:   unmap_page_range
#
#
#                                       _-----=> irqs-off        
#                                      / _----=> need-resched    
#                                     | / _---=> hardirq/softirq 
#                                     || / _--=> preempt-depth   
#                                     ||| /                      
#     TIME        CPU  TASK/PID       ||||  DURATION                  FUNCTION CALLS
#      |          |     |    |        ||||   |   |                     |   |   |   |
 1153.066240 |   1)    ls-22713    |  ...1  0.000 us    |  preempt_count_add();
 1153.066242 |   1)    ls-22713    |  ...1  0.250 us    |  do_raw_spin_lock();
 1153.066244 |   1)    ls-22713    |  ...1  0.208 us    |  _vm_normal_page();
 1153.066246 |   1)    ls-22713    |  ...1  0.208 us    |  mark_page_accessed();
 1153.066248 |   1)    ls-22713    |  ...1              |  page_remove_rmap() {
 1153.066249 |   1)    ls-22713    |  ...1              |    lock_page_memcg() {
 1153.066250 |   1)    ls-22713    |  ...1  0.167 us    |      __rcu_read_lock();
 1153.066251 |   1)    ls-22713    |  ...1  2.167 us    |    }
 1153.066252 |   1)    ls-22713    |  ...1              |    unlock_page_memcg() {
 1153.066253 |   1)    ls-22713    |  ...1              |      __unlock_page_memcg() {
 1153.066254 |   1)    ls-22713    |  ...1  0.167 us    |        __rcu_read_unlock();
 1153.066256 |   1)    ls-22713    |  ...1  2.167 us    |      }
 1153.066257 |   1)    ls-22713    |  ...1  3.875 us    |    }
 1153.066258 |   1)    ls-22713    |  ...1  9.542 us    |  }
 1153.066259 |   1)    ls-22713    |  ...1  0.167 us    |  _vm_normal_page();
 1153.066261 |   1)    ls-22713    |  ...1  0.208 us    |  mark_page_accessed();
 1153.066263 |   1)    ls-22713    |  ...1              |  page_remove_rmap() {
 1153.066264 |   1)    ls-22713    |  ...1              |    lock_page_memcg() {
 1153.066265 |   1)    ls-22713    |  ...1  0.208 us    |      __rcu_read_lock();
 1153.066266 |   1)    ls-22713    |  ...1  2.209 us    |    }
 1153.066267 |   1)    ls-22713    |  ...1              |    unlock_page_memcg() {
 1153.066268 |   1)    ls-22713    |  ...1              |      __unlock_page_memcg() {
 1153.066269 |   1)    ls-22713    |  ...1  0.208 us    |        __rcu_read_unlock();
 1153.066271 |   1)    ls-22713    |  ...1  2.125 us    |      }
 1153.066273 |   1)    ls-22713    |  ...1  3.834 us    |    }
 1153.066273 |   1)    ls-22713    |  ...1  10.167 us   |  }
 1153.066274 |   1)    ls-22713    |  ...1  0.208 us    |  _vm_normal_page();
 1153.066276 |   1)    ls-22713    |  ...1  0.208 us    |  mark_page_accessed();
 1153.066278 |   1)    ls-22713    |  ...1              |  page_remove_rmap() {
 1153.066279 |   1)    ls-22713    |  ...1              |    lock_page_memcg() {
 1153.066280 |   1)    ls-22713    |  ...1  0.167 us    |      __rcu_read_lock();
 1153.066282 |   1)    ls-22713    |  ...1  2.209 us    |    }
 1153.066283 |   1)    ls-22713    |  ...1              |    unlock_page_memcg() {
 1153.066284 |   1)    ls-22713    |  ...1              |      __unlock_page_memcg() {
 1153.066285 |   1)    ls-22713    |  ...1  0.208 us    |        __rcu_read_unlock();
 1153.066287 |   1)    ls-22713    |  ...1  2.084 us    |      }
 1153.066288 |   1)    ls-22713    |  ...1  3.917 us    |    }
 1153.066288 |   1)    ls-22713    |  ...1  9.459 us    |  }

root:/sys/kernel/debug/tracing# cat tracing_max_latency 
1684
root:/sys/kernel/debug/tracing# cat trace
# tracer: irqsoff
#
# irqsoff latency trace v1.1.5 on 4.14.74
# --------------------------------------------------------------------
# latency: 1684 us, #917/917, CPU#1 | (M:preempt VP:0, KP:0, SP:0 HP:0 #P:4)
#    -----------------
#    | task: stressapptest-1889 (uid:0 nice:0 policy:0 rt_prio:0)
#    -----------------
#  => started at: el0_irq_naked
#  => ended at:   irq_exit
#
#
#                                       _-----=> irqs-off        
#                                      / _----=> need-resched    
#                                     | / _---=> hardirq/softirq 
#                                     || / _--=> preempt-depth   
#                                     ||| /                      
#     TIME        CPU  TASK/PID       ||||  DURATION                  FUNCTION CALLS
#      |          |     |    |        ||||   |   |                     |   |   |   |
 1170.547913 |   1)  stressa-1889  |  d...  0.000 us    |  el0_irq_naked();
 1170.549600 |   1)  stressa-1889  |  dns.  0.000 us    |  trace_hardirqs_on();
stressap-1889    1dns. 1715us : <stack trace>
 => gic_handle_irq
 => el0_irq_naked

root:~# echo 1 >  /sys/block/mmcblk0/trace/enable 
root:~# echo blk > /sys/kernel/debug/tracing/current_tracer 
root:~# echo 1 > /sys/kernel/debug/tracing/tracing_on 
root:~# cat /sys/kernel/debug/tracing/trace
# tracer: blk
#
 jbd2/mmcblk0p9--1100  [001] ...1   679.901410: 179,0    A  WS 323710 + 8 <- (179,9) 265048
 jbd2/mmcblk0p9--1100  [001] ...1   679.901428: 179,0    Q  WS 323710 + 8 [jbd2/mmcblk0p9-]
 jbd2/mmcblk0p9--1100  [001] ...1   679.901469: 179,0    G  WS 323710 + 8 [jbd2/mmcblk0p9-]
 jbd2/mmcblk0p9--1100  [001] ...1   679.901474: 179,0    P   N [jbd2/mmcblk0p9-]
 jbd2/mmcblk0p9--1100  [001] ...1   679.901491: 179,0    A  WS 323718 + 8 <- (179,9) 265056
         mmcqd/0-998   [000] ...1   679.901627: 179,0    m   N cfq1100SN dispatch_insert
         mmcqd/0-998   [000] ...1   679.901635: 179,0    m   N cfq1100SN dispatched a request
         mmcqd/0-998   [000] ...1   679.901641: 179,0    m   N cfq1100SN activate rq, drv=1
         mmcqd/0-998   [000] ...2   679.901645: 179,0    D  WS 323710 + 16 [mmcqd/0]
         mmcqd/0-998   [000] ...1   679.902979: 179,0    C  WS 323710 + 16 [0]

# tracer: irqsoff
#
# irqsoff latency trace v1.1.5 on 4.14.74
# --------------------------------------------------------------------
# latency: 1152 us, #4/4, CPU#1 | (M:preempt VP:0, KP:0, SP:0 HP:0 #P:4)
#    -----------------
#    | task: hapi_xj3_test-4680 (uid:0 nice:0 policy:0 rt_prio:0)
#    -----------------
#  => started at: dwe0_reset_control
#  => ended at:   dwe0_reset_control
#
#
#                  _------=> CPU#            
#                 / _-----=> irqs-off        
#                | / _----=> need-resched    
#                || / _---=> hardirq/softirq 
#                ||| / _--=> preempt-depth   
#                |||| /     delay            
#  cmd     pid   ||||| time  |   caller      
#     \   /      |||||  \    |   /         
hapi_xj3-4680    1d...    0us#: _raw_spin_lock_irqsave <-dwe0_reset_control
hapi_xj3-4680    1d..1 1151us : _raw_spin_unlock_irqrestore <-dwe0_reset_control
hapi_xj3-4680    1d..1 1155us : trace_hardirqs_on <-dwe0_reset_control
hapi_xj3-4680    1d..1 1160us : <stack trace>
 => dwe_fop_open
 => chrdev_open
 => do_dentry_open.isra.1
 => vfs_open
 => path_openat
 => do_filp_open
 => do_sys_open
 => SyS_openat
 => el0_svc_naked

root:/sys/kernel/debug/tracing# cat trace
# tracer: irqsoff
#
# irqsoff latency trace v1.1.5 on 4.14.74
# --------------------------------------------------------------------
# latency: 1934 us, #1076/1076, CPU#0 | (M:preempt VP:0, KP:0, SP:0 HP:0 #P:4)
#    -----------------
#    | task: swapper/0-0 (uid:0 nice:0 policy:0 rt_prio:0)
#    -----------------
#  => started at: arch_cpu_idle
#  => ended at:   irq_exit
#
#
#                  _------=> CPU#            
#                 / _-----=> irqs-off        
#                | / _----=> need-resched    
#                || / _---=> hardirq/softirq 
#                ||| / _--=> preempt-depth   
#                |||| /     delay            
#  cmd     pid   ||||| time  |   caller      
#     \   /      |||||  \    |   /         
  <idle>-0       0d..1    1us : el1_irq <-arch_cpu_idle
  <idle>-0       0d..2    5us : __handle_domain_irq <-gic_handle_irq
  <idle>-0       0d..2    8us : irq_enter <-__handle_domain_irq
  <idle>-0       0d..2   11us : rcu_irq_enter <-irq_enter
  <idle>-0       0d..2   15us : rcu_dynticks_eqs_exit <-rcu_irq_enter
  <idle>-0       0d..2   19us : __local_bh_disable_ip <-irq_enter
  <idle>-0       0d..2   22us : tick_irq_enter <-irq_enter
  <idle>-0       0d..2   26us : tick_check_oneshot_broadcast_this_cpu <-tick_irq_enter
  <idle>-0       0d..2   30us : ktime_get <-tick_irq_enter
  <idle>-0       0d..2   38us : arch_counter_read <-ktime_get
  <idle>-0       0d..2   41us : arch_counter_read_cc <-arch_counter_read
  <idle>-0       0d..2   45us : tick_nohz_stop_idle <-tick_irq_enter
  <idle>-0       0d..2   48us : update_ts_time_stats <-tick_nohz_stop_idle
  <idle>-0       0d..2   52us : nr_iowait_cpu <-update_ts_time_stats
  <idle>-0       0d..2   58us : _local_bh_enable <-irq_enter
.......
  <idle>-0       0d.h2 1344us : _raw_spin_lock <-x3_ldc_irq
  <idle>-0       0d.h2 1346us : preempt_count_add <-_raw_spin_lock
  <idle>-0       0d.h3 1347us : do_raw_spin_lock <-_raw_spin_lock
  <idle>-0       0d.h3 1349us : LOG_INTER <-x3_ldc_irq
  <idle>-0       0d.h3 1350us : _raw_spin_unlock <-x3_ldc_irq
  <idle>-0       0d.h3 1352us : do_raw_spin_unlock <-_raw_spin_unlock
  <idle>-0       0d.h3 1353us : preempt_count_sub <-_raw_spin_unlock
  <idle>-0       0d.h2 1354us : enable_irq <-x3_ldc_irq
  <idle>-0       0d.h2 1355us : __irq_get_desc_lock <-enable_irq
  <idle>-0       0d.h2 1356us : _raw_spin_lock_irqsave <-__irq_get_desc_lock
  <idle>-0       0d.h2 1357us : preempt_count_add <-_raw_spin_lock_irqsave
  <idle>-0       0d.h3 1359us : do_raw_spin_lock <-_raw_spin_lock_irqsave
  <idle>-0       0d.h3 1360us : __enable_irq <-enable_irq
  <idle>-0       0d.h3 1361us : irq_startup <-__enable_irq
  <idle>-0       0d.h3 1362us : irq_enable <-irq_startup
  <idle>-0       0d.h3 1364us : check_irq_resend <-irq_startup
  <idle>-0       0d.h3 1365us : __irq_put_desc_unlock <-enable_irq
  <idle>-0       0d.h3 1366us : _raw_spin_unlock_irqrestore <-__irq_put_desc_unlock
  <idle>-0       0d.h3 1367us : do_raw_spin_unlock <-_raw_spin_unlock_irqrestore
  <idle>-0       0d.h3 1369us : preempt_count_sub <-_raw_spin_unlock_irqrestore
  <idle>-0       0d.h2 1370us : add_interrupt_randomness <-handle_irq_event_percpu
  <idle>-0       0d.h2 1372us : note_interrupt <-handle_irq_event_percpu
  <idle>-0       0d.h2 1373us : _raw_spin_lock <-handle_irq_event
  <idle>-0       0d.h2 1374us : preempt_count_add <-_raw_spin_lock
.......
  <idle>-0       0d.h2 1925us : irqtime_account_irq <-irq_exit
  <idle>-0       0d.h2 1926us : irqtime_account_delta.isra.0 <-irqtime_account_irq
  <idle>-0       0d.h2 1927us : preempt_count_sub <-irq_exit
  <idle>-0       0d..2 1929us : ksoftirqd_running <-irq_exit
  <idle>-0       0d..2 1930us : __do_softirq <-irq_exit
  <idle>-0       0d..2 1931us : irqtime_account_irq <-__do_softirq
  <idle>-0       0d..2 1932us : __local_bh_disable_ip <-__do_softirq
  <idle>-0       0d.s1 1934us : __do_softirq <-irq_exit
  <idle>-0       0d.s1 1937us : trace_hardirqs_on <-irq_exit
  <idle>-0       0d.s1 1946us : <stack trace>
 => gic_handle_irq
 => el1_irq
 => arch_cpu_idle
 => default_idle_call
 => do_idle
 => cpu_startup_entry
 => rest_init
 => start_kernel

# tracer: irqsoff
#
# irqsoff latency trace v1.1.5 on 4.14.74
# --------------------------------------------------------------------
# latency: 3374 us, #3732/3732, CPU#2 | (M:preempt VP:0, KP:0, SP:0 HP:0 #P:4)
#    -----------------
#    | task: hapi_xj3_test-3282 (uid:0 nice:0 policy:0 rt_prio:0)
#    -----------------
#  => started at: unset_migratetype_isolate
#  => ended at:   unset_migratetype_isolate
#
#
#                                       _-----=> irqs-off        
#                                      / _----=> need-resched    
#                                     | / _---=> hardirq/softirq 
#                                     || / _--=> preempt-depth   
#                                     ||| /                      
#     TIME        CPU  TASK/PID       ||||  DURATION                  FUNCTION CALLS
#      |          |     |    |        ||||   |   |                     |   |   |   |
  108.240596 |   2)  hapi_xj-3282  |  d...  0.000 us    |  _raw_spin_lock_irqsave();
  108.240597 |   2)  hapi_xj-3282  |  d...              |  preempt_count_add() {
  108.240598 |   2)  hapi_xj-3282  |  d..1  0.209 us    |    preempt_count_add.part.2();
  108.240601 |   2)  hapi_xj-3282  |  d..1  2.041 us    |  }
  108.240602 |   2)  hapi_xj-3282  |  d..1  0.208 us    |  do_raw_spin_lock();
  108.240604 |   2)  hapi_xj-3282  |  d..1  0.208 us    |  get_pfnblock_flags_mask();
  108.240606 |   2)  hapi_xj-3282  |  d..1              |  move_freepages_block() {    //這塊是cma的操作,可見CMA可能影響性能
  108.240607 |   2)  hapi_xj-3282  |  d..1              |    pfn_valid() {
  108.240608 |   2)  hapi_xj-3282  |  d..1  0.209 us    |      memblock_is_map_memory();
  108.240610 |   2)  hapi_xj-3282  |  d..1  2.083 us    |    }
...省略掉大量重復
  108.243953 |   2)  hapi_xj-3282  |  d..1              |    pfn_valid() {
  108.243954 |   2)  hapi_xj-3282  |  d..1  0.209 us    |      memblock_is_map_memory();
  108.243956 |   2)  hapi_xj-3282  |  d..1  2.042 us    |    }
  108.243956 |   2)  hapi_xj-3282  |  d..1  3349.792 us |  }
  108.243957 |   2)  hapi_xj-3282  |  d..1  0.458 us    |  __mod_zone_page_state();
  108.243960 |   2)  hapi_xj-3282  |  d..1  0.292 us    |  __mod_zone_page_state();
  108.243962 |   2)  hapi_xj-3282  |  d..1              |  set_pageblock_migratetype() {
  108.243963 |   2)  hapi_xj-3282  |  d..1  0.375 us    |    set_pfnblock_flags_mask();
  108.243965 |   2)  hapi_xj-3282  |  d..1  2.292 us    |  }
  108.243966 |   2)  hapi_xj-3282  |  d..1              |  _raw_spin_unlock_irqrestore() {
  108.243967 |   2)  hapi_xj-3282  |  d..1  0.250 us    |    do_raw_spin_unlock();
  108.243969 |   2)  hapi_xj-3282  |  d..1  0.000 us    |  _raw_spin_unlock_irqrestore();
  108.243972 |   2)  hapi_xj-3282  |  d..1  0.000 us    |  trace_hardirqs_on();
hapi_xj3-3282    2d..1 3386us : <stack trace>
 => alloc_contig_range
 => cma_alloc
 => ion_cma_allocate
 => ion_alloc
 => pym_alloc_ion_bufffer
 => x3_pym_ioctl
 => do_vfs_ioctl
 => SyS_ioctl
 => el0_svc_naked
  108.243955 |   2)  hapi_xj-3282  |  d..1  0.209 us    |      } /* memblock_is_map_memory */
  108.243956 |   2)  hapi_xj-3282  |  d..1  2.042 us    |    } /* pfn_valid */
  108.243956 |   2)  hapi_xj-3282  |  d..1  3349.792 us |  } /* move_freepages_block */
  108.243957 |   2)  hapi_xj-3282  |  d..1  0.458 us    |  __mod_zone_page_state();
  108.243960 |   2)  hapi_xj-3282  |  d..1  0.292 us    |  __mod_zone_page_state();
  108.243962 |   2)  hapi_xj-3282  |  d..1              |  set_pageblock_migratetype() {
  108.243963 |   2)  hapi_xj-3282  |  d..1  0.375 us    |    set_pfnblock_flags_mask();
  108.243965 |   2)  hapi_xj-3282  |  d..1  2.292 us    |  }
  108.243966 |   2)  hapi_xj-3282  |  d..1              |  _raw_spin_unlock_irqrestore() {
  108.243967 |   2)  hapi_xj-3282  |  d..1  0.250 us    |    do_raw_spin_unlock();
  108.243969 |   2)  hapi_xj-3282  |  d..1  0.000 us    |  _raw_spin_unlock_irqrestore();
  108.243972 |   2)  hapi_xj-3282  |  d..1  0.000 us    |  trace_hardirqs_on();
hapi_xj3-3282    2d..1 3386us : <stack trace>
 => alloc_contig_range
 => cma_alloc
 => ion_cma_allocate
 => ion_alloc
 => pym_alloc_ion_bufffer
 => x3_pym_ioctl
 => do_vfs_ioctl
 => SyS_ioctl
 => el0_svc_naked
  • tracing_thresh
    • 記錄超過這個tracing_thresh的lantecy
  • tracing_max_latency
    • 顯示最大的lantency,和當前trace里記錄的一致。

2.5 Function Trace的設置

  • available_filter_functions: 列出所有可以過濾的函數
  • dyn_ftrace_total_info: 函數總數
  • set_ftrace_filter: 設置跟蹤的函數
  • set_ftrace_notrace: 設置不跟蹤的函數
  • set_ftrace_pid: 設置只在哪些進程上過濾
  • enabled_functions: 顯示當前所有被跟蹤的函數

這組文件用於過濾函數。從dyn_ftrace_total_info可以看到,一個運行的kernel可跟蹤的函數可能有幾萬個,如果不做過濾,得到的log冗余信息太多。

set_ftrace_filter的使用規則如下

  set_ftrace_filter     - echo function name in here to only trace these functions,使用echo 設置
             accepts: func_full_name or glob-matching-pattern,函數全名或者匹配字符串
             modules: Can select a group via module, 可以通過module選擇一組函數
              Format: :mod:<module-name>, module設置使用:mod:開頭,例如:mod:hobot_ipu 
             example: echo :mod:ext3 > set_ftrace_filter
            triggers: a command to perform when function is hit,執行到被trace的函數時,可以指定一個動作,還可以指定第幾次執行trigger
              Format: <function>:<trigger>[:count]
             trigger: traceon, traceoff
                      enable_event:<system>:<event>
                      disable_event:<system>:<event>
                      stacktrace
                      snapshot
                      dump
                      cpudump
             example: echo do_fault:traceoff > set_ftrace_filter
                      echo do_trap:traceoff:3 > set_ftrace_filter
             The first one will disable tracing every time do_fault is hit
             The second will disable tracing at most 3 times when do_trap is hit
               The first time do trap is hit and it disables tracing, the
               counter will decrement to 2. If tracing is already disabled,
               the counter will not decrement. It only decrements when the
               trigger did work
             To remove trigger without count:
               echo '!<function>:<trigger> > set_ftrace_filter
             To remove trigger with a count:
               echo '!<function>:<trigger>:0 > set_ftrace_filter

需要把tracer設置成function或者function_graph

root:/sys/kernel/debug/tracing# echo function_graph > current_tracer 
root:/sys/kernel/debug/tracing# echo :mod:comp_xpu > set_ftrace_filter 
root:/sys/kernel/debug/tracing# head enabled_functions 
xpu_set_input_img_size [comp_xpu] (1)    
xpu_set_rdma_stride [comp_xpu] (1)    
xpu_set_us_wdma_stride [comp_xpu] (1)    
xpu_set_ds_wdma_stride [comp_xpu] (1)    
xpu_set_ds_roi_enable [comp_xpu] (1)    
xpu_set_ds_roi_rect [comp_xpu] (1)    
xpu_set_ds_enable [comp_xpu] (1)    
xpu_set_ds2_wdma_enable [comp_xpu] (1)    
xpu_set_ds_target_size [comp_xpu] (1)    
xpu_set_ds_step [comp_xpu] (1)    
root:/sys/kernel/debug/tracing# echo 0 > tracing_on 
root:/sys/kernel/debug/tracing# echo > trace
root:/sys/kernel/debug/tracing# echo 1 > tracing_on 
root:/sys/kernel/debug/tracing# cat trace
# tracer: function_graph
#
# CPU  DURATION                  FUNCTION CALLS
# |     |   |                     |   |   |   |
 0) + 10.792 us   |  xx_xpu_open [comp_xpu]();
 0)               |  xx_xpu_ioctl [comp_xpu]() {
 0) + 23.708 us   |    xpu_bind_chain_group [comp_xpu]();
 0) + 28.042 us   |  }
 0)               |  xx_xpu_ioctl [comp_xpu]() {
 0)               |    xpu_video_init [comp_xpu]() {
 0)               |      xpu_update_ds_param [comp_xpu]() {
 0)               |        xpu_update_ds_ch_param [comp_xpu]() {
 0)   0.834 us    |          xpu_get_shd_rdy [comp_xpu]();
 0)   0.375 us    |          xpu_set_shd_rdy [comp_xpu]();
 0)   1.167 us    |          xpu_set_ds_target_size [comp_xpu]();
 0)   0.583 us    |          xpu_set_ds_wdma_stride [comp_xpu]();
 0)   1.333 us    |          xpu_set_ds_step [comp_xpu]();
 0)   1.625 us    |          xpu_set_ds_roi_rect [comp_xpu]();
 0)   0.292 us    |          xpu_get_shd_rdy [comp_xpu]();
 0)   0.209 us    |          xpu_set_shd_rdy [comp_xpu]();
 0) + 28.042 us   |        }
 0) + 10.875 us   |        xpu_set_group_leader [comp_xpu]();
 0) + 45.000 us   |      }
 0) ! 229.083 us  |    }
 0) ! 232.666 us  |  }
 0)               |  xx_xpu_ioctl [comp_xpu]() {
 0) + 25.292 us   |    xpu_video_reqbufs [comp_xpu]();
 0) + 28.667 us   |  }
 0)               |  xx_xpu_ioctl [comp_xpu]() {
 0)   0.375 us    |    xpu_video_getindex [comp_xpu]();
 0)   3.458 us    |  }
 0)               |  xx_xpu_ioctl [comp_xpu]() {
 0) * 15894.87 us |    xpu_alloc_ion_bufffer [comp_xpu]();
 0) * 15916.04 us |  }
 0) + 23.208 us   |  xx_xpu_mmap [comp_xpu]();
 0)   9.958 us    |  xx_xpu_mmap [comp_xpu]();
 0) + 11.625 us   |  xx_xpu_mmap [comp_xpu]();
 0)   4.500 us    |  xx_xpu_mmap [comp_xpu]();
 0) + 12.375 us   |  xx_xpu_mmap [comp_xpu]();
 0)   9.583 us    |  xx_xpu_mmap [comp_xpu]();
 0) + 11.417 us   |  xx_xpu_mmap [comp_xpu]();
 0) + 49.542 us   |  xx_xpu_mmap [comp_xpu]();
 0) + 12.375 us   |  xx_xpu_mmap [comp_xpu]();
 0)   9.541 us    |  xx_xpu_mmap [comp_xpu]();
 0) + 11.458 us   |  xx_xpu_mmap [comp_xpu]();
 0)   4.667 us    |  xx_xpu_mmap [comp_xpu]();
 0)   6.333 us    |  xx_xpu_open [comp_xpu]();
 0)               |  xx_xpu_ioctl [comp_xpu]() {
 0) + 31.334 us   |    xpu_bind_chain_group [comp_xpu]();
 0) + 35.791 us   |  }
 0)               |  xx_xpu_ioctl [comp_xpu]() {
 0)               |    xpu_video_init [comp_xpu]() {
 0)               |      xpu_update_common_param [comp_xpu]() {
 0)   0.541 us    |        xpu_get_shd_rdy [comp_xpu]();
 0)   0.333 us    |        xpu_set_shd_rdy [comp_xpu]();
 0)   0.833 us    |        xpu_src_select [comp_xpu]();
 0)   0.375 us    |        xpu_set_frameid_enable [comp_xpu]();
 0)   0.625 us    |        xpu_set_input_img_size [comp_xpu]();
 0)   0.958 us    |        xpu_set_ds2_wdma_enable [comp_xpu]();
 0)               |        xpu_update_ds_ch_param [comp_xpu]() {
 0)   0.334 us    |          xpu_get_shd_rdy [comp_xpu]();
 0)   0.250 us    |          xpu_set_shd_rdy [comp_xpu]();
 0)   1.209 us    |          xpu_set_ds_target_size [comp_xpu]();
 0)   0.708 us    |          xpu_set_ds_wdma_stride [comp_xpu]();
 0)   1.542 us    |          xpu_set_ds_step [comp_xpu]();
 0)   1.916 us    |          xpu_set_ds_roi_rect [comp_xpu]();
 0)   0.333 us    |          xpu_get_shd_rdy [comp_xpu]();
 0)   0.250 us    |          xpu_set_shd_rdy [comp_xpu]();
 0) + 26.958 us   |        }

root:/sys/kernel/debug/tracing# echo :mod:comp_pim >> set_ftrace_filter 
root:/sys/kernel/debug/tracing# cat enabled_functions | grep pim
pim_select_input_path [comp_pim] (1)    
pim_enable_module [comp_pim] (1)    
pim_enable_otf_clk [comp_pim] (1)    
pim_enable_ddr_clk [comp_pim] (1)    
pim_rdma_set_addr [comp_pim] (1)    
pim_wdma_ds_set_addr [comp_pim] (1)    

2.6 靜態trace事件的配置

  • available_events: 當前所有支持的trace event,比如xj3上有1236個,
  • events/: events/目錄下第一級目錄是模塊目錄,第二級目錄時事件目錄
  • set_event:用於設置打開事件,也可以查詢
  • set_event_pid

跟蹤靜態事件一般把tracer設置為nop。

root:/sys/kernel/debug/tracing# echo ext4_releasepage > set_event
root:/sys/kernel/debug/tracing# echo ext4_mballoc_alloc >> set_event
root:/sys/kernel/debug/tracing# echo 0 > tracing_on 
root:/sys/kernel/debug/tracing# echo nop > current_tracer 
root:/sys/kernel/debug/tracing# echo > trace
root:/sys/kernel/debug/tracing# echo 1 > tracing_on 
root:/sys/kernel/debug/tracing# mkdir /userdata/xxxxx
root:/sys/kernel/debug/tracing# sync

root:/sys/kernel/debug/tracing# cat trace
# tracer: nop
#
#                              _-----=> irqs-off
#                             / _----=> need-resched
#                            | / _---=> hardirq/softirq
#                            || / _--=> preempt-depth
#                            ||| /     delay
#           TASK-PID   CPU#  ||||    TIMESTAMP  FUNCTION
#              | |       |   ||||       |         |
           mkdir-29520 [002] ....  3492.156569: ext4_mballoc_alloc: dev 179,12 inode 271 orig 0/0/1@0 goal 0/0/1@0 result 0/8357/1@0 blks 1 grps 1 cr 1 flags  tail 0 broken 0

root:/sys/kernel/debug/tracing# echo syscalls > set_event
root:/sys/kernel/debug/tracing# cat set_event
syscalls:sys_exit_arm64_personality
syscalls:sys_enter_arm64_personality
syscalls:sys_exit_unshare
syscalls:sys_enter_unshare
syscalls:sys_exit_clone
syscalls:sys_enter_clone
syscalls:sys_exit_set_tid_address
syscalls:sys_enter_set_tid_address
syscalls:sys_exit_wait4
syscalls:sys_enter_wait4
syscalls:sys_exit_waitid
syscalls:sys_enter_waitid

root:/sys/kernel/debug/tracing# echo > trace
root:/sys/kernel/debug/tracing# echo xxxxx > /userdata/test.txt
root:/sys/kernel/debug/tracing# sync
root:/sys/kernel/debug/tracing# trace
-sh: trace: not found
root:/sys/kernel/debug/tracing# cat trace
# tracer: function_graph
#
# CPU  DURATION                  FUNCTION CALLS
# |     |   |                     |   |   |   |
 1)               |  /* sys_openat -> 0x3 */
 1)               |  /* sys_fcntl(fd: 1, cmd: 406, arg: a) */
 1)               |  /* sys_fcntl -> 0xb */
 1)               |  /* sys_dup3(oldfd: 3, newfd: 1, flags: 0) */
 1)               |  /* sys_dup3 -> 0x1 */
 1)               |  /* sys_close(fd: 3) */
 1)               |  /* sys_close -> 0x0 */
 1)               |  /* sys_wait4(upid: ffffffffffffffff, stat_addr: 7feae680fc, options: 3, ru: 0) */
 1)               |  /* sys_wait4 -> 0xfffffffffffffff6 */
 1)               |  /* sys_write(fd: 1, buf: 55825a3b00, count: 1) */
 1)               |  /* sys_write -> 0x1 */
 1)               |  /* sys_dup3(oldfd: b, newfd: 1, flags: 0) */
 1)               |  /* sys_dup3 -> 0x1 */
 1)               |  /* sys_close(fd: b) */
 1)               |  /* sys_close -> 0x0 */
 1)               |  /* sys_wait4(upid: ffffffffffffffff, stat_addr: 7feae6821c, options: 3, ru: 0) */
 1)               |  /* sys_wait4 -> 0xfffffffffffffff6 */
 1)               |  /* sys_ioctl(fd: 0, cmd: 5401, arg: 7feae68048) */
 1)               |  /* sys_ioctl -> 0x0 */
 1)               |  /* sys_ioctl(fd: 0, cmd: 5402, arg: 7feae68068) */
 1)               |  /* sys_ioctl -> 0x0 */
 1)               |  /* sys_geteuid() */
 1)               |  /* sys_geteuid -> 0x0 */
 1)               |  /* sys_openat(dfd: ffffffffffffff9c, filename: 7fa221dae0, flags: 80000, mode: 0) */
 1)               |  /* sys_openat -> 0x3 */

root:~# cd /sys/kernel/debug/tracing/events/ext4/ext4_readpage
root:/sys/kernel/debug/tracing/events/ext4/ext4_readpage# cat enable 
0
root:/sys/kernel/debug/tracing/events/ext4/ext4_readpage# cat filter 
none
root:/sys/kernel/debug/tracing/events/ext4/ext4_readpage# cat format 
name: ext4_readpage
ID: 731
format:
        field:unsigned short common_type;       offset:0;       size:2; signed:0;
        field:unsigned char common_flags;       offset:2;       size:1; signed:0;
        field:unsigned char common_preempt_count;       offset:3;       size:1; signed:0;
        field:int common_pid;   offset:4;       size:4; signed:1;

        field:dev_t dev;        offset:8;       size:4; signed:0;
        field:ino_t ino;        offset:16;      size:8; signed:0;
        field:unsigned long index;      offset:24;      size:8; signed:0;

print fmt: "dev %d,%d ino %lu page_index %lu", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), (unsigned long) REC->ino, (unsigned long) REC->index
root:/sys/kernel/debug/tracing/events/ext4/ext4_readpage# cat id 
731
root:/sys/kernel/debug/tracing/events/ext4/ext4_readpage# cat trigger 
# Available triggers:
# traceon traceoff snapshot stacktrace enable_event disable_event

2.7 動態trace事件的配置

  • kprobe_events,內核函數動態trace事件的設置和查詢

  • kprobe_profile,動態事件觸發的次數

  • uprobe_events,用戶空間函數動態trace事件的設置和查詢

  • uprobe_profile

    root:/sys/kernel/debug/tracing# echo 0 > tracing_on 
    root:/sys/kernel/debug/tracing# edho > trace
    root:/sys/kernel/debug/tracing# echo nop > current_tracer 
    root:/sys/kernel/debug/tracing# echo 'p:myprobe xxx_set_dma_addr base_addr=%x0 ds_ch=%x1 y_addr=%x2 cb_addr=%x
    root:/sys/kernel/debug/tracing# cat kprobe_events
    p:kprobes/myprobe xxx_set_dma_addr base_addr=%x0 ds_ch=%x1 y_addr=%x2 cb_addr=%x3
    root:/sys/kernel/debug/tracing# echo 1 > tracing_on
    root:/sys/kernel/debug/tracing# echo 1 > events/kprobes/enable
    root:/sys/kernel/debug/tracing# /app/bin/test_prog.sh
    root:/sys/kernel/debug/tracing# cat trace
    # tracer: nop
    #
    #                              _-----=> irqs-off
    #                             / _----=> need-resched
    #                            | / _---=> hardirq/softirq
    #                            || / _--=> preempt-depth
    #                            ||| /     delay
    #           TASK-PID   CPU#  ||||    TIMESTAMP  FUNCTION
    #              | |       |   ||||       |         |
             test_exe-29655 [001] d..1  4905.371874: myprobe: (xxx_set_dma_addr+0x0/0xa0 [comp_xxx]) base_addr=0xffffff800a57d000 ds_ch=0x5a00000 y_addr=0x5b00000 cb_addr=0xfc0bf9
             test_exe-29655 [001] d..1  4905.401943: myprobe: (xxx_set_dma_addr+0x0/0xa0 [comp_xxx]) base_addr=0xffffff800a57d000 ds_ch=0x5c00000 y_addr=0x5b80000 cb_addr=0xfc0bf9
             test_exe-29655 [001] d..1  4905.432149: myprobe: (xxx_set_dma_addr+0x0/0xa0 [comp_xxx]) base_addr=0xffffff800a57d000 ds_ch=0x5d00000 y_addr=0x5e00000 cb_addr=0xfc0bf9
             test_exe-29655 [001] d..1  4905.462380: myprobe: (xxx_set_dma_addr+0x0/0xa0 [comp_xxx]) base_addr=0xffffff800a57d000 ds_ch=0x5f00000 y_addr=0x5e80000 cb_addr=0xfc0bf9
             test_exe-29655 [001] d..1  4905.492587: myprobe: (xxx_set_dma_addr+0x0/0xa0 [comp_xxx]) base_addr=0xffffff800a57d000 ds_ch=0x6000000 y_addr=0x6100000 cb_addr=0xfc0bf9
             test_exe-29655 [001] d..1  4905.522793: myprobe: (xxx_set_dma_addr+0x0/0xa0 [comp_xxx]) base_addr=0xffffff800a57d000 ds_ch=0x6200000 y_addr=0x6180000 cb_addr=0xfc0bf9
             test_exe-29655 [001] d..1  4905.552998: myprobe: (xxx_set_dma_addr+0x0/0xa0 [comp_xxx]) base_addr=0xffffff800a57d000 ds_ch=0x6300000 y_addr=0x6400000 cb_addr=0xfc0bf9
             test_exe-29655 [001] d..1  4905.583207: myprobe: (xxx_set_dma_addr+0x0/0xa0 [comp_xxx]) base_addr=0xffffff800a57d000 ds_ch=0x6500000 y_addr=0x6480000 cb_addr=0xfc0bf9
             test_exe-29655 [001] d..1  4905.613419: myprobe: (xxx_set_dma_addr+0x0/0xa0 [comp_xxx]) base_addr=0xffffff800a57d000 ds_ch=0x5a00000 y_addr=0x5b00000 cb_addr=0xfc0bf9
             test_exe-29655 [001] d..1  4905.643628: myprobe: (xxx_set_dma_addr+0x0/0xa0 [comp_xxx]) base_addr=0xffffff800a57d000 ds_ch=0x5c00000 y_addr=0x5b80000 cb_addr=0xfc0bf9
             test_exe-29655 [001] d..1  4905.673825: myprobe: (xxx_set_dma_addr+0x0/0xa0 [comp_xxx]) base_addr=0xffffff800a57d000 ds_ch=0x5d00000 y_addr=0x5e00000 cb_addr=0xfc0bf9
    

2.8 instance功能

instance功能很強大。

在這個目錄下創建一個目錄,可以生成和tracefs下相同的所有配置文件。

相當於在全局的設置之外,可以創建多個instance,每個都有自己的獨立配置,比如下面這樣,foo跟蹤sched_wakeup event;bar跟蹤irq event;zoot跟蹤syscalls event,這樣可以很清晰地把不同類型的事件區分開。

/sys/kernel/debug/tracing/instances# mkdir xxx
/sys/kernel/debug/tracing/instances# ls xxx/
available_tracers     free_buffer           set_ftrace_filter     trace_clock           tracing_cpumask
buffer_size_kb        options               set_ftrace_notrace    trace_marker          tracing_max_latency
buffer_total_size_kb  per_cpu               set_ftrace_pid        trace_marker_raw      tracing_on
current_tracer        set_event             snapshot              trace_options
events      

# mkdir instances/foo
# mkdir instances/bar
# mkdir instances/zoot
# echo 100000 > buffer_size_kb
# echo 1000 > instances/foo/buffer_size_kb
# echo 5000 > instances/bar/per_cpu/cpu1/buffer_size_kb
# echo function > current_trace
# echo 1 > instances/foo/events/sched/sched_wakeup/enable
# echo 1 > instances/foo/events/sched/sched_wakeup_new/enable
# echo 1 > instances/foo/events/sched/sched_switch/enable
# echo 1 > instances/bar/events/irq/enable
# echo 1 > instances/zoot/events/syscalls/enable       

2.9 其它功能

  • stack_max_size
  • stack_trace
  • stack_trace_filter

stack trace就是利用ftrace的function tracer,在每次trace函數調用時來記錄stack的狀態

stack trace是個獨立的技術,可以使用中斷等方式抽樣,也可是利用ftrace,所以其配置文件在/proc下

stack_max_size記錄的是最大的深度的棧,Depth是棧的深度,Size是每個棧幀的大小,Location是函數的調用順序

CONFIG_STACK_TRACER enables the ftrace stack tracing functionality.
To enable it, write a '1' into /proc/sys/kernel/stack_tracer_enabled.

 # echo 1 > /proc/sys/kernel/stack_tracer_enabled

# cat stack_max_size
2928

 # cat stack_trace
        Depth    Size   Location    (18 entries)
        -----    ----   --------
  0)     2928     224   update_sd_lb_stats+0xbc/0x4ac
  1)     2704     160   find_busiest_group+0x31/0x1f1
  2)     2544     256   load_balance+0xd9/0x662
  3)     2288      80   idle_balance+0xbb/0x130
  4)     2208     128   __schedule+0x26e/0x5b9
  5)     2080      16   schedule+0x64/0x66
  6)     2064     128   schedule_timeout+0x34/0xe0
  7)     1936     112   wait_for_common+0x97/0xf1
  8)     1824      16   wait_for_completion+0x1d/0x1f
  9)     1808     128   flush_work+0xfe/0x119
 10)     1680      16   tty_flush_to_ldisc+0x1e/0x20
 11)     1664      48   input_available_p+0x1d/0x5c
 12)     1616      48   n_tty_poll+0x6d/0x134
 13)     1568      64   tty_poll+0x64/0x7f
 14)     1504     880   do_select+0x31e/0x511
 15)      624     400   core_sys_select+0x177/0x216
 16)      224      96   sys_select+0x91/0xb9
 17)      128     128   system_call_fastpath+0x16/0x1b
  • printk_formats

    用於外部工具讀取二進制的buffer數據,不常用,略。

  • saved_cmdlines

  • saved_cmdlines_size

  • saved_tgids

    saved_cmdlines 顯示當前tracing到的所有執行程序的pid和程序名.

    saved_cmdlines_size 用來設置最多顯示多少條,默認是128

    save_tgids記錄所有的pid和tigd對。

    root:/sys/kernel/debug/tracing# cat saved_cmdlines
    14497 awk
    14498 hobot-log
    14499 hobot-log
    14500 awk
    1062 tsn_worker
    2012 stressapptest
    2052 stressapptest
    2049 stressapptest
    14501 sleep
    2046 stressapptest
    12 watchdog/0
    15 watchdog/1
    2050 stressapptest
    2060 stressapptest
    
    root:/sys/kernel/debug/tracing# echo 1 > options/record-tgid 
    root:/sys/kernel/debug/tracing# cat saved_tgids 
    7 7
    8 8
    9 9
    11 11
    12 12
    ...
    28 28
    62 62
    994 994
    996 996
    1062 1062
    1099 1099
    ...
    2058 2012
    ...
    2097 2097
    13090 13090
    18191 18191
    ...
    22737 22737
    22738 22738
    

2.10 Trigger

用一個事件trigger一個命令(command)

可以trigger如下command:

  • enable_event/disable_event

  • stacktrace

  • snapshot

  • traceon/traceoff

  • hist

    # echo 'command[:count] [if filter]' > trigger
    
    For example, the following trigger causes kmalloc events to be      
     traced when a read system call is entered, and the :1 at the end    
     specifies that this enablement happens only once:                   
                                                                         
     # echo 'enable_event:kmem:kmalloc:1' > \                            
         /sys/kernel/debug/tracing/events/syscalls/sys_enter_read/trigger
    
    For example, the following trigger dumps a stacktrace every time the
    kmalloc tracepoint is hit:
    # echo 'stacktrace' > \                                    
          /sys/kernel/debug/tracing/events/kmem/kmalloc/trigger
    

2.10 Hlist

hist功能很強大,通過trigger觸發,可以提供強大的統計功能

# echo 'hist:key=id.syscall,common_pid.execname:val=hitcount:sort=id,hitcount if id == 16' > \                                
       /sys/kernel/debug/tracing/events/raw_syscalls/sys_enter/trigger                                                        
                                                                                                                              
# cat /sys/kernel/debug/tracing/events/raw_syscalls/sys_enter/hist                                                            
# trigger info: hist:keys=id.syscall,common_pid.execname:vals=hitcount:sort=id.syscall,hitcount:size=2048 if id == 16 [active]
                                                                                                                              
{ id: sys_ioctl                     [ 16], common_pid: gmain           [      2769] } hitcount:          1                    
{ id: sys_ioctl                     [ 16], common_pid: evolution-addre [      8571] } hitcount:          1                    
{ id: sys_ioctl                     [ 16], common_pid: gmain           [      3003] } hitcount:          1                    
{ id: sys_ioctl                     [ 16], common_pid: gmain           [      2781] } hitcount:          1                    
{ id: sys_ioctl                     [ 16], common_pid: gmain           [      2829] } hitcount:          1                    
{ id: sys_ioctl                     [ 16], common_pid: bash            [      8726] } hitcount:          1                    
{ id: sys_ioctl                     [ 16], common_pid: bash            [      8508] } hitcount:          1                    
{ id: sys_ioctl                     [ 16], common_pid: gmain           [      2970] } hitcount:          1                    
{ id: sys_ioctl                     [ 16], common_pid: gmain           [      2768] } hitcount:          1                    
.                                                                                                                             
.                                                                                                                             
.                                                                                                                             
{ id: sys_ioctl                     [ 16], common_pid: pool            [      8559] } hitcount:         45                    
{ id: sys_ioctl                     [ 16], common_pid: pool            [      8555] } hitcount:         48                    
{ id: sys_ioctl                     [ 16], common_pid: pool            [      8551] } hitcount:         48                    
{ id: sys_ioctl                     [ 16], common_pid: avahi-daemon    [       896] } hitcount:         66                    
{ id: sys_ioctl                     [ 16], common_pid: Xorg            [      1267] } hitcount:      26674                    
{ id: sys_ioctl                     [ 16], common_pid: compiz          [      2994] } hitcount:      73443                    
                                                                                                                              
Totals:                                                                                                                       
    Hits: 101162                                                                                                              
    Entries: 103                                                                                                              
    Dropped: 0                                                                                                                
                                                                                                                              
The above output shows that 'compiz' and 'Xorg' are far and away                                                              
the heaviest ioctl callers (which might lead to questions about                                                               
whether they really need to be making all those calls and to                                                                  
possible avenues for further investigation.)

3. 前端工具

除了通過tracefs設置ftrace以外,還可以使用trace-cmd來設置。trace-cmd可以簡化命令,生成trace.dat文件,並提供給kernelShark等UI工具解析,實現trace 可視化。

下載編譯ARM64 trace-cmd方法

git clone [https://github.com/rostedt/trace-cmd.git](https://github.com/rostedt/trace-cmd.git)
export CROSS_COMPILE=aarch64-linux-gnu-
export ARCH=arm64
make

源碼的Documentation目錄有trace-cmd和kernelShark的幫助文檔。

3.1 trace-cmd

root:/userdata# ./trace-cmd record -e hbpvt -e sched -e irq
/sys/kernel/debug/tracing/events/hbpvt/filter
/sys/kernel/debug/tracing/events/*/hbpvt/filter
/sys/kernel/debug/tracing/events/sched/filter
/sys/kernel/debug/tracing/events/*/sched/filter
/sys/kernel/debug/tracing/events/irq/filter
/sys/kernel/debug/tracing/events/*/irq/filter
Hit Ctrl^C to stop recording
^CKernel buffer statistics:
  Note: "entries" are the entries left in the kernel ring buffer and are not
        recorded in the trace data. They should all be zero.

......

CPU0 data recorded at offset=0x3bf000
    1646592 bytes in size
CPU1 data recorded at offset=0x551000
    122880 bytes in size
CPU2 data recorded at offset=0x56f000
    69632 bytes in size
CPU3 data recorded at offset=0x580000
    860160 bytes in size

root:/userdata# ls trace.dat -l
-rw-r--r--    1 root     root       6627328 Jan  1 08:06 trace.dat

root:/userdata# ./trace-cmd  report
version = 6
cpus=4
       trace-cmd-8484  [003]   391.101843: sched_stat_runtime:   comm=trace-cmd pid=8484 runtime=274667 [ns] vruntime=216201549 [ns]
       trace-cmd-8484  [003]   391.101857: sched_switch:         prev_comm=trace-cmd prev_pid=8484 prev_prio=120 prev_state=D ==> next_comm=trace-cmd next_pid=8526 next_prio=120
       trace-cmd-8524  [002]   391.101862: sched_stat_runtime:   comm=trace-cmd pid=8524 runtime=1816750 [ns] vruntime=447143972 [ns]
       trace-cmd-8524  [002]   391.101883: sched_switch:         prev_comm=trace-cmd prev_pid=8524 prev_prio=120 prev_state=D ==> next_comm=swapper/2 next_pid=0 next_prio=120
       trace-cmd-8525  [000]   391.102127: irq_handler_entry:    irq=10 name=hobot-uart0
       trace-cmd-8525  [000]   391.102140: irq_handler_exit:     irq=10 ret=handled
       trace-cmd-8525  [000]   391.102148: sched_waking:         comm=trace-cmd pid=8523 prio=120 target_cpu=001
       trace-cmd-8525  [000]   391.102161: sched_wakeup:         comm=trace-cmd pid=8523 prio=120 target_cpu=001
       trace-cmd-8525  [000]   391.102166: irq_handler_entry:    irq=10 name=hobot-uart0
          <idle>-0     [001]   391.102166: sched_switch:         prev_comm=swapper/1 prev_pid=0 prev_prio=120 prev_state=S ==> next_comm=trace-cmd next_pid=8523 next_prio=120
       trace-cmd-8525  [000]   391.102170: irq_handler_exit:     irq=10 ret=handled
       trace-cmd-8523  [001]   391.102174: sched_waking:         comm=trace-cmd pid=8524 prio=120 target_cpu=002
       trace-cmd-8523  [001]   391.102183: sched_wakeup:         comm=trace-cmd pid=8524 prio=120 target_cpu=002
          <idle>-0     [002]   391.102188: sched_switch:         prev_comm=swapper/2 prev_pid=0 prev_prio=120 prev_state=S ==> next_comm=trace-cmd next_pid=8524 next_prio=120
       trace-cmd-8523  [001]   391.102206: sched_stat_runtime:   comm=trace-cmd pid=8523 runtime=36749 [ns] vruntime=358754408 [ns]
       trace-cmd-8524  [002]   391.102207: sched_stat_runtime:   comm=trace-cmd pid=8524 runtime=28458 [ns] vruntime=447172430 [ns]
       trace-cmd-8523  [001]   391.102212: sched_switch:         prev_comm=trace-cmd prev_pid=8523 prev_prio=120 prev_state=D ==> next_comm=swapper/1 next_pid=0 next_prio=120
       trace-cmd-8524  [002]   391.102212: sched_switch:         prev_comm=trace-cmd prev_pid=8524 prev_prio=120 prev_state=D ==> next_comm=swapper/2 next_pid=0 next_prio=120
       trace-cmd-8525  [000]   391.102244: sched_stat_runtime:   comm=trace-cmd pid=8525 runtime=480585 [ns] vruntime=393791861 [ns]
       trace-cmd-8525  [000]   391.102251: sched_switch:         prev_comm=trace-cmd prev_pid=8525 prev_prio=120 prev_state=D ==> next_comm=swapper/0 next_pid=0 next_prio=120
       trace-cmd-8526  [003]   391.102671: irq_handler_entry:    irq=3 name=arch_timer
       trace-cmd-8526  [003]   391.102679: sched_waking:         comm=tsn_worker pid=1043 prio=89 target_cpu=000
       trace-cmd-8526  [003]   391.102687: sched_wakeup:         comm=tsn_worker pid=1043 prio=89 target_cpu=000
       trace-cmd-8526  [003]   391.102693: irq_handler_exit:     irq=3 ret=handled
          <idle>-0     [000]   391.102693: sched_switch:         prev_comm=swapper/0 prev_pid=0 prev_prio=120 prev_state=S ==> next_comm=tsn_worker next_pid=1043 next_prio=89
      tsn_worker-1043  [000]   391.102706: sched_switch:         prev_comm=tsn_worker prev_pid=1043 prev_prio=89 prev_state=D ==> next_comm=swapper/0 next_pid=0 next_prio=120
       trace-cmd-8526  [003]   391.102923: sched_stat_runtime:   comm=trace-cmd pid=8526 runtime=1051791 [ns] vruntime=225938915 [ns]
       trace-cmd-8526  [003]   391.102932: sched_switch:         prev_comm=trace-cmd prev_pid=8526 prev_prio=120 prev_state=D ==> next_comm=swapper/3 next_pid=0 next_prio=120
          <idle>-0     [001]   391.103063: irq_handler_entry:    irq=3 name=arch_timer
          <idle>-0     [000]   391.103063: irq_handler_entry:    irq=3 name=arch_timer
          <idle>-0     [002]   391.103063: irq_handler_entry:    irq=3 name=arch_timer
          <idle>-0     [003]   391.103063: irq_handler_entry:    irq=3 name=arch_timer

3.2 kernelShark

可以在板子上使用trace-cmd record 記錄事件,把得到的trace.data放到linux 桌面系統,用kernelshark打開,看到圖形化的信息

過濾只顯示sched_wakeup 事件:

— End—

文章標題:Ftrace的配置和使用
本文作者:hpyu
本文鏈接:https://www.cnblogs.com/hpyu/articles/14348151.html
歡迎轉載,請注明原文鏈接


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM