宏 TRACE_EVENT 的展开

Using the TRACE_EVENT() macro (Part 1)
https://lwn.net/Articles/379903/
Using the TRACE_EVENT() macro (Part 2)
https://lwn.net/Articles/381064/
Using the TRACE_EVENT() macro (Part 3)
https://lwn.net/Articles/383362/

include/trace/events/

一个宏TRACE_EVENT 可以展开成多种形式,定义不同函数、结构体、变量。
原理是,包含一次头文件,然后头文件内部的递归调用,每次递归时把原来的宏取消(#undef),再次定义成新的(#define)

printk.h的展开结果:(使用make kernel/printk/printk.i)

extern struct tracepoint __tracepoint_console;  

static inline void trace_console(const char *text, size_t len) 
{ 
if (static_key_false(&__tracepoint_console.key)) 
do { struct tracepoint_func *it_func_ptr; 
void *it_func; void *__data; 
if (!((((*({ (void)(0); ({ do { const void *__vpp_verify = (typeof((&cpu_number) + 0))((void *)0); 
(void)__vpp_verify; } while (0); (typeof(*(&cpu_number)) *)(&cpu_number); }); }))) == 0))) 
return; ; 
rcu_read_lock_sched_notrace(); 
it_func_ptr = ({ typeof(*((&__tracepoint_console)->funcs)) *________p1 = (typeof(*((&__tracepoint_console)->funcs)) *)({ typeof(((&__tracepoint_console)->funcs)) _________p1 = READ_ONCE(((&__tracepoint_console)->funcs)); 
do { } while(0); (_________p1); }); do { } while (0); ; ((typeof(*((&__tracepoint_console)->funcs)) *)(________p1)); });
 if (it_func_ptr) 
 {
	 do { it_func = (it_func_ptr)->func;
	 __data = (it_func_ptr)->data;
	 ((void(*)(void *__data, const char *text, size_t len))(it_func))(__data, text, len);   
	 } while ((++it_func_ptr)->func); 
 } 
 rcu_read_unlock_sched_notrace(); ; } 
 while (0); 
 if ((0 || 0) && ((((*({ (void)(0); ({ do { const void *__vpp_verify = (typeof((&cpu_number) + 0))
((void *)0); (void)__vpp_verify; } while (0); (typeof(*(&cpu_number)) *)(&cpu_number); }); }))) == 0))) 
{
 rcu_read_lock_sched_notrace();
 ({ typeof(*(__tracepoint_console.funcs)) *________p1 = 
 (typeof(*(__tracepoint_console.funcs)) *)({ typeof((__tracepoint_console.funcs)) _________p1 = READ_ONCE((__tracepoint_console.funcs)); 
 do { } while(0); (_________p1); }); do { } while (0); ; ((typeof(*(__tracepoint_console.funcs)) *)(________p1)); });
 rcu_read_unlock_sched_notrace(); 
 } 
} 
 
 static inline void trace_console_rcuidle(const char *text, size_t len) 
 {
 if (static_key_false(&__tracepoint_console.key)) 
 do {
	 struct tracepoint_func *it_func_ptr;
	 void *it_func; 
	 void *__data; 
	 if (!((((*({ (void)(0);  ({ do { const void *__vpp_verify = (typeof((&cpu_number) + 0))
	((void *)0); (void)__vpp_verify; } while (0); (typeof(*(&cpu_number)) *)(&cpu_number); }); }))) == 0))) 
	return; 
	rcu_irq_enter(); 
	rcu_read_lock_sched_notrace(); 
	it_func_ptr = ({ typeof(*((&__tracepoint_console)->funcs)) *________p1 = 
	(typeof(*((&__tracepoint_console)->funcs)) *)({ typeof(((&__tracepoint_console)->funcs)) _________p1 =
	 READ_ONCE(((&__tracepoint_console)->funcs)); do { } while(0); (_________p1); }); do { } while (0); ; 
	 ((typeof(*((&__tracepoint_console)->funcs)) *)(________p1)); }); 
	if (it_func_ptr) 
	{ 
	do { it_func = (it_func_ptr)->func; __data = 
	(it_func_ptr)->data; ((void(*)(void *__data, const char *text, size_t len))(it_func))(__data, text, len); } while ((++it_func_ptr)->func); 
	} 
	rcu_read_unlock_sched_notrace(); 
	rcu_irq_exit(); 
}while (0); 
} 


static inline int register_trace_console(void (*probe)(void *__data, const char *text, size_t len), void *data) 
{ 
return tracepoint_probe_register(&__tracepoint_console, (void *)probe, data); 
} 


static inline int register_trace_prio_console(void (*probe)(void *__data, const char *text, size_t len), void *data, int prio) 
{ 
return tracepoint_probe_register_prio(&__tracepoint_console, (void *)probe, data, prio); 
} 


static inline int unregister_trace_console(void (*probe)(void *__data, const char *text, size_t len), void *data) 
{ return tracepoint_probe_unregister(&__tracepoint_console, (void *)probe, data); } 

static inline void check_trace_callback_type_console(void (*cb)(void *__data, const char *text, size_t len)) 
{ } 

static inline bool trace_console_enabled(void) 
{ return static_key_false(&__tracepoint_console.key); }



static const char __tpstrtab_console[] __attribute__((section("__tracepoints_strings"))) = "console"; 
struct tracepoint __tracepoint_console __attribute__((section("__tracepoints"))) =   
{ __tpstrtab_console,  
{ .enabled = ATOMIC_INIT(0) }, 
((void *)0), 
((void *)0), 
((void *)0) 
}; 

static struct tracepoint * const __tracepoint_ptr_console __used __attribute__((section("__tracepoints_ptrs"))) = &__tracepoint_console;;
static const char str__printk__trace_system_name[] = "printk";


struct trace_event_raw_console {
	 struct trace_entry ent;  
	 u32 __data_loc_msg;   trace_event_data_offsets_console.msg
	 char __data[0];  
}; 
 
 static struct trace_event_class event_class_console;;  
 static struct trace_event_call __used __attribute__((__aligned__(4))) event_console;  
 

struct trace_event_data_offsets_console { 
	u32 msg;
};; ;

static notrace enum print_line_t 
trace_raw_output_console(struct trace_iterator *iter, int flags, struct trace_event *trace_event) 
{ 
	struct trace_seq *s = &iter->seq; 
	struct trace_seq __maybe_unused *p = &iter->tmp_seq; 
	struct trace_event_raw_console *field; 
	int ret; 
	field = (typeof(field))iter->ent;  
	ret = trace_raw_output_prep(iter, trace_event);  
	if (ret != TRACE_TYPE_HANDLED) 
	return ret; 
	trace_seq_printf(s, "%s" "\n", (char *)((void *)field + (field->__data_loc_msg & 0xffff)));  
	return trace_handle_return(s); 
} 

static struct trace_event_functions trace_event_type_funcs_console = { 
	.trace = trace_raw_output_console,  
};; 

static int notrace __attribute__ ((__section__(".init.text"))) notrace trace_event_define_fields_console(struct trace_event_call *event_call) 
{
	 struct trace_event_raw_console field; 
	 int ret; 

	 ret = trace_define_field(event_call, 
							 "__data_loc " "char" "[]", 
							 "msg",
							 ((size_t)&((typeof(field) *)0)->__data_loc_msg),  /* offset */
							 sizeof(field.__data_loc_msg),                     /* size */
							 (((char)(-1)) < (char)1),                         /* is_signed */
							 FILTER_OTHER);;                                   /* filter_type */
	 return ret; 
}; ;


static inline notrace int trace_event_get_offsets_console(struct trace_event_data_offsets_console *__data_offsets, const char *text, size_t len) 
{ 
	int __data_size = 0; 
	int __maybe_unused __item_length; 
	struct trace_event_raw_console __maybe_unused *entry; 

	__item_length = (len + 1) * sizeof(char); 

	__data_offsets->msg = __data_size + ((size_t)&((typeof(*entry) *)0)->__data);   
	__data_offsets->msg |= __item_length << 16;  
	__data_size += __item_length;;  
	return __data_size;  
}; ;

static notrace void trace_event_raw_event_console(void *__data, const char *text, size_t len) 
{ 
	struct trace_event_file *trace_file = __data; 
	struct trace_event_data_offsets_console __maybe_unused __data_offsets; 
	struct trace_event_buffer fbuffer; 
	struct trace_event_raw_console *entry; 
	int __data_size; 
	if (trace_trigger_soft_disabled(trace_file)) 
		return; 
	__data_size = trace_event_get_offsets_console(&__data_offsets, text, len); 

	entry = trace_event_buffer_reserve(&fbuffer, trace_file, sizeof(*entry) + __data_size);   
	if (!entry) 
		return; 
	entry->__data_loc_msg = __data_offsets.msg; 
	{ memcpy(((void *)entry + (entry->__data_loc_msg & 0xffff)), text, len);  
	((char *)((void *)entry + (entry->__data_loc_msg & 0xffff)))[len] = 0;; } 
	trace_event_buffer_commit(&fbuffer);  
}; 

static inline void ftrace_test_probe_console(void) 
{ 
	check_trace_callback_type_console(trace_event_raw_event_console); 
};

static notrace void perf_trace_console(void *__data, const char *text, size_t len);; 

static char print_fmt_console[] = "\"" "%s" "\", " "__get_str(msg)"; 

static struct trace_event_class __used __attribute__ ((__section__(".ref.data"))) event_class_console = { 
	.system = str__printk__trace_system_name,  
	.define_fields = trace_event_define_fields_console, 
	.fields = { &(event_class_console.fields), &(event_class_console.fields) },  
	.probe = trace_event_raw_event_console,   
	.reg = trace_event_reg,  
	.perf_probe = perf_trace_console, 
};; 

static struct trace_event_call __used event_console = {
	.class = &event_class_console,  
	{ 
	.tp = &__tracepoint_console, 
	}, 
	.event.funcs = &trace_event_type_funcs_console,   
	.print_fmt = print_fmt_console, 
	.flags = TRACE_EVENT_FL_TRACEPOINT, 
}; 

static struct trace_event_call __used __attribute__((section("_ftrace_events"))) *__event_console = &event_console;
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值