register_trace_##name宏中
tracepoint_probe_register在这个函数中在同一个cp上可以挂多个处理函数,
查看函数:trace_block_rq_issue中定义了这个tracepoint以及tracepoint的钩子函数
tracepoint中给你输入了trace_block_rq_issue(q, rq);其中q是request_queue,rq是struct request,这两个东西是tracepoint提供给你的,所有的函数都能够得到,这个函数的执行的流程是啥样子的啊,钩子函数中一定是要有void函数的,各路ftrace啥的都注册了自己的函数,包括perf也是在函数中注册了自己的函数,看下ftrace注册的什么函数呢,ftrace中肯定是注册了自己的特定的函数
kernel/trace/trace_events.c中有许多的钩子函数
ftrace_enable_fops
ftrace_event_format_fops
__ftrace_event_enable_disable
使用牛逼的systemtap可以轻而易举地得到函数中的钩子是啥:call->class->reg(call, TRACE_REG_UNREGISTER, file);
得到钩子的地址是:trace_event_reg
然后钩子函数是啥子咧,发现是是函数 trace_event_raw_event_block_rq_issue
这个函数是咋生成的呢?
都是在头文件中生成的
./include/trace/events/f2fs.h
DECLARE_EVENT_CLASS在这个宏中会扩展函数trace_event_raw_event_block_rq_issue函数
以f2fs的declare_event_class函数中
122 DECLARE_EVENT_CLASS(f2fs__inode,
123
124 TP_PROTO(struct inode *inode),
125
126 TP_ARGS(inode),
127
128 TP_STRUCT__entry(
129 __field(dev_t, dev)
130 __field(ino_t, ino)
131 __field(ino_t, pino)
132 __field(umode_t, mode)
133 __field(loff_t, size)
134 __field(unsigned int, nlink)
135 __field(blkcnt_t, blocks)
136 __field(__u8, advise)
137 ),
138
139 TP_fast_assign(
140 __entry->dev = inode->i_sb->s_dev;
141 __entry->ino = inode->i_ino;
142 __entry->pino = F2FS_I(inode)->i_pino;
143 __entry->mode = inode->i_mode;
144 __entry->nlink = inode->i_nlink;
145 __entry->size = inode->i_size;
146 __entry->blocks = inode->i_blocks;
147 __entry->advise = F2FS_I(inode)->i_advise;
148 ),
149
150 TP_printk("dev = (%d,%d), ino = %lu, pino = %lu, i_mode = 0x%hx, "
151 "i_size = %lld, i_nlink = %u, i_blocks = %llu, i_advise = 0x%x",
152 show_dev_ino(__entry),
153 (unsigned long)__entry->pino,
154 __entry->mode,
155 __entry->size,
156 (unsigned int)__entry->nlink,
157 (unsigned long long)__entry->blocks,
158 (unsigned char)__entry->advise)
159 );
函数中:
./include/trace/trace_events.h
664 static notrace void
665 trace_event_raw_event_##call(void *__data, proto)
666 {
667 struct trace_event_file *trace_file = __data;
668 struct trace_event_data_offsets_##call __maybe_unused __data_offsets;
669 struct trace_event_buffer fbuffer;
670 struct trace_event_raw_##call *entry;
671 int __data_size;
672
673 if (trace_trigger_soft_disabled(trace_file))
674 return;
675
676 __data_size = trace_event_get_offsets_##call(&__data_offsets, args);
677
678 entry = trace_event_buffer_reserve(&fbuffer, trace_file,
679 sizeof(*entry) + __data_size);
680
681 if (!entry)
682 return;
683
684 tstruct
685
686 { assign; }
687
688 trace_event_buffer_commit(&fbuffer);
689 }
按说,ftrace的printk部分
perf注册的函数是perf_trace_##call函数,include/trace/perf.h文件