再看内核的ftrace架构
在上面这篇文章中,我们知道了如何在函数中tracepoint上注册函数,那么是谁搭建的这个平台呢?内核中ftrace平台
register_trace_##name
tracepoint_probe_register_prio
__DECLARE_TRACE
DEFINE_TRACE
把所有注册tracepoint的函数都抽象出来了做成了宏。
trace_##name 函数是真正的trace函数
trace_sched_switch后面是如何扩展开来的?
trace_sched_switch并不是系统的函数,包括在最后的符号表中也没有trace_sched_switch这个函数存在,其实trace_sched_switch是个宏里,
扩展trace_sched_switch
1) step1: include/trace/events/sched.h函数中, TRACE_EVENT(sched_switch...) 2)step2: TARCE_EVENT(line 483)-->DECLARE_TRACE(347)-->__DECLARE_TRACE(181),逐渐就把整个宏给扩展开来了, __DECLARE_TRACE中生成了许多的函数:包括 static inline void trace_sched_switch static inline int register_trace_prio_sched_switch static inline int unregister_trace_prio_sched_switch static inline void check_trace_callback_type_##name(void (*cb)(data_proot) static inline bool trace_sched_switch_enable(void); 所以呢,在函数kernel/sched/core.c函数中当有下面的#include <sched.h>函数时,其实在这个文件中新增加了这样三个函数,所以在sched/sched/core.c中函数中直接调用了trace_sched_switch函数是可以的,看下这个函数的内容是啥183 static inline void trace_##name(proto) \ 184 { \ 185 if (static_key_false(&__tracepoint_##name.key)) \ 186 __DO_TRACE(&__tracepoint_##name, \ 187 TP_PROTO(data_proto), \ 188 TP_ARGS(data_args), \ 189 TP_CONDITION(cond),,); \ 190 if (IS_ENABLED(CONFIG_LOCKDEP) && (cond)) { \ 191 rcu_read_lock_sched_notrace(); \ 192 rcu_dereference_sched(__tracepoint_##name.funcs);\ 193 rcu_read_unlock_sched_notrace(); \ 194 } \ 195 } \
static key机制就是在这里生效的,这个tracpoing的结构体是在在哪里注册的呢?
所以呢,在哪个地方肯定是生成了static key, __tracepoint_sched_switch了,到这里都是trace point机制,那么这个tracepoint结构体的定义以及初始化是在哪里完成的呢?,
然后在每个include/trace/events/sched.h文件的最末尾都会有:include<trace/define_trace.h>,这个文件中又会对TRACE_EVENT 进一步扩展,首先上来,TRACE_EVENT会被扩展成tracepoint结构体
3) DEFINE_TRACE->DEFINE_TRACE_FN,(include/linux/tracepint.h)