如何在tracepoint上注册函数

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

原文地址:https://www.cnblogs.com/honpey/p/9012016.html