register_trace_##name宏中node
tracepoint_probe_register在这个函数中在同一个cp上能够挂多个处理函数,函数
查看函数:trace_block_rq_issue中定义了这个tracepoint以及tracepoint的钩子函数code
tracepoint中给你输入了trace_block_rq_issue(q, rq);其中q是request_queue,rq是struct request,这两个东西是tracepoint提供给你的,全部的函数都可以获得,这个函数的执行的流程是啥样子的啊,钩子函数中必定是要有void函数的,各路ftrace啥的都注册了本身的函数,包括perf也是在函数中注册了本身的函数,看下ftrace注册的什么函数呢,ftrace中确定是注册了本身的特定的函数orm
kernel/trace/trace_events.c中有许多的钩子函数blog
ftrace_enable_fopsget
ftrace_event_format_fopsit
__ftrace_event_enable_disable钩子
使用牛逼的systemtap能够垂手可得地获得函数中的钩子是啥:call->class->reg(call, TRACE_REG_UNREGISTER, file);event
获得钩子的地址是:trace_event_regast
而后钩子函数是啥子咧,发现是是函数 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文件