aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSteven Rostedt <srostedt@redhat.com>2009-09-12 19:17:15 -0400
committerSteven Rostedt <rostedt@goodmis.org>2009-09-12 23:08:06 -0400
commit0a1c49db8d91c538f104f8d70e560c6fdd589bd4 (patch)
tree41cf96b9c7bd351702526c6313cef9944c741954
parent16bb8eb1b73bf940d30ff88cae622bfcd3790f61 (diff)
tracing: use macros to create internal ftrace entry ring buffer structures
The entries used by ftrace internal code (plugins) currently have their formats manually exported to userspace. That is, the format files in debugfs/tracing/events/ftrace/*/format are currently created by hand. This is a maintenance nightmare, and can easily become out of sync with what is actually shown. This patch uses the methodology of the TRACE_EVENT macros to build the structures so that their formats can be automated and this will keep the structures in sync with what users can see. This patch only changes the way the structures are created. Further patches will build off of this to automate the format files. Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
-rw-r--r--kernel/trace/trace.h160
-rw-r--r--kernel/trace/trace_entries.h342
2 files changed, 369 insertions, 133 deletions
diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h
index 4ad4e1ddcb9b..d308195d40aa 100644
--- a/kernel/trace/trace.h
+++ b/kernel/trace/trace.h
@@ -42,150 +42,45 @@ enum trace_type {
42 __TRACE_LAST_TYPE, 42 __TRACE_LAST_TYPE,
43}; 43};
44 44
45/* 45enum kmemtrace_type_id {
46 * Function trace entry - function address and parent function addres: 46 KMEMTRACE_TYPE_KMALLOC = 0, /* kmalloc() or kfree(). */
47 */ 47 KMEMTRACE_TYPE_CACHE, /* kmem_cache_*(). */
48struct ftrace_entry { 48 KMEMTRACE_TYPE_PAGES, /* __get_free_pages() and friends. */
49 struct trace_entry ent;
50 unsigned long ip;
51 unsigned long parent_ip;
52};
53
54/* Function call entry */
55struct ftrace_graph_ent_entry {
56 struct trace_entry ent;
57 struct ftrace_graph_ent graph_ent;
58}; 49};
59 50
60/* Function return entry */
61struct ftrace_graph_ret_entry {
62 struct trace_entry ent;
63 struct ftrace_graph_ret ret;
64};
65extern struct tracer boot_tracer; 51extern struct tracer boot_tracer;
66 52
67/* 53#undef __field
68 * Context switch trace entry - which task (and prio) we switched from/to: 54#define __field(type, item) type item;
69 */
70struct ctx_switch_entry {
71 struct trace_entry ent;
72 unsigned int prev_pid;
73 unsigned char prev_prio;
74 unsigned char prev_state;
75 unsigned int next_pid;
76 unsigned char next_prio;
77 unsigned char next_state;
78 unsigned int next_cpu;
79};
80
81/*
82 * Special (free-form) trace entry:
83 */
84struct special_entry {
85 struct trace_entry ent;
86 unsigned long arg1;
87 unsigned long arg2;
88 unsigned long arg3;
89};
90
91/*
92 * Stack-trace entry:
93 */
94 55
95#define FTRACE_STACK_ENTRIES 8 56#undef __array
57#define __array(type, item, size) type item[size];
96 58
97struct stack_entry { 59#undef __dynamic_array
98 struct trace_entry ent; 60#define __dynamic_array(type, item) type item[];
99 unsigned long caller[FTRACE_STACK_ENTRIES];
100};
101 61
102struct userstack_entry { 62#undef F_STRUCT
103 struct trace_entry ent; 63#define F_STRUCT(args...) args
104 unsigned int tgid;
105 unsigned long caller[FTRACE_STACK_ENTRIES];
106};
107
108/*
109 * trace_printk entry:
110 */
111struct bprint_entry {
112 struct trace_entry ent;
113 unsigned long ip;
114 const char *fmt;
115 u32 buf[];
116};
117
118struct print_entry {
119 struct trace_entry ent;
120 unsigned long ip;
121 char buf[];
122};
123 64
124struct trace_mmiotrace_rw { 65#undef FTRACE_ENTRY
125 struct trace_entry ent; 66#define FTRACE_ENTRY(name, struct_name, id, tstruct, print) \
126 struct mmiotrace_rw rw; 67 struct struct_name { \
127}; 68 struct trace_entry ent; \
128 69 tstruct \
129struct trace_mmiotrace_map { 70 }
130 struct trace_entry ent;
131 struct mmiotrace_map map;
132};
133
134struct trace_boot_call {
135 struct trace_entry ent;
136 struct boot_trace_call boot_call;
137};
138
139struct trace_boot_ret {
140 struct trace_entry ent;
141 struct boot_trace_ret boot_ret;
142};
143
144#define TRACE_FUNC_SIZE 30
145#define TRACE_FILE_SIZE 20
146struct trace_branch {
147 struct trace_entry ent;
148 unsigned line;
149 char func[TRACE_FUNC_SIZE+1];
150 char file[TRACE_FILE_SIZE+1];
151 char correct;
152};
153
154struct hw_branch_entry {
155 struct trace_entry ent;
156 u64 from;
157 u64 to;
158};
159
160struct trace_power {
161 struct trace_entry ent;
162 struct power_trace state_data;
163};
164 71
165enum kmemtrace_type_id { 72#undef TP_ARGS
166 KMEMTRACE_TYPE_KMALLOC = 0, /* kmalloc() or kfree(). */ 73#define TP_ARGS(args...) args
167 KMEMTRACE_TYPE_CACHE, /* kmem_cache_*(). */
168 KMEMTRACE_TYPE_PAGES, /* __get_free_pages() and friends. */
169};
170 74
171struct kmemtrace_alloc_entry { 75#undef FTRACE_ENTRY_DUP
172 struct trace_entry ent; 76#define FTRACE_ENTRY_DUP(name, name_struct, id, tstruct, printk)
173 enum kmemtrace_type_id type_id;
174 unsigned long call_site;
175 const void *ptr;
176 size_t bytes_req;
177 size_t bytes_alloc;
178 gfp_t gfp_flags;
179 int node;
180};
181 77
182struct kmemtrace_free_entry { 78#include "trace_entries.h"
183 struct trace_entry ent;
184 enum kmemtrace_type_id type_id;
185 unsigned long call_site;
186 const void *ptr;
187};
188 79
80/*
81 * syscalls are special, and need special handling, this is why
82 * they are not included in trace_entries.h
83 */
189struct syscall_trace_enter { 84struct syscall_trace_enter {
190 struct trace_entry ent; 85 struct trace_entry ent;
191 int nr; 86 int nr;
@@ -198,7 +93,6 @@ struct syscall_trace_exit {
198 unsigned long ret; 93 unsigned long ret;
199}; 94};
200 95
201
202/* 96/*
203 * trace_flag_type is an enumeration that holds different 97 * trace_flag_type is an enumeration that holds different
204 * states when a trace occurs. These are: 98 * states when a trace occurs. These are:
diff --git a/kernel/trace/trace_entries.h b/kernel/trace/trace_entries.h
new file mode 100644
index 000000000000..82c51fdca035
--- /dev/null
+++ b/kernel/trace/trace_entries.h
@@ -0,0 +1,342 @@
1/*
2 * This file defines the trace event structures that go into the ring
3 * buffer directly. They are created via macros so that changes for them
4 * appear in the format file. Using macros will automate this process.
5 *
6 * The macro used to create a ftrace data structure is:
7 *
8 * FTRACE_ENTRY( name, struct_name, id, structure, print )
9 *
10 * @name: the name used the event name, as well as the name of
11 * the directory that holds the format file.
12 *
13 * @struct_name: the name of the structure that is created.
14 *
15 * @id: The event identifier that is used to detect what event
16 * this is from the ring buffer.
17 *
18 * @structure: the structure layout
19 *
20 * - __field( type, item )
21 * This is equivalent to declaring
22 * type item;
23 * in the structure.
24 * - __array( type, item, size )
25 * This is equivalent to declaring
26 * type item[size];
27 * in the structure.
28 *
29 * @print: the print format shown to users in the format file.
30 */
31
32/*
33 * Function trace entry - function address and parent function addres:
34 */
35FTRACE_ENTRY(function, ftrace_entry,
36
37 TRACE_FN,
38
39 F_STRUCT(
40 __field( unsigned long, ip )
41 __field( unsigned long, parent_ip )
42 ),
43
44 F_printk(" %lx <-- %lx", __entry->ip, __entry->parent_ip)
45);
46
47/* Function call entry */
48FTRACE_ENTRY(funcgraph_entry, ftrace_graph_ent_entry,
49
50 TRACE_GRAPH_ENT,
51
52 F_STRUCT(
53 __field( struct ftrace_graph_ent, graph_ent )
54 ),
55
56 F_printk("--> %lx (%d)", __entry->graph_ent.func, __entry->depth)
57);
58
59/* Function return entry */
60FTRACE_ENTRY(funcgraph_exit, ftrace_graph_ret_entry,
61
62 TRACE_GRAPH_RET,
63
64 F_STRUCT(
65 __field( struct ftrace_graph_ret, ret )
66 ),
67
68 F_printk("<-- %lx (%d) (start: %llx end: %llx) over: %d",
69 __entry->func, __entry->depth,
70 __entry->calltime, __entry->rettim,
71 __entrty->depth)
72);
73
74/*
75 * Context switch trace entry - which task (and prio) we switched from/to:
76 *
77 * This is used for both wakeup and context switches. We only want
78 * to create one structure, but we need two outputs for it.
79 */
80#define FTRACE_CTX_FIELDS \
81 __field( unsigned int, prev_pid ) \
82 __field( unsigned char, prev_prio ) \
83 __field( unsigned char, prev_state ) \
84 __field( unsigned int, next_pid ) \
85 __field( unsigned char, next_prio ) \
86 __field( unsigned char, next_state ) \
87 __field( unsigned int, next_cpu )
88
89#if 0
90FTRACE_ENTRY_STRUCT_ONLY(ctx_switch_entry,
91
92 F_STRUCT(
93 FTRACE_CTX_FIELDS
94 )
95);
96#endif
97
98FTRACE_ENTRY(context_switch, ctx_switch_entry,
99
100 TRACE_CTX,
101
102 F_STRUCT(
103 FTRACE_CTX_FIELDS
104 ),
105
106 F_printk(b"%u:%u:%u ==> %u:%u:%u [%03u]",
107 __entry->prev_pid, __entry->prev_prio, __entry->prev_state,
108 __entry->next_pid, __entry->next_prio, __entry->next_state,
109 __entry->next_cpu
110 )
111);
112
113/*
114 * FTRACE_ENTRY_DUP only creates the format file, it will not
115 * create another structure.
116 */
117FTRACE_ENTRY_DUP(wakeup, ctx_switch_entry,
118
119 TRACE_WAKE,
120
121 F_STRUCT(
122 FTRACE_CTX_FIELDS
123 ),
124
125 F_printk("%u:%u:%u ==+ %u:%u:%u [%03u]",
126 __entry->prev_pid, __entry->prev_prio, __entry->prev_state,
127 __entry->next_pid, __entry->next_prio, __entry->next_state,
128 __entry->next_cpu
129 )
130);
131
132/*
133 * Special (free-form) trace entry:
134 */
135FTRACE_ENTRY(special, special_entry,
136
137 TRACE_SPECIAL,
138
139 F_STRUCT(
140 __field( unsigned long, arg1 )
141 __field( unsigned long, arg2 )
142 __field( unsigned long, arg3 )
143 ),
144
145 F_printk("(%08lx) (%08lx) (%08lx)",
146 __entry->arg1, __entry->arg2, __entry->arg3)
147);
148
149/*
150 * Stack-trace entry:
151 */
152
153#define FTRACE_STACK_ENTRIES 8
154
155FTRACE_ENTRY(kernel_stack, stack_entry,
156
157 TRACE_STACK,
158
159 F_STRUCT(
160 __array( unsigned long, caller, FTRACE_STACK_ENTRIES )
161 ),
162
163 F_printk("\t=> (%08lx)\n\t=> (%08lx)\n\t=> (%08lx)\n\t=> (%08lx)\n"
164 "\t=> (%08lx)\n\t=> (%08lx)\n\t=> (%08lx)\n\t=> (%08lx)\n",
165 __entry->caller[0], __entry->caller[1], __entry->caller[2],
166 __entry->caller[3], __entry->caller[4], __entry->caller[5],
167 __entry->caller[6], __entry->caller[7])
168);
169
170FTRACE_ENTRY(user_stack, userstack_entry,
171
172 TRACE_USER_STACK,
173
174 F_STRUCT(
175 __field( unsigned int, tgid )
176 __array( unsigned long, caller, FTRACE_STACK_ENTRIES )
177 ),
178
179 F_printk("\t=> (%08lx)\n\t=> (%08lx)\n\t=> (%08lx)\n\t=> (%08lx)\n"
180 "\t=> (%08lx)\n\t=> (%08lx)\n\t=> (%08lx)\n\t=> (%08lx)\n",
181 __entry->caller[0], __entry->caller[1], __entry->caller[2],
182 __entry->caller[3], __entry->caller[4], __entry->caller[5],
183 __entry->caller[6], __entry->caller[7])
184);
185
186/*
187 * trace_printk entry:
188 */
189FTRACE_ENTRY(bprint, bprint_entry,
190
191 TRACE_BPRINT,
192
193 F_STRUCT(
194 __field( unsigned long, ip )
195 __field( const char *, fmt )
196 __dynamic_array( u32, buf )
197 ),
198
199 F_printk("%08lx fmt:%p",
200 __entry->ip, __entry->fmt)
201);
202
203FTRACE_ENTRY(print, print_entry,
204
205 TRACE_PRINT,
206
207 F_STRUCT(
208 __field( unsigned long, ip )
209 __dynamic_array( char, buf )
210 ),
211
212 F_printk("%08lx %s",
213 __entry->ip, __entry->buf)
214);
215
216FTRACE_ENTRY(mmiotrace_rw, trace_mmiotrace_rw,
217
218 TRACE_MMIO_RW,
219
220 F_STRUCT(
221 __field( struct mmiotrace_rw, rw )
222 ),
223
224 F_printk("%lx %lx %lx %d %lx %lx",
225 __entry->phs, __entry->value, __entry->pc,
226 __entry->map_id, __entry->opcode, __entry->width)
227);
228
229FTRACE_ENTRY(mmiotrace_map, trace_mmiotrace_map,
230
231 TRACE_MMIO_MAP,
232
233 F_STRUCT(
234 __field( struct mmiotrace_map, map )
235 ),
236
237 F_printk("%lx %lx %lx %d %lx",
238 __entry->phs, __entry->virt, __entry->len,
239 __entry->map_id, __entry->opcode)
240);
241
242FTRACE_ENTRY(boot_call, trace_boot_call,
243
244 TRACE_BOOT_CALL,
245
246 F_STRUCT(
247 __field( struct boot_trace_call, boot_call )
248 ),
249
250 F_printk("%d %s", __entry->caller, __entry->func)
251);
252
253FTRACE_ENTRY(boot_ret, trace_boot_ret,
254
255 TRACE_BOOT_RET,
256
257 F_STRUCT(
258 __field( struct boot_trace_ret, boot_ret )
259 ),
260
261 F_printk("%s %d %lx",
262 __entry->func, __entry->result, __entry->duration)
263);
264
265#define TRACE_FUNC_SIZE 30
266#define TRACE_FILE_SIZE 20
267
268FTRACE_ENTRY(branch, trace_branch,
269
270 TRACE_BRANCH,
271
272 F_STRUCT(
273 __field( unsigned int, line )
274 __array( char, func, TRACE_FUNC_SIZE+1 )
275 __array( char, file, TRACE_FILE_SIZE+1 )
276 __field( char, correct )
277 ),
278
279 F_printk("%u:%s:%s (%u)",
280 __entry->line,
281 __entry->func, __entry->file, __entry->correct)
282);
283
284FTRACE_ENTRY(hw_branch, hw_branch_entry,
285
286 TRACE_HW_BRANCHES,
287
288 F_STRUCT(
289 __field( u64, from )
290 __field( u64, to )
291 ),
292
293 F_printk("from: %llx to: %llx", __entry->from, __entry->to)
294);
295
296FTRACE_ENTRY(power, trace_power,
297
298 TRACE_POWER,
299
300 F_STRUCT(
301 __field( struct power_trace, state_data )
302 ),
303
304 F_printk("%llx->%llx type:%u state:%u",
305 __entry->stamp, __entry->end,
306 __entry->type, __entry->state)
307);
308
309FTRACE_ENTRY(kmem_alloc, kmemtrace_alloc_entry,
310
311 TRACE_KMEM_ALLOC,
312
313 F_STRUCT(
314 __field( enum kmemtrace_type_id, type_id )
315 __field( unsigned long, call_site )
316 __field( const void *, ptr )
317 __field( size_t, bytes_req )
318 __field( size_t, bytes_alloc )
319 __field( gfp_t, gfp_flags )
320 __field( int, node )
321 ),
322
323 F_printk("type:%u call_site:%lx ptr:%p req:%lu alloc:%lu"
324 " flags:%x node:%d",
325 __entry->type_id, __entry->call_site, __entry->ptr,
326 __entry->bytes_req, __entry->bytes_alloc,
327 __entry->gfp_flags, __entry->node)
328);
329
330FTRACE_ENTRY(kmem_free, kmemtrace_free_entry,
331
332 TRACE_KMEM_FREE,
333
334 F_STRUCT(
335 __field( enum kmemtrace_type_id, type_id )
336 __field( unsigned long, call_site )
337 __field( const void *, ptr )
338 ),
339
340 F_printk("type:%u call_site:%lx ptr:%p",
341 __entry->type_id, __entry->call_site, __entry->ptr)
342);