例子
这篇文章https://www.ibm.com/developerworks/cn/linux/1609_houp_ftrace/index.html 对tracepoint和event trace都说的很清晰了,这里就不做赘述了,主要来看一下kernel里的一个例子。
先看一下抓的log和命令
命令:分别用3个bat完成
-
enable trace
set tracing_dir=/sys/kernel/debug/tracing adb wait-for-device rem adb shell "echo ftrace > %tracing_dir%/current_tracer" adb shell "echo 1 > %tracing_dir%/tracing_on" pause
-
cat trace
set tracing_dir=/sys/kernel/debug adb wait-for-device adb pull %tracing_dir%/tracing/trace %CD% pause
-
disable ftrace
set tracing_dir=/sys/kernel/debug/tracing adb wait-for-device adb shell "echo 0 > %tracing_dir%/tracing_on" pause
log 部分
# tracer: nop
#
# entries-in-buffer/entries-written: 44493/44493 #P:8
# enabled events: ipi:ipi_exit ipi:ipi_entry ipi:ipi_raise irq:softirq_raise irq:softirq_exit irq:softirq_entry workqueue:workqueue_execute_end workqueue:workqueue_execute_start sched:sched_migrate_task sched:sched_switch sched:sched_wakeup_new sched:sched_wakeup mtk_events:sspm_ipi mtk_events:sched_update mtk_events:hps_update mtk_events:ppm_limit_callback_update mtk_events:ppm_overutil_update mtk_events:ppm_hica mtk_events:ppm_update mtk_events:gpu_freq mtk_events:irq_exit mtk_events:irq_entry mtk_events:cpu_hotplug mtk_events:tracing_on power:cpu_frequency block:block_bio_frontmerge block:block_bio_backmerge block:block_rq_issue block:block_rq_insert block:block_rq_complete block:block_rq_requeue
# kernel time now: 951651.297449
# UTC time: 2018-09-25 06:35:54.112033
# android time: 2018-09-25 06:35:54.112033
#
# _-----=> irqs-off
# / _----=> need-resched
# | / _---=> hardirq/softirq
# || / _--=> preempt-depth
# ||| / delay
# TASK-PID CPU# |||| TIMESTAMP FUNCTION
# | | | |||| | |
sh-9697 [001] ...1 951603.118943: tracing_on: ftrace is enabled caller=__vfs_write
sh-9697 [001] d..4 951603.119468: sched_update: (0)(0x7cd)
sh-9697 [001] d..4 951603.119481: ipi_raise: target_mask=00000000,00000004 (Rescheduling interrupts)
sh-9697 [001] d..4 951603.119491: sched_wakeup: comm=adbd pid=393 prio=120 success=1 target_cpu=002 state=R overutil=0
<idle>-0 [002] dn.2 951603.119677: ipi_entry: (Rescheduling interrupts)
<idle>-0 [002] dn.2 951603.119687: ipi_exit: (Rescheduling interrupts)
<idle>-0 [002] dn.3 951603.119741: sched_update: (0)(0x7dd)
<idle>-0 [002] d..3 951603.119758: sched_switch: prev_comm=swapper/2 prev_pid=0 prev_prio=120 prev_state=R ==> next_comm=adbd next_pid=393 next_prio=120 prev->cgrp=1 next->cgrp=1
adbd-393 [002] d..4 951603.120392: sched_update: (0)(0x7ed)
adbd-393 [002] d..4 951603.120402: ipi_raise: target_mask=00000000,00000001 (Rescheduling interrupts)
adbd-393 [002] d..4 951603.120407: sched_wakeup: comm=->transport pid=24433 prio=120 success=1 target_cpu=000 state=R overutil=0
<idle>-0 [000] dn.2 951603.120577: ipi_entry: (Rescheduling interrupts)
<idle>-0 [000] dn.2 951603.120585: ipi_exit: (Rescheduling interrupts)
<idle>-0 [000] dn.3 951603.120630: sched_update: (0)(0x7fd)
<idle>-0 [000] d..3 951603.120647: sched_switch: prev_comm=swapper/0 prev_pid=0 prev_prio=120 prev_state=R ==> next_comm=->transport next_pid=24433 next_prio=120 prev->cgrp=1 next->cgrp=1
->transport-24433 [000] d.h1 951603.120806: irq_entry: irq=93 name=musb-hdrc
adbd-393 [002] d.h1 951603.120816: irq_entry: irq=2 name=arch_timer
sh-9697 [001] d.h1 951603.120816: irq_entry: irq=2 name=arch_timer
<idle>-0 [003] d.h2 951603.120824: irq_entry: irq=2 name=arch_timer
<idle>-0 [003] d.h2 951603.120837: softirq_raise: vec=1 [action=TIMER]
adbd-393 [002] d.h1 951603.120838: softirq_raise: vec=1 [action=TIMER]
adbd-393 [002] d.h1 951603.120844: softirq_raise: vec=9 [action=RCU]
sh-9697 [001] d.h1 951603.120847: softirq_raise: vec=1 [action=TIMER]
->transport-24433 [000] d.h1 951603.120848: irq_exit: irq=93
sh-9697 [001] d.h1 951603.120852: softirq_raise: vec=9 [action=RCU]
->transport-24433 [000] d.h1 951603.120857: irq_entry: irq=2 name=arch_timer
adbd-393 [002] d.h3 951603.120865: sched_migrate_task: comm=logd.klogd pid=341 prio=118 orig_cpu=0 dest_cpu=3 state=W
<idle>-0 [003] d.h2 951603.120867: irq_exit: irq=2
->transport-24433 [000] d.h1 951603.120868: softirq_raise: vec=1 [action=TIMER]
->transport-24433 [000] d.h1 951603.120872: softirq_raise: vec=9 [action=RCU]
<idle>-0 [003] ..s2 951603.120874: softirq_entry: vec=1 [action=TIMER]
adbd-393 [002] d.h4 951603.120897: sched_update: (0)(0x80d)
->transport-24433 [000] d.h1 951603.120898: softirq_raise: vec=7 [action=SCHED]
adbd-393 [002] d.h4 951603.120904: ipi_raise: target_mask=00000000,00000008 (Rescheduling interrupts)
adbd-393 [002] d.h4 951603.120909: sched_wakeup: comm=logd.klogd pid=341 prio=118 success=1 target_cpu=003 state=R overutil=0
->transport-24433 [000] d.h1 951603.120913: irq_exit: irq=2
->transport-24433 [000] ..s1 951603.120918: softirq_entry: vec=1 [action=TIMER]
adbd-393 [002] d.h1 951603.120930: softirq_raise: vec=7 [action=SCHED]
<idle>-0 [003] dns4 951603.120940: sched_update: (0)(0x81d)
adbd-393 [002] d.h1 951603.120943: irq_exit: irq=2
sh-9697 [001] d.h1 951603.120944: irq_exit: irq=2
以下面的一句log为例来说明kernel是怎么填event trace的
<idle>-0 [002] d..3 951603.119758: sched_switch: prev_comm=swapper/2 prev_pid=0 prev_prio=120 prev_state=R ==> next_comm=adbd next_pid=393 next_prio=120 prev->cgrp=1 next->cgrp=1
- sched_switch是函数名字,其实省略了trace_ , 在代码里真正调用的是trace_sched_switch, 如下
static void __sched notrace __schedule(bool preempt)
{
```
prev = rq->curr;
next = pick_next_task(rq, prev);
if (likely(prev != next)) {
rq->nr_switches++;
rq->curr = next;
++*switch_count;
trace_sched_switch(preempt, prev, next); //event trace
rq = context_switch(rq, prev, next); /* unlocks the rq */
cpu = cpu_of(rq);
} else {
lockdep_unpin_lock(&rq->lock);
raw_spin_unlock_irq(&rq->lock);
}
- 定义trace_sched_switch的地方
include\trace\events\sched.h
/*
* Tracepoint for task switches, performed by the scheduler:
*/
TRACE_EVENT(sched_switch,
TP_PROTO(struct task_struct *prev,
struct task_struct *next),
TP_ARGS(prev, next),
TP_STRUCT__entry(
__array( char, prev_comm, TASK_COMM_LEN )
__field( pid_t, prev_pid )
__field( int, prev_prio )
__field( long, prev_state )
__array( char, next_comm, TASK_COMM_LEN )
__field( pid_t, next_pid )
__field( int, next_prio )
),
TP_fast_assign(
memcpy(__entry->next_comm, next->comm, TASK_COMM_LEN);
__entry->prev_pid = prev->pid;
__entry->prev_prio = prev->prio;
__entry->prev_state = __trace_sched_switch_state(prev);
memcpy(__entry->prev_comm, prev->comm, TASK_COMM_LEN);
__entry->next_pid = next->pid;
__entry->next_prio = next->prio;
),
TP_printk("prev_comm=%s prev_pid=%d prev_prio=%d prev_state=%s%s ==> next_comm=%s next_pid=%d next_prio=%d",
__entry->prev_comm, __entry->prev_pid, __entry->prev_prio,
__entry->prev_state & (TASK_STATE_MAX-1) ?
__print_flags(__entry->prev_state & (TASK_STATE_MAX-1), "|",
{ 1, "S"} , { 2, "D" }, { 4, "T" }, { 8, "t" },
{ 16, "Z" }, { 32, "X" }, { 64, "x" },
{ 128, "K" }, { 256, "W" }, { 512, "P" }) : "R",
__entry->prev_state & TASK_STATE_MAX ? "+" : "",
__entry->next_comm, __entry->next_pid, __entry->next_prio)
);
TRACE_EVENT是一个宏定义,在linux/tracepoint.h 和trace/define_trace.h有不同的定义,相当于include两支不同的头文件,实现两个不同的功能。 这样之后,代码就可以使用trace_sched_switch了
3.在/sys/kernel/debug/tracing/events可以看当前的event trace,再往里面可以看他们具体的status,如是否enable
k63v1us_64_bsp:/sys/kernel/debug/tracing/events/sched/sched_switch # ls
enable filter format id trigger
#cat enable
#1
参考文章
good
https://www.ibm.com/developerworks/cn/linux/1609_houp_ftrace/index.html
https://www.ibm.com/developerworks/cn/linux/l-cn-ftrace/index.html