1770cb243SSteven Rostedt /* 2770cb243SSteven Rostedt * trace_export.c - export basic ftrace utilities to user space 3770cb243SSteven Rostedt * 4770cb243SSteven Rostedt * Copyright (C) 2009 Steven Rostedt <srostedt@redhat.com> 5770cb243SSteven Rostedt */ 6770cb243SSteven Rostedt #include <linux/stringify.h> 7770cb243SSteven Rostedt #include <linux/kallsyms.h> 8770cb243SSteven Rostedt #include <linux/seq_file.h> 9770cb243SSteven Rostedt #include <linux/debugfs.h> 10770cb243SSteven Rostedt #include <linux/uaccess.h> 11770cb243SSteven Rostedt #include <linux/ftrace.h> 12770cb243SSteven Rostedt #include <linux/module.h> 13770cb243SSteven Rostedt #include <linux/init.h> 14770cb243SSteven Rostedt #include <linux/fs.h> 15770cb243SSteven Rostedt 16770cb243SSteven Rostedt #include "trace_output.h" 17770cb243SSteven Rostedt 184e5292eaSSteven Rostedt #undef TRACE_SYSTEM 194e5292eaSSteven Rostedt #define TRACE_SYSTEM ftrace 20da4d0302SSteven Rostedt 21e59a0bffSJiri Olsa /* 22e59a0bffSJiri Olsa * The FTRACE_ENTRY_REG macro allows ftrace entry to define register 23e59a0bffSJiri Olsa * function and thus become accesible via perf. 24e59a0bffSJiri Olsa */ 25e59a0bffSJiri Olsa #undef FTRACE_ENTRY_REG 26e59a0bffSJiri Olsa #define FTRACE_ENTRY_REG(name, struct_name, id, tstruct, print, regfn) \ 27e59a0bffSJiri Olsa FTRACE_ENTRY(name, struct_name, id, PARAMS(tstruct), PARAMS(print)) 28e59a0bffSJiri Olsa 294e5292eaSSteven Rostedt /* not needed for this file */ 304e5292eaSSteven Rostedt #undef __field_struct 314e5292eaSSteven Rostedt #define __field_struct(type, item) 32da4d0302SSteven Rostedt 334e5292eaSSteven Rostedt #undef __field 3405ffa2d0SLi Zefan #define __field(type, item) type item; 3505ffa2d0SLi Zefan 3605ffa2d0SLi Zefan #undef __field_desc 3705ffa2d0SLi Zefan #define __field_desc(type, container, item) type item; 3805ffa2d0SLi Zefan 3905ffa2d0SLi Zefan #undef __array 4005ffa2d0SLi Zefan #define __array(type, item, size) type item[size]; 4105ffa2d0SLi Zefan 4205ffa2d0SLi Zefan #undef __array_desc 4305ffa2d0SLi Zefan #define __array_desc(type, container, item, size) type item[size]; 4405ffa2d0SLi Zefan 4505ffa2d0SLi Zefan #undef __dynamic_array 4605ffa2d0SLi Zefan #define __dynamic_array(type, item) type item[]; 4705ffa2d0SLi Zefan 4805ffa2d0SLi Zefan #undef F_STRUCT 4905ffa2d0SLi Zefan #define F_STRUCT(args...) args 5005ffa2d0SLi Zefan 5105ffa2d0SLi Zefan #undef F_printk 5205ffa2d0SLi Zefan #define F_printk(fmt, args...) fmt, args 5305ffa2d0SLi Zefan 5405ffa2d0SLi Zefan #undef FTRACE_ENTRY 5505ffa2d0SLi Zefan #define FTRACE_ENTRY(name, struct_name, id, tstruct, print) \ 5605ffa2d0SLi Zefan struct ____ftrace_##name { \ 5705ffa2d0SLi Zefan tstruct \ 5805ffa2d0SLi Zefan }; \ 595e9b3972SLi Zefan static void __always_unused ____ftrace_check_##name(void) \ 6005ffa2d0SLi Zefan { \ 6105ffa2d0SLi Zefan struct ____ftrace_##name *__entry = NULL; \ 6205ffa2d0SLi Zefan \ 635e9b3972SLi Zefan /* force compile-time check on F_printk() */ \ 6405ffa2d0SLi Zefan printk(print); \ 6505ffa2d0SLi Zefan } 6605ffa2d0SLi Zefan 6705ffa2d0SLi Zefan #undef FTRACE_ENTRY_DUP 6805ffa2d0SLi Zefan #define FTRACE_ENTRY_DUP(name, struct_name, id, tstruct, print) \ 6905ffa2d0SLi Zefan FTRACE_ENTRY(name, struct_name, id, PARAMS(tstruct), PARAMS(print)) 7005ffa2d0SLi Zefan 7105ffa2d0SLi Zefan #include "trace_entries.h" 7205ffa2d0SLi Zefan 734e5292eaSSteven Rostedt #undef __field 744e5292eaSSteven Rostedt #define __field(type, item) \ 754e5292eaSSteven Rostedt ret = trace_define_field(event_call, #type, #item, \ 764e5292eaSSteven Rostedt offsetof(typeof(field), item), \ 774e5292eaSSteven Rostedt sizeof(field.item), \ 784e5292eaSSteven Rostedt is_signed_type(type), FILTER_OTHER); \ 794e5292eaSSteven Rostedt if (ret) \ 804e5292eaSSteven Rostedt return ret; 814e5292eaSSteven Rostedt 824e5292eaSSteven Rostedt #undef __field_desc 834e5292eaSSteven Rostedt #define __field_desc(type, container, item) \ 844e5292eaSSteven Rostedt ret = trace_define_field(event_call, #type, #item, \ 854e5292eaSSteven Rostedt offsetof(typeof(field), \ 864e5292eaSSteven Rostedt container.item), \ 874e5292eaSSteven Rostedt sizeof(field.container.item), \ 884e5292eaSSteven Rostedt is_signed_type(type), FILTER_OTHER); \ 894e5292eaSSteven Rostedt if (ret) \ 904e5292eaSSteven Rostedt return ret; 914e5292eaSSteven Rostedt 924e5292eaSSteven Rostedt #undef __array 934e5292eaSSteven Rostedt #define __array(type, item, len) \ 9404295780SSteven Rostedt do { \ 954e5292eaSSteven Rostedt BUILD_BUG_ON(len > MAX_FILTER_STR_VAL); \ 9604295780SSteven Rostedt mutex_lock(&event_storage_mutex); \ 9704295780SSteven Rostedt snprintf(event_storage, sizeof(event_storage), \ 9804295780SSteven Rostedt "%s[%d]", #type, len); \ 9904295780SSteven Rostedt ret = trace_define_field(event_call, event_storage, #item, \ 1004e5292eaSSteven Rostedt offsetof(typeof(field), item), \ 101fb7ae981SLai Jiangshan sizeof(field.item), \ 102fb7ae981SLai Jiangshan is_signed_type(type), FILTER_OTHER); \ 10304295780SSteven Rostedt mutex_unlock(&event_storage_mutex); \ 1044e5292eaSSteven Rostedt if (ret) \ 10504295780SSteven Rostedt return ret; \ 10604295780SSteven Rostedt } while (0); 1074e5292eaSSteven Rostedt 1084e5292eaSSteven Rostedt #undef __array_desc 1094e5292eaSSteven Rostedt #define __array_desc(type, container, item, len) \ 1104e5292eaSSteven Rostedt BUILD_BUG_ON(len > MAX_FILTER_STR_VAL); \ 1114e5292eaSSteven Rostedt ret = trace_define_field(event_call, #type "[" #len "]", #item, \ 1124e5292eaSSteven Rostedt offsetof(typeof(field), \ 1134e5292eaSSteven Rostedt container.item), \ 114fb7ae981SLai Jiangshan sizeof(field.container.item), \ 115fb7ae981SLai Jiangshan is_signed_type(type), FILTER_OTHER); \ 1164e5292eaSSteven Rostedt if (ret) \ 1174e5292eaSSteven Rostedt return ret; 1184e5292eaSSteven Rostedt 1194e5292eaSSteven Rostedt #undef __dynamic_array 120809826a3SLai Jiangshan #define __dynamic_array(type, item) \ 121809826a3SLai Jiangshan ret = trace_define_field(event_call, #type, #item, \ 122809826a3SLai Jiangshan offsetof(typeof(field), item), \ 123809826a3SLai Jiangshan 0, is_signed_type(type), FILTER_OTHER);\ 124809826a3SLai Jiangshan if (ret) \ 125809826a3SLai Jiangshan return ret; 1264e5292eaSSteven Rostedt 1274e5292eaSSteven Rostedt #undef FTRACE_ENTRY 1284e5292eaSSteven Rostedt #define FTRACE_ENTRY(name, struct_name, id, tstruct, print) \ 1294e5292eaSSteven Rostedt int \ 1304e5292eaSSteven Rostedt ftrace_define_fields_##name(struct ftrace_event_call *event_call) \ 131e45f2e2bSTom Zanussi { \ 1324e5292eaSSteven Rostedt struct struct_name field; \ 133e45f2e2bSTom Zanussi int ret; \ 134e45f2e2bSTom Zanussi \ 1354e5292eaSSteven Rostedt tstruct; \ 136e45f2e2bSTom Zanussi \ 137e45f2e2bSTom Zanussi return ret; \ 138e45f2e2bSTom Zanussi } 139e45f2e2bSTom Zanussi 1404e5292eaSSteven Rostedt #include "trace_entries.h" 1414e5292eaSSteven Rostedt 142509e760cSLai Jiangshan #undef __entry 143509e760cSLai Jiangshan #define __entry REC 144509e760cSLai Jiangshan 1454e5292eaSSteven Rostedt #undef __field 1464e5292eaSSteven Rostedt #define __field(type, item) 1474e5292eaSSteven Rostedt 1484e5292eaSSteven Rostedt #undef __field_desc 1494e5292eaSSteven Rostedt #define __field_desc(type, container, item) 1504e5292eaSSteven Rostedt 1514e5292eaSSteven Rostedt #undef __array 1524e5292eaSSteven Rostedt #define __array(type, item, len) 1534e5292eaSSteven Rostedt 1544e5292eaSSteven Rostedt #undef __array_desc 1554e5292eaSSteven Rostedt #define __array_desc(type, container, item, len) 1564e5292eaSSteven Rostedt 1574e5292eaSSteven Rostedt #undef __dynamic_array 1584e5292eaSSteven Rostedt #define __dynamic_array(type, item) 1594e5292eaSSteven Rostedt 160509e760cSLai Jiangshan #undef F_printk 161509e760cSLai Jiangshan #define F_printk(fmt, args...) #fmt ", " __stringify(args) 162509e760cSLai Jiangshan 163e59a0bffSJiri Olsa #undef FTRACE_ENTRY_REG 164e59a0bffSJiri Olsa #define FTRACE_ENTRY_REG(call, struct_name, etype, tstruct, print, regfn)\ 165770cb243SSteven Rostedt \ 1662e33af02SSteven Rostedt struct ftrace_event_class event_class_ftrace_##call = { \ 1672e33af02SSteven Rostedt .system = __stringify(TRACE_SYSTEM), \ 1682e33af02SSteven Rostedt .define_fields = ftrace_define_fields_##call, \ 169ffb9f995SLi Zefan .fields = LIST_HEAD_INIT(event_class_ftrace_##call.fields),\ 170e59a0bffSJiri Olsa .reg = regfn, \ 1712e33af02SSteven Rostedt }; \ 1722e33af02SSteven Rostedt \ 173e4a9ea5eSSteven Rostedt struct ftrace_event_call __used event_##call = { \ 174770cb243SSteven Rostedt .name = #call, \ 17532c0edaeSSteven Rostedt .event.type = etype, \ 1762e33af02SSteven Rostedt .class = &event_class_ftrace_##call, \ 177509e760cSLai Jiangshan .print_fmt = print, \ 178e1112b4dSTom Zanussi }; \ 179e4a9ea5eSSteven Rostedt struct ftrace_event_call __used \ 180e4a9ea5eSSteven Rostedt __attribute__((section("_ftrace_events"))) *__event_##call = &event_##call; 181e1112b4dSTom Zanussi 182e59a0bffSJiri Olsa #undef FTRACE_ENTRY 183e59a0bffSJiri Olsa #define FTRACE_ENTRY(call, struct_name, etype, tstruct, print) \ 184e59a0bffSJiri Olsa FTRACE_ENTRY_REG(call, struct_name, etype, \ 185e59a0bffSJiri Olsa PARAMS(tstruct), PARAMS(print), NULL) 186e59a0bffSJiri Olsa 1874e5292eaSSteven Rostedt #include "trace_entries.h" 188