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文件