aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/trace/trace.h
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/trace/trace.h')
-rw-r--r--kernel/trace/trace.h215
1 files changed, 149 insertions, 66 deletions
diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h
index f69f86788c2b..8465ad052707 100644
--- a/kernel/trace/trace.h
+++ b/kernel/trace/trace.h
@@ -5,7 +5,9 @@
5#include <asm/atomic.h> 5#include <asm/atomic.h>
6#include <linux/sched.h> 6#include <linux/sched.h>
7#include <linux/clocksource.h> 7#include <linux/clocksource.h>
8#include <linux/ring_buffer.h>
8#include <linux/mmiotrace.h> 9#include <linux/mmiotrace.h>
10#include <linux/ftrace.h>
9 11
10enum trace_type { 12enum trace_type {
11 __TRACE_FIRST_TYPE = 0, 13 __TRACE_FIRST_TYPE = 0,
@@ -13,38 +15,60 @@ enum trace_type {
13 TRACE_FN, 15 TRACE_FN,
14 TRACE_CTX, 16 TRACE_CTX,
15 TRACE_WAKE, 17 TRACE_WAKE,
18 TRACE_CONT,
16 TRACE_STACK, 19 TRACE_STACK,
20 TRACE_PRINT,
17 TRACE_SPECIAL, 21 TRACE_SPECIAL,
18 TRACE_MMIO_RW, 22 TRACE_MMIO_RW,
19 TRACE_MMIO_MAP, 23 TRACE_MMIO_MAP,
24 TRACE_BOOT,
20 25
21 __TRACE_LAST_TYPE 26 __TRACE_LAST_TYPE
22}; 27};
23 28
24/* 29/*
30 * The trace entry - the most basic unit of tracing. This is what
31 * is printed in the end as a single line in the trace output, such as:
32 *
33 * bash-15816 [01] 235.197585: idle_cpu <- irq_enter
34 */
35struct trace_entry {
36 unsigned char type;
37 unsigned char cpu;
38 unsigned char flags;
39 unsigned char preempt_count;
40 int pid;
41};
42
43/*
25 * Function trace entry - function address and parent function addres: 44 * Function trace entry - function address and parent function addres:
26 */ 45 */
27struct ftrace_entry { 46struct ftrace_entry {
47 struct trace_entry ent;
28 unsigned long ip; 48 unsigned long ip;
29 unsigned long parent_ip; 49 unsigned long parent_ip;
30}; 50};
51extern struct tracer boot_tracer;
31 52
32/* 53/*
33 * Context switch trace entry - which task (and prio) we switched from/to: 54 * Context switch trace entry - which task (and prio) we switched from/to:
34 */ 55 */
35struct ctx_switch_entry { 56struct ctx_switch_entry {
57 struct trace_entry ent;
36 unsigned int prev_pid; 58 unsigned int prev_pid;
37 unsigned char prev_prio; 59 unsigned char prev_prio;
38 unsigned char prev_state; 60 unsigned char prev_state;
39 unsigned int next_pid; 61 unsigned int next_pid;
40 unsigned char next_prio; 62 unsigned char next_prio;
41 unsigned char next_state; 63 unsigned char next_state;
64 unsigned int next_cpu;
42}; 65};
43 66
44/* 67/*
45 * Special (free-form) trace entry: 68 * Special (free-form) trace entry:
46 */ 69 */
47struct special_entry { 70struct special_entry {
71 struct trace_entry ent;
48 unsigned long arg1; 72 unsigned long arg1;
49 unsigned long arg2; 73 unsigned long arg2;
50 unsigned long arg3; 74 unsigned long arg3;
@@ -57,33 +81,62 @@ struct special_entry {
57#define FTRACE_STACK_ENTRIES 8 81#define FTRACE_STACK_ENTRIES 8
58 82
59struct stack_entry { 83struct stack_entry {
84 struct trace_entry ent;
60 unsigned long caller[FTRACE_STACK_ENTRIES]; 85 unsigned long caller[FTRACE_STACK_ENTRIES];
61}; 86};
62 87
63/* 88/*
64 * The trace entry - the most basic unit of tracing. This is what 89 * ftrace_printk entry:
65 * is printed in the end as a single line in the trace output, such as:
66 *
67 * bash-15816 [01] 235.197585: idle_cpu <- irq_enter
68 */ 90 */
69struct trace_entry { 91struct print_entry {
70 char type; 92 struct trace_entry ent;
71 char cpu; 93 unsigned long ip;
72 char flags; 94 char buf[];
73 char preempt_count; 95};
74 int pid; 96
75 cycle_t t; 97#define TRACE_OLD_SIZE 88
76 union { 98
77 struct ftrace_entry fn; 99struct trace_field_cont {
78 struct ctx_switch_entry ctx; 100 unsigned char type;
79 struct special_entry special; 101 /* Temporary till we get rid of this completely */
80 struct stack_entry stack; 102 char buf[TRACE_OLD_SIZE - 1];
81 struct mmiotrace_rw mmiorw; 103};
82 struct mmiotrace_map mmiomap; 104
83 }; 105struct trace_mmiotrace_rw {
106 struct trace_entry ent;
107 struct mmiotrace_rw rw;
108};
109
110struct trace_mmiotrace_map {
111 struct trace_entry ent;
112 struct mmiotrace_map map;
113};
114
115struct trace_boot {
116 struct trace_entry ent;
117 struct boot_trace initcall;
118};
119
120/*
121 * trace_flag_type is an enumeration that holds different
122 * states when a trace occurs. These are:
123 * IRQS_OFF - interrupts were disabled
124 * IRQS_NOSUPPORT - arch does not support irqs_disabled_flags
125 * NEED_RESCED - reschedule is requested
126 * HARDIRQ - inside an interrupt handler
127 * SOFTIRQ - inside a softirq handler
128 * CONT - multiple entries hold the trace item
129 */
130enum trace_flag_type {
131 TRACE_FLAG_IRQS_OFF = 0x01,
132 TRACE_FLAG_IRQS_NOSUPPORT = 0x02,
133 TRACE_FLAG_NEED_RESCHED = 0x04,
134 TRACE_FLAG_HARDIRQ = 0x08,
135 TRACE_FLAG_SOFTIRQ = 0x10,
136 TRACE_FLAG_CONT = 0x20,
84}; 137};
85 138
86#define TRACE_ENTRY_SIZE sizeof(struct trace_entry) 139#define TRACE_BUF_SIZE 1024
87 140
88/* 141/*
89 * The CPU trace array - it consists of thousands of trace entries 142 * The CPU trace array - it consists of thousands of trace entries
@@ -91,16 +144,9 @@ struct trace_entry {
91 * the trace, etc.) 144 * the trace, etc.)
92 */ 145 */
93struct trace_array_cpu { 146struct trace_array_cpu {
94 struct list_head trace_pages;
95 atomic_t disabled; 147 atomic_t disabled;
96 raw_spinlock_t lock;
97 struct lock_class_key lock_key;
98 148
99 /* these fields get copied into max-trace: */ 149 /* these fields get copied into max-trace: */
100 unsigned trace_head_idx;
101 unsigned trace_tail_idx;
102 void *trace_head; /* producer */
103 void *trace_tail; /* consumer */
104 unsigned long trace_idx; 150 unsigned long trace_idx;
105 unsigned long overrun; 151 unsigned long overrun;
106 unsigned long saved_latency; 152 unsigned long saved_latency;
@@ -124,6 +170,7 @@ struct trace_iterator;
124 * They have on/off state as well: 170 * They have on/off state as well:
125 */ 171 */
126struct trace_array { 172struct trace_array {
173 struct ring_buffer *buffer;
127 unsigned long entries; 174 unsigned long entries;
128 long ctrl; 175 long ctrl;
129 int cpu; 176 int cpu;
@@ -132,6 +179,56 @@ struct trace_array {
132 struct trace_array_cpu *data[NR_CPUS]; 179 struct trace_array_cpu *data[NR_CPUS];
133}; 180};
134 181
182#define FTRACE_CMP_TYPE(var, type) \
183 __builtin_types_compatible_p(typeof(var), type *)
184
185#undef IF_ASSIGN
186#define IF_ASSIGN(var, entry, etype, id) \
187 if (FTRACE_CMP_TYPE(var, etype)) { \
188 var = (typeof(var))(entry); \
189 WARN_ON(id && (entry)->type != id); \
190 break; \
191 }
192
193/* Will cause compile errors if type is not found. */
194extern void __ftrace_bad_type(void);
195
196/*
197 * The trace_assign_type is a verifier that the entry type is
198 * the same as the type being assigned. To add new types simply
199 * add a line with the following format:
200 *
201 * IF_ASSIGN(var, ent, type, id);
202 *
203 * Where "type" is the trace type that includes the trace_entry
204 * as the "ent" item. And "id" is the trace identifier that is
205 * used in the trace_type enum.
206 *
207 * If the type can have more than one id, then use zero.
208 */
209#define trace_assign_type(var, ent) \
210 do { \
211 IF_ASSIGN(var, ent, struct ftrace_entry, TRACE_FN); \
212 IF_ASSIGN(var, ent, struct ctx_switch_entry, 0); \
213 IF_ASSIGN(var, ent, struct trace_field_cont, TRACE_CONT); \
214 IF_ASSIGN(var, ent, struct stack_entry, TRACE_STACK); \
215 IF_ASSIGN(var, ent, struct print_entry, TRACE_PRINT); \
216 IF_ASSIGN(var, ent, struct special_entry, 0); \
217 IF_ASSIGN(var, ent, struct trace_mmiotrace_rw, \
218 TRACE_MMIO_RW); \
219 IF_ASSIGN(var, ent, struct trace_mmiotrace_map, \
220 TRACE_MMIO_MAP); \
221 IF_ASSIGN(var, ent, struct trace_boot, TRACE_BOOT); \
222 __ftrace_bad_type(); \
223 } while (0)
224
225/* Return values for print_line callback */
226enum print_line_t {
227 TRACE_TYPE_PARTIAL_LINE = 0, /* Retry after flushing the seq */
228 TRACE_TYPE_HANDLED = 1,
229 TRACE_TYPE_UNHANDLED = 2 /* Relay to other output functions */
230};
231
135/* 232/*
136 * A specific tracer, represented by methods that operate on a trace array: 233 * A specific tracer, represented by methods that operate on a trace array:
137 */ 234 */
@@ -152,7 +249,7 @@ struct tracer {
152 int (*selftest)(struct tracer *trace, 249 int (*selftest)(struct tracer *trace,
153 struct trace_array *tr); 250 struct trace_array *tr);
154#endif 251#endif
155 int (*print_line)(struct trace_iterator *iter); 252 enum print_line_t (*print_line)(struct trace_iterator *iter);
156 struct tracer *next; 253 struct tracer *next;
157 int print_max; 254 int print_max;
158}; 255};
@@ -171,57 +268,58 @@ struct trace_iterator {
171 struct trace_array *tr; 268 struct trace_array *tr;
172 struct tracer *trace; 269 struct tracer *trace;
173 void *private; 270 void *private;
174 long last_overrun[NR_CPUS]; 271 struct ring_buffer_iter *buffer_iter[NR_CPUS];
175 long overrun[NR_CPUS];
176 272
177 /* The below is zeroed out in pipe_read */ 273 /* The below is zeroed out in pipe_read */
178 struct trace_seq seq; 274 struct trace_seq seq;
179 struct trace_entry *ent; 275 struct trace_entry *ent;
180 int cpu; 276 int cpu;
181 277 u64 ts;
182 struct trace_entry *prev_ent;
183 int prev_cpu;
184 278
185 unsigned long iter_flags; 279 unsigned long iter_flags;
186 loff_t pos; 280 loff_t pos;
187 unsigned long next_idx[NR_CPUS];
188 struct list_head *next_page[NR_CPUS];
189 unsigned next_page_idx[NR_CPUS];
190 long idx; 281 long idx;
191}; 282};
192 283
193void tracing_reset(struct trace_array_cpu *data); 284void trace_wake_up(void);
285void tracing_reset(struct trace_array *tr, int cpu);
194int tracing_open_generic(struct inode *inode, struct file *filp); 286int tracing_open_generic(struct inode *inode, struct file *filp);
195struct dentry *tracing_init_dentry(void); 287struct dentry *tracing_init_dentry(void);
196void init_tracer_sysprof_debugfs(struct dentry *d_tracer); 288void init_tracer_sysprof_debugfs(struct dentry *d_tracer);
197 289
290struct trace_entry *tracing_get_trace_entry(struct trace_array *tr,
291 struct trace_array_cpu *data);
292void tracing_generic_entry_update(struct trace_entry *entry,
293 unsigned long flags,
294 int pc);
295
198void ftrace(struct trace_array *tr, 296void ftrace(struct trace_array *tr,
199 struct trace_array_cpu *data, 297 struct trace_array_cpu *data,
200 unsigned long ip, 298 unsigned long ip,
201 unsigned long parent_ip, 299 unsigned long parent_ip,
202 unsigned long flags); 300 unsigned long flags, int pc);
203void tracing_sched_switch_trace(struct trace_array *tr, 301void tracing_sched_switch_trace(struct trace_array *tr,
204 struct trace_array_cpu *data, 302 struct trace_array_cpu *data,
205 struct task_struct *prev, 303 struct task_struct *prev,
206 struct task_struct *next, 304 struct task_struct *next,
207 unsigned long flags); 305 unsigned long flags, int pc);
208void tracing_record_cmdline(struct task_struct *tsk); 306void tracing_record_cmdline(struct task_struct *tsk);
209 307
210void tracing_sched_wakeup_trace(struct trace_array *tr, 308void tracing_sched_wakeup_trace(struct trace_array *tr,
211 struct trace_array_cpu *data, 309 struct trace_array_cpu *data,
212 struct task_struct *wakee, 310 struct task_struct *wakee,
213 struct task_struct *cur, 311 struct task_struct *cur,
214 unsigned long flags); 312 unsigned long flags, int pc);
215void trace_special(struct trace_array *tr, 313void trace_special(struct trace_array *tr,
216 struct trace_array_cpu *data, 314 struct trace_array_cpu *data,
217 unsigned long arg1, 315 unsigned long arg1,
218 unsigned long arg2, 316 unsigned long arg2,
219 unsigned long arg3); 317 unsigned long arg3, int pc);
220void trace_function(struct trace_array *tr, 318void trace_function(struct trace_array *tr,
221 struct trace_array_cpu *data, 319 struct trace_array_cpu *data,
222 unsigned long ip, 320 unsigned long ip,
223 unsigned long parent_ip, 321 unsigned long parent_ip,
224 unsigned long flags); 322 unsigned long flags, int pc);
225 323
226void tracing_start_cmdline_record(void); 324void tracing_start_cmdline_record(void);
227void tracing_stop_cmdline_record(void); 325void tracing_stop_cmdline_record(void);
@@ -239,7 +337,7 @@ void update_max_tr_single(struct trace_array *tr,
239 337
240extern cycle_t ftrace_now(int cpu); 338extern cycle_t ftrace_now(int cpu);
241 339
242#ifdef CONFIG_FTRACE 340#ifdef CONFIG_FUNCTION_TRACER
243void tracing_start_function_trace(void); 341void tracing_start_function_trace(void);
244void tracing_stop_function_trace(void); 342void tracing_stop_function_trace(void);
245#else 343#else
@@ -268,51 +366,33 @@ extern unsigned long ftrace_update_tot_cnt;
268extern int DYN_FTRACE_TEST_NAME(void); 366extern int DYN_FTRACE_TEST_NAME(void);
269#endif 367#endif
270 368
271#ifdef CONFIG_MMIOTRACE
272extern void __trace_mmiotrace_rw(struct trace_array *tr,
273 struct trace_array_cpu *data,
274 struct mmiotrace_rw *rw);
275extern void __trace_mmiotrace_map(struct trace_array *tr,
276 struct trace_array_cpu *data,
277 struct mmiotrace_map *map);
278#endif
279
280#ifdef CONFIG_FTRACE_STARTUP_TEST 369#ifdef CONFIG_FTRACE_STARTUP_TEST
281#ifdef CONFIG_FTRACE
282extern int trace_selftest_startup_function(struct tracer *trace, 370extern int trace_selftest_startup_function(struct tracer *trace,
283 struct trace_array *tr); 371 struct trace_array *tr);
284#endif
285#ifdef CONFIG_IRQSOFF_TRACER
286extern int trace_selftest_startup_irqsoff(struct tracer *trace, 372extern int trace_selftest_startup_irqsoff(struct tracer *trace,
287 struct trace_array *tr); 373 struct trace_array *tr);
288#endif
289#ifdef CONFIG_PREEMPT_TRACER
290extern int trace_selftest_startup_preemptoff(struct tracer *trace, 374extern int trace_selftest_startup_preemptoff(struct tracer *trace,
291 struct trace_array *tr); 375 struct trace_array *tr);
292#endif
293#if defined(CONFIG_IRQSOFF_TRACER) && defined(CONFIG_PREEMPT_TRACER)
294extern int trace_selftest_startup_preemptirqsoff(struct tracer *trace, 376extern int trace_selftest_startup_preemptirqsoff(struct tracer *trace,
295 struct trace_array *tr); 377 struct trace_array *tr);
296#endif
297#ifdef CONFIG_SCHED_TRACER
298extern int trace_selftest_startup_wakeup(struct tracer *trace, 378extern int trace_selftest_startup_wakeup(struct tracer *trace,
299 struct trace_array *tr); 379 struct trace_array *tr);
300#endif 380extern int trace_selftest_startup_nop(struct tracer *trace,
301#ifdef CONFIG_CONTEXT_SWITCH_TRACER 381 struct trace_array *tr);
302extern int trace_selftest_startup_sched_switch(struct tracer *trace, 382extern int trace_selftest_startup_sched_switch(struct tracer *trace,
303 struct trace_array *tr); 383 struct trace_array *tr);
304#endif
305#ifdef CONFIG_SYSPROF_TRACER
306extern int trace_selftest_startup_sysprof(struct tracer *trace, 384extern int trace_selftest_startup_sysprof(struct tracer *trace,
307 struct trace_array *tr); 385 struct trace_array *tr);
308#endif
309#endif /* CONFIG_FTRACE_STARTUP_TEST */ 386#endif /* CONFIG_FTRACE_STARTUP_TEST */
310 387
311extern void *head_page(struct trace_array_cpu *data); 388extern void *head_page(struct trace_array_cpu *data);
312extern int trace_seq_printf(struct trace_seq *s, const char *fmt, ...); 389extern int trace_seq_printf(struct trace_seq *s, const char *fmt, ...);
390extern void trace_seq_print_cont(struct trace_seq *s,
391 struct trace_iterator *iter);
313extern ssize_t trace_seq_to_user(struct trace_seq *s, char __user *ubuf, 392extern ssize_t trace_seq_to_user(struct trace_seq *s, char __user *ubuf,
314 size_t cnt); 393 size_t cnt);
315extern long ns2usecs(cycle_t nsec); 394extern long ns2usecs(cycle_t nsec);
395extern int trace_vprintk(unsigned long ip, const char *fmt, va_list args);
316 396
317extern unsigned long trace_flags; 397extern unsigned long trace_flags;
318 398
@@ -334,6 +414,9 @@ enum trace_iterator_flags {
334 TRACE_ITER_BLOCK = 0x80, 414 TRACE_ITER_BLOCK = 0x80,
335 TRACE_ITER_STACKTRACE = 0x100, 415 TRACE_ITER_STACKTRACE = 0x100,
336 TRACE_ITER_SCHED_TREE = 0x200, 416 TRACE_ITER_SCHED_TREE = 0x200,
417 TRACE_ITER_PRINTK = 0x400,
337}; 418};
338 419
420extern struct tracer nop_trace;
421
339#endif /* _LINUX_KERNEL_TRACE_H */ 422#endif /* _LINUX_KERNEL_TRACE_H */