1#ifndef _LINUX_FTRACE_H
2#define _LINUX_FTRACE_H
3
4#include <linux/trace_clock.h>
5#include <linux/kallsyms.h>
6#include <linux/linkage.h>
7#include <linux/bitops.h>
8#include <linux/module.h>
9#include <linux/ktime.h>
10#include <linux/sched.h>
11#include <linux/types.h>
12#include <linux/init.h>
13#include <linux/fs.h>
14
15#include <asm/ftrace.h>
16
17#ifdef CONFIG_FUNCTION_TRACER
18
19extern int ftrace_enabled;
20extern int
21ftrace_enable_sysctl(struct ctl_table *table, int write,
22 void __user *buffer, size_t *lenp,
23 loff_t *ppos);
24
25typedef void (*ftrace_func_t)(unsigned long ip, unsigned long parent_ip);
26
27struct ftrace_ops {
28 ftrace_func_t func;
29 struct ftrace_ops *next;
30};
31
32extern int function_trace_stop;
33
34
35
36
37enum ftrace_tracing_type_t {
38 FTRACE_TYPE_ENTER = 0,
39 FTRACE_TYPE_RETURN,
40};
41
42
43extern enum ftrace_tracing_type_t ftrace_tracing_type;
44
45
46
47
48
49
50
51
52
53static inline void ftrace_stop(void)
54{
55 function_trace_stop = 1;
56}
57
58
59
60
61
62
63
64
65
66static inline void ftrace_start(void)
67{
68 function_trace_stop = 0;
69}
70
71
72
73
74
75
76
77
78int register_ftrace_function(struct ftrace_ops *ops);
79int unregister_ftrace_function(struct ftrace_ops *ops);
80void clear_ftrace_function(void);
81
82extern void ftrace_stub(unsigned long a0, unsigned long a1);
83
84#else
85# define register_ftrace_function(ops) do { } while (0)
86# define unregister_ftrace_function(ops) do { } while (0)
87# define clear_ftrace_function(ops) do { } while (0)
88static inline void ftrace_kill(void) { }
89static inline void ftrace_stop(void) { }
90static inline void ftrace_start(void) { }
91#endif
92
93#ifdef CONFIG_STACK_TRACER
94extern int stack_tracer_enabled;
95int
96stack_trace_sysctl(struct ctl_table *table, int write,
97 void __user *buffer, size_t *lenp,
98 loff_t *ppos);
99#endif
100
101struct ftrace_func_command {
102 struct list_head list;
103 char *name;
104 int (*func)(char *func, char *cmd,
105 char *params, int enable);
106};
107
108#ifdef CONFIG_DYNAMIC_FTRACE
109
110int ftrace_arch_code_modify_prepare(void);
111int ftrace_arch_code_modify_post_process(void);
112
113struct seq_file;
114
115struct ftrace_probe_ops {
116 void (*func)(unsigned long ip,
117 unsigned long parent_ip,
118 void **data);
119 int (*callback)(unsigned long ip, void **data);
120 void (*free)(void **data);
121 int (*print)(struct seq_file *m,
122 unsigned long ip,
123 struct ftrace_probe_ops *ops,
124 void *data);
125};
126
127extern int
128register_ftrace_function_probe(char *glob, struct ftrace_probe_ops *ops,
129 void *data);
130extern void
131unregister_ftrace_function_probe(char *glob, struct ftrace_probe_ops *ops,
132 void *data);
133extern void
134unregister_ftrace_function_probe_func(char *glob, struct ftrace_probe_ops *ops);
135extern void unregister_ftrace_function_probe_all(char *glob);
136
137enum {
138 FTRACE_FL_FREE = (1 << 0),
139 FTRACE_FL_FAILED = (1 << 1),
140 FTRACE_FL_FILTER = (1 << 2),
141 FTRACE_FL_ENABLED = (1 << 3),
142 FTRACE_FL_NOTRACE = (1 << 4),
143 FTRACE_FL_CONVERTED = (1 << 5),
144 FTRACE_FL_FROZEN = (1 << 6),
145};
146
147struct dyn_ftrace {
148 union {
149 unsigned long ip;
150 struct dyn_ftrace *freelist;
151 };
152 union {
153 unsigned long flags;
154 struct dyn_ftrace *newlist;
155 };
156 struct dyn_arch_ftrace arch;
157};
158
159int ftrace_force_update(void);
160void ftrace_set_filter(unsigned char *buf, int len, int reset);
161
162int register_ftrace_command(struct ftrace_func_command *cmd);
163int unregister_ftrace_command(struct ftrace_func_command *cmd);
164
165
166extern int ftrace_ip_converted(unsigned long ip);
167extern int ftrace_dyn_arch_init(void *data);
168extern int ftrace_update_ftrace_func(ftrace_func_t func);
169extern void ftrace_caller(void);
170extern void ftrace_call(void);
171extern void mcount_call(void);
172
173#ifndef FTRACE_ADDR
174#define FTRACE_ADDR ((unsigned long)ftrace_caller)
175#endif
176#ifdef CONFIG_FUNCTION_GRAPH_TRACER
177extern void ftrace_graph_caller(void);
178extern int ftrace_enable_ftrace_graph_caller(void);
179extern int ftrace_disable_ftrace_graph_caller(void);
180#else
181static inline int ftrace_enable_ftrace_graph_caller(void) { return 0; }
182static inline int ftrace_disable_ftrace_graph_caller(void) { return 0; }
183#endif
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206extern int ftrace_make_nop(struct module *mod,
207 struct dyn_ftrace *rec, unsigned long addr);
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229extern int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr);
230
231
232extern int ftrace_arch_read_dyn_info(char *buf, int size);
233
234extern int skip_trace(unsigned long ip);
235
236extern void ftrace_disable_daemon(void);
237extern void ftrace_enable_daemon(void);
238#else
239# define skip_trace(ip) ({ 0; })
240# define ftrace_force_update() ({ 0; })
241# define ftrace_set_filter(buf, len, reset) do { } while (0)
242# define ftrace_disable_daemon() do { } while (0)
243# define ftrace_enable_daemon() do { } while (0)
244static inline void ftrace_release_mod(struct module *mod) {}
245static inline int register_ftrace_command(struct ftrace_func_command *cmd)
246{
247 return -EINVAL;
248}
249static inline int unregister_ftrace_command(char *cmd_name)
250{
251 return -EINVAL;
252}
253#endif
254
255
256void ftrace_kill(void);
257
258static inline void tracer_disable(void)
259{
260#ifdef CONFIG_FUNCTION_TRACER
261 ftrace_enabled = 0;
262#endif
263}
264
265
266
267
268
269
270static inline int __ftrace_enabled_save(void)
271{
272#ifdef CONFIG_FUNCTION_TRACER
273 int saved_ftrace_enabled = ftrace_enabled;
274 ftrace_enabled = 0;
275 return saved_ftrace_enabled;
276#else
277 return 0;
278#endif
279}
280
281static inline void __ftrace_enabled_restore(int enabled)
282{
283#ifdef CONFIG_FUNCTION_TRACER
284 ftrace_enabled = enabled;
285#endif
286}
287
288#ifndef HAVE_ARCH_CALLER_ADDR
289# ifdef CONFIG_FRAME_POINTER
290# define CALLER_ADDR0 ((unsigned long)__builtin_return_address(0))
291# define CALLER_ADDR1 ((unsigned long)__builtin_return_address(1))
292# define CALLER_ADDR2 ((unsigned long)__builtin_return_address(2))
293# define CALLER_ADDR3 ((unsigned long)__builtin_return_address(3))
294# define CALLER_ADDR4 ((unsigned long)__builtin_return_address(4))
295# define CALLER_ADDR5 ((unsigned long)__builtin_return_address(5))
296# define CALLER_ADDR6 ((unsigned long)__builtin_return_address(6))
297# else
298# define CALLER_ADDR0 ((unsigned long)__builtin_return_address(0))
299# define CALLER_ADDR1 0UL
300# define CALLER_ADDR2 0UL
301# define CALLER_ADDR3 0UL
302# define CALLER_ADDR4 0UL
303# define CALLER_ADDR5 0UL
304# define CALLER_ADDR6 0UL
305# endif
306#endif
307
308#ifdef CONFIG_IRQSOFF_TRACER
309 extern void time_hardirqs_on(unsigned long a0, unsigned long a1);
310 extern void time_hardirqs_off(unsigned long a0, unsigned long a1);
311#else
312# define time_hardirqs_on(a0, a1) do { } while (0)
313# define time_hardirqs_off(a0, a1) do { } while (0)
314#endif
315
316#ifdef CONFIG_PREEMPT_TRACER
317 extern void trace_preempt_on(unsigned long a0, unsigned long a1);
318 extern void trace_preempt_off(unsigned long a0, unsigned long a1);
319#else
320# define trace_preempt_on(a0, a1) do { } while (0)
321# define trace_preempt_off(a0, a1) do { } while (0)
322#endif
323
324#ifdef CONFIG_FTRACE_MCOUNT_RECORD
325extern void ftrace_init(void);
326#else
327static inline void ftrace_init(void) { }
328#endif
329
330
331
332
333struct ftrace_graph_ent {
334 unsigned long func;
335 int depth;
336};
337
338
339
340
341struct ftrace_graph_ret {
342 unsigned long func;
343 unsigned long long calltime;
344 unsigned long long rettime;
345
346 unsigned long overrun;
347 int depth;
348};
349
350#ifdef CONFIG_FUNCTION_GRAPH_TRACER
351
352
353#define INIT_FTRACE_GRAPH .ret_stack = NULL,
354
355
356
357
358
359
360struct ftrace_ret_stack {
361 unsigned long ret;
362 unsigned long func;
363 unsigned long long calltime;
364 unsigned long long subtime;
365 unsigned long fp;
366};
367
368
369
370
371
372
373extern void return_to_handler(void);
374
375extern int
376ftrace_push_return_trace(unsigned long ret, unsigned long func, int *depth,
377 unsigned long frame_pointer);
378
379
380
381
382
383
384#define __notrace_funcgraph notrace
385
386
387
388
389
390#define __irq_entry __attribute__((__section__(".irqentry.text")))
391
392
393extern char __irqentry_text_start[];
394extern char __irqentry_text_end[];
395
396#define FTRACE_RETFUNC_DEPTH 50
397#define FTRACE_RETSTACK_ALLOC_SIZE 32
398
399typedef void (*trace_func_graph_ret_t)(struct ftrace_graph_ret *);
400typedef int (*trace_func_graph_ent_t)(struct ftrace_graph_ent *);
401
402extern int register_ftrace_graph(trace_func_graph_ret_t retfunc,
403 trace_func_graph_ent_t entryfunc);
404
405extern void ftrace_graph_stop(void);
406
407
408extern trace_func_graph_ret_t ftrace_graph_return;
409extern trace_func_graph_ent_t ftrace_graph_entry;
410
411extern void unregister_ftrace_graph(void);
412
413extern void ftrace_graph_init_task(struct task_struct *t);
414extern void ftrace_graph_exit_task(struct task_struct *t);
415
416static inline int task_curr_ret_stack(struct task_struct *t)
417{
418 return t->curr_ret_stack;
419}
420
421static inline void pause_graph_tracing(void)
422{
423 atomic_inc(¤t->tracing_graph_pause);
424}
425
426static inline void unpause_graph_tracing(void)
427{
428 atomic_dec(¤t->tracing_graph_pause);
429}
430#else
431
432#define __notrace_funcgraph
433#define __irq_entry
434#define INIT_FTRACE_GRAPH
435
436static inline void ftrace_graph_init_task(struct task_struct *t) { }
437static inline void ftrace_graph_exit_task(struct task_struct *t) { }
438
439static inline int task_curr_ret_stack(struct task_struct *tsk)
440{
441 return -1;
442}
443
444static inline void pause_graph_tracing(void) { }
445static inline void unpause_graph_tracing(void) { }
446#endif
447
448#ifdef CONFIG_TRACING
449
450
451enum {
452 TSK_TRACE_FL_TRACE_BIT = 0,
453 TSK_TRACE_FL_GRAPH_BIT = 1,
454};
455enum {
456 TSK_TRACE_FL_TRACE = 1 << TSK_TRACE_FL_TRACE_BIT,
457 TSK_TRACE_FL_GRAPH = 1 << TSK_TRACE_FL_GRAPH_BIT,
458};
459
460static inline void set_tsk_trace_trace(struct task_struct *tsk)
461{
462 set_bit(TSK_TRACE_FL_TRACE_BIT, &tsk->trace);
463}
464
465static inline void clear_tsk_trace_trace(struct task_struct *tsk)
466{
467 clear_bit(TSK_TRACE_FL_TRACE_BIT, &tsk->trace);
468}
469
470static inline int test_tsk_trace_trace(struct task_struct *tsk)
471{
472 return tsk->trace & TSK_TRACE_FL_TRACE;
473}
474
475static inline void set_tsk_trace_graph(struct task_struct *tsk)
476{
477 set_bit(TSK_TRACE_FL_GRAPH_BIT, &tsk->trace);
478}
479
480static inline void clear_tsk_trace_graph(struct task_struct *tsk)
481{
482 clear_bit(TSK_TRACE_FL_GRAPH_BIT, &tsk->trace);
483}
484
485static inline int test_tsk_trace_graph(struct task_struct *tsk)
486{
487 return tsk->trace & TSK_TRACE_FL_GRAPH;
488}
489
490extern int ftrace_dump_on_oops;
491
492#ifdef CONFIG_PREEMPT
493#define INIT_TRACE_RECURSION .trace_recursion = 0,
494#endif
495
496#endif
497
498#ifndef INIT_TRACE_RECURSION
499#define INIT_TRACE_RECURSION
500#endif
501
502#ifdef CONFIG_HW_BRANCH_TRACER
503
504void trace_hw_branch(u64 from, u64 to);
505void trace_hw_branch_oops(void);
506
507#else
508
509static inline void trace_hw_branch(u64 from, u64 to) {}
510static inline void trace_hw_branch_oops(void) {}
511
512#endif
513
514#endif
515