1
2
3
4
5
6
7#ifndef _LINUX_FTRACE_H
8#define _LINUX_FTRACE_H
9
10#include <linux/trace_recursion.h>
11#include <linux/trace_clock.h>
12#include <linux/kallsyms.h>
13#include <linux/linkage.h>
14#include <linux/bitops.h>
15#include <linux/ptrace.h>
16#include <linux/ktime.h>
17#include <linux/sched.h>
18#include <linux/types.h>
19#include <linux/init.h>
20#include <linux/fs.h>
21
22#include <asm/ftrace.h>
23
24
25
26
27
28
29#ifndef ARCH_SUPPORTS_FTRACE_OPS
30#define ARCH_SUPPORTS_FTRACE_OPS 0
31#endif
32
33
34
35
36
37
38#if !ARCH_SUPPORTS_FTRACE_OPS
39# define FTRACE_FORCE_LIST_FUNC 1
40#else
41# define FTRACE_FORCE_LIST_FUNC 0
42#endif
43
44
45#ifdef CONFIG_TRACING
46void trace_init(void);
47void early_trace_init(void);
48#else
49static inline void trace_init(void) { }
50static inline void early_trace_init(void) { }
51#endif
52
53struct module;
54struct ftrace_hash;
55struct ftrace_direct_func;
56
57#if defined(CONFIG_FUNCTION_TRACER) && defined(CONFIG_MODULES) && \
58 defined(CONFIG_DYNAMIC_FTRACE)
59const char *
60ftrace_mod_address_lookup(unsigned long addr, unsigned long *size,
61 unsigned long *off, char **modname, char *sym);
62#else
63static inline const char *
64ftrace_mod_address_lookup(unsigned long addr, unsigned long *size,
65 unsigned long *off, char **modname, char *sym)
66{
67 return NULL;
68}
69#endif
70
71#if defined(CONFIG_FUNCTION_TRACER) && defined(CONFIG_DYNAMIC_FTRACE)
72int ftrace_mod_get_kallsym(unsigned int symnum, unsigned long *value,
73 char *type, char *name,
74 char *module_name, int *exported);
75#else
76static inline int ftrace_mod_get_kallsym(unsigned int symnum, unsigned long *value,
77 char *type, char *name,
78 char *module_name, int *exported)
79{
80 return -1;
81}
82#endif
83
84#ifdef CONFIG_FUNCTION_TRACER
85
86extern int ftrace_enabled;
87extern int
88ftrace_enable_sysctl(struct ctl_table *table, int write,
89 void *buffer, size_t *lenp, loff_t *ppos);
90
91struct ftrace_ops;
92
93#ifndef CONFIG_HAVE_DYNAMIC_FTRACE_WITH_ARGS
94
95struct ftrace_regs {
96 struct pt_regs regs;
97};
98#define arch_ftrace_get_regs(fregs) (&(fregs)->regs)
99
100
101
102
103
104
105
106#define ftrace_instruction_pointer_set(fregs, ip) do { } while (0)
107#endif
108
109static __always_inline struct pt_regs *ftrace_get_regs(struct ftrace_regs *fregs)
110{
111 if (!fregs)
112 return NULL;
113
114 return arch_ftrace_get_regs(fregs);
115}
116
117typedef void (*ftrace_func_t)(unsigned long ip, unsigned long parent_ip,
118 struct ftrace_ops *op, struct ftrace_regs *fregs);
119
120ftrace_func_t ftrace_ops_get_func(struct ftrace_ops *ops);
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178enum {
179 FTRACE_OPS_FL_ENABLED = BIT(0),
180 FTRACE_OPS_FL_DYNAMIC = BIT(1),
181 FTRACE_OPS_FL_SAVE_REGS = BIT(2),
182 FTRACE_OPS_FL_SAVE_REGS_IF_SUPPORTED = BIT(3),
183 FTRACE_OPS_FL_RECURSION = BIT(4),
184 FTRACE_OPS_FL_STUB = BIT(5),
185 FTRACE_OPS_FL_INITIALIZED = BIT(6),
186 FTRACE_OPS_FL_DELETED = BIT(7),
187 FTRACE_OPS_FL_ADDING = BIT(8),
188 FTRACE_OPS_FL_REMOVING = BIT(9),
189 FTRACE_OPS_FL_MODIFYING = BIT(10),
190 FTRACE_OPS_FL_ALLOC_TRAMP = BIT(11),
191 FTRACE_OPS_FL_IPMODIFY = BIT(12),
192 FTRACE_OPS_FL_PID = BIT(13),
193 FTRACE_OPS_FL_RCU = BIT(14),
194 FTRACE_OPS_FL_TRACE_ARRAY = BIT(15),
195 FTRACE_OPS_FL_PERMANENT = BIT(16),
196 FTRACE_OPS_FL_DIRECT = BIT(17),
197};
198
199#ifdef CONFIG_DYNAMIC_FTRACE
200
201struct ftrace_ops_hash {
202 struct ftrace_hash __rcu *notrace_hash;
203 struct ftrace_hash __rcu *filter_hash;
204 struct mutex regex_lock;
205};
206
207void ftrace_free_init_mem(void);
208void ftrace_free_mem(struct module *mod, void *start, void *end);
209#else
210static inline void ftrace_free_init_mem(void) { }
211static inline void ftrace_free_mem(struct module *mod, void *start, void *end) { }
212#endif
213
214
215
216
217
218
219
220
221
222
223
224
225struct ftrace_ops {
226 ftrace_func_t func;
227 struct ftrace_ops __rcu *next;
228 unsigned long flags;
229 void *private;
230 ftrace_func_t saved_func;
231#ifdef CONFIG_DYNAMIC_FTRACE
232 struct ftrace_ops_hash local_hash;
233 struct ftrace_ops_hash *func_hash;
234 struct ftrace_ops_hash old_hash;
235 unsigned long trampoline;
236 unsigned long trampoline_size;
237 struct list_head list;
238#endif
239};
240
241extern struct ftrace_ops __rcu *ftrace_ops_list;
242extern struct ftrace_ops ftrace_list_end;
243
244
245
246
247
248
249
250
251
252
253#define do_for_each_ftrace_op(op, list) \
254 op = rcu_dereference_raw_check(list); \
255 do
256
257
258
259
260#define while_for_each_ftrace_op(op) \
261 while (likely(op = rcu_dereference_raw_check((op)->next)) && \
262 unlikely((op) != &ftrace_list_end))
263
264
265
266
267enum ftrace_tracing_type_t {
268 FTRACE_TYPE_ENTER = 0,
269 FTRACE_TYPE_RETURN,
270};
271
272
273extern enum ftrace_tracing_type_t ftrace_tracing_type;
274
275
276
277
278
279
280
281
282int register_ftrace_function(struct ftrace_ops *ops);
283int unregister_ftrace_function(struct ftrace_ops *ops);
284
285extern void ftrace_stub(unsigned long a0, unsigned long a1,
286 struct ftrace_ops *op, struct ftrace_regs *fregs);
287
288#else
289
290
291
292
293#define register_ftrace_function(ops) ({ 0; })
294#define unregister_ftrace_function(ops) ({ 0; })
295static inline void ftrace_kill(void) { }
296static inline void ftrace_free_init_mem(void) { }
297static inline void ftrace_free_mem(struct module *mod, void *start, void *end) { }
298#endif
299
300struct ftrace_func_entry {
301 struct hlist_node hlist;
302 unsigned long ip;
303 unsigned long direct;
304};
305
306struct dyn_ftrace;
307
308#ifdef CONFIG_DYNAMIC_FTRACE_WITH_DIRECT_CALLS
309extern int ftrace_direct_func_count;
310int register_ftrace_direct(unsigned long ip, unsigned long addr);
311int unregister_ftrace_direct(unsigned long ip, unsigned long addr);
312int modify_ftrace_direct(unsigned long ip, unsigned long old_addr, unsigned long new_addr);
313struct ftrace_direct_func *ftrace_find_direct_func(unsigned long addr);
314int ftrace_modify_direct_caller(struct ftrace_func_entry *entry,
315 struct dyn_ftrace *rec,
316 unsigned long old_addr,
317 unsigned long new_addr);
318unsigned long ftrace_find_rec_direct(unsigned long ip);
319#else
320# define ftrace_direct_func_count 0
321static inline int register_ftrace_direct(unsigned long ip, unsigned long addr)
322{
323 return -ENOTSUPP;
324}
325static inline int unregister_ftrace_direct(unsigned long ip, unsigned long addr)
326{
327 return -ENOTSUPP;
328}
329static inline int modify_ftrace_direct(unsigned long ip,
330 unsigned long old_addr, unsigned long new_addr)
331{
332 return -ENOTSUPP;
333}
334static inline struct ftrace_direct_func *ftrace_find_direct_func(unsigned long addr)
335{
336 return NULL;
337}
338static inline int ftrace_modify_direct_caller(struct ftrace_func_entry *entry,
339 struct dyn_ftrace *rec,
340 unsigned long old_addr,
341 unsigned long new_addr)
342{
343 return -ENODEV;
344}
345static inline unsigned long ftrace_find_rec_direct(unsigned long ip)
346{
347 return 0;
348}
349#endif
350
351#ifndef CONFIG_HAVE_DYNAMIC_FTRACE_WITH_DIRECT_CALLS
352
353
354
355
356
357
358
359
360
361
362
363
364
365static inline void arch_ftrace_set_direct_caller(struct pt_regs *regs,
366 unsigned long addr) { }
367#endif
368
369#ifdef CONFIG_STACK_TRACER
370
371extern int stack_tracer_enabled;
372
373int stack_trace_sysctl(struct ctl_table *table, int write, void *buffer,
374 size_t *lenp, loff_t *ppos);
375
376
377DECLARE_PER_CPU(int, disable_stack_tracer);
378
379
380
381
382
383
384
385
386
387
388
389
390static inline void stack_tracer_disable(void)
391{
392
393 if (IS_ENABLED(CONFIG_DEBUG_PREEMPT))
394 WARN_ON_ONCE(!preempt_count() || !irqs_disabled());
395 this_cpu_inc(disable_stack_tracer);
396}
397
398
399
400
401
402
403
404static inline void stack_tracer_enable(void)
405{
406 if (IS_ENABLED(CONFIG_DEBUG_PREEMPT))
407 WARN_ON_ONCE(!preempt_count() || !irqs_disabled());
408 this_cpu_dec(disable_stack_tracer);
409}
410#else
411static inline void stack_tracer_disable(void) { }
412static inline void stack_tracer_enable(void) { }
413#endif
414
415#ifdef CONFIG_DYNAMIC_FTRACE
416
417int ftrace_arch_code_modify_prepare(void);
418int ftrace_arch_code_modify_post_process(void);
419
420enum ftrace_bug_type {
421 FTRACE_BUG_UNKNOWN,
422 FTRACE_BUG_INIT,
423 FTRACE_BUG_NOP,
424 FTRACE_BUG_CALL,
425 FTRACE_BUG_UPDATE,
426};
427extern enum ftrace_bug_type ftrace_bug_type;
428
429
430
431
432
433extern const void *ftrace_expected;
434
435void ftrace_bug(int err, struct dyn_ftrace *rec);
436
437struct seq_file;
438
439extern int ftrace_text_reserved(const void *start, const void *end);
440
441struct ftrace_ops *ftrace_ops_trampoline(unsigned long addr);
442
443bool is_ftrace_trampoline(unsigned long addr);
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465enum {
466 FTRACE_FL_ENABLED = (1UL << 31),
467 FTRACE_FL_REGS = (1UL << 30),
468 FTRACE_FL_REGS_EN = (1UL << 29),
469 FTRACE_FL_TRAMP = (1UL << 28),
470 FTRACE_FL_TRAMP_EN = (1UL << 27),
471 FTRACE_FL_IPMODIFY = (1UL << 26),
472 FTRACE_FL_DISABLED = (1UL << 25),
473 FTRACE_FL_DIRECT = (1UL << 24),
474 FTRACE_FL_DIRECT_EN = (1UL << 23),
475};
476
477#define FTRACE_REF_MAX_SHIFT 23
478#define FTRACE_REF_MAX ((1UL << FTRACE_REF_MAX_SHIFT) - 1)
479
480#define ftrace_rec_count(rec) ((rec)->flags & FTRACE_REF_MAX)
481
482struct dyn_ftrace {
483 unsigned long ip;
484 unsigned long flags;
485 struct dyn_arch_ftrace arch;
486};
487
488int ftrace_set_filter_ip(struct ftrace_ops *ops, unsigned long ip,
489 int remove, int reset);
490int ftrace_set_filter(struct ftrace_ops *ops, unsigned char *buf,
491 int len, int reset);
492int ftrace_set_notrace(struct ftrace_ops *ops, unsigned char *buf,
493 int len, int reset);
494void ftrace_set_global_filter(unsigned char *buf, int len, int reset);
495void ftrace_set_global_notrace(unsigned char *buf, int len, int reset);
496void ftrace_free_filter(struct ftrace_ops *ops);
497void ftrace_ops_set_global_filter(struct ftrace_ops *ops);
498
499enum {
500 FTRACE_UPDATE_CALLS = (1 << 0),
501 FTRACE_DISABLE_CALLS = (1 << 1),
502 FTRACE_UPDATE_TRACE_FUNC = (1 << 2),
503 FTRACE_START_FUNC_RET = (1 << 3),
504 FTRACE_STOP_FUNC_RET = (1 << 4),
505 FTRACE_MAY_SLEEP = (1 << 5),
506};
507
508
509
510
511
512
513
514
515
516
517
518
519enum {
520 FTRACE_UPDATE_IGNORE,
521 FTRACE_UPDATE_MAKE_CALL,
522 FTRACE_UPDATE_MODIFY_CALL,
523 FTRACE_UPDATE_MAKE_NOP,
524};
525
526enum {
527 FTRACE_ITER_FILTER = (1 << 0),
528 FTRACE_ITER_NOTRACE = (1 << 1),
529 FTRACE_ITER_PRINTALL = (1 << 2),
530 FTRACE_ITER_DO_PROBES = (1 << 3),
531 FTRACE_ITER_PROBE = (1 << 4),
532 FTRACE_ITER_MOD = (1 << 5),
533 FTRACE_ITER_ENABLED = (1 << 6),
534};
535
536void arch_ftrace_update_code(int command);
537void arch_ftrace_update_trampoline(struct ftrace_ops *ops);
538void *arch_ftrace_trampoline_func(struct ftrace_ops *ops, struct dyn_ftrace *rec);
539void arch_ftrace_trampoline_free(struct ftrace_ops *ops);
540
541struct ftrace_rec_iter;
542
543struct ftrace_rec_iter *ftrace_rec_iter_start(void);
544struct ftrace_rec_iter *ftrace_rec_iter_next(struct ftrace_rec_iter *iter);
545struct dyn_ftrace *ftrace_rec_iter_record(struct ftrace_rec_iter *iter);
546
547#define for_ftrace_rec_iter(iter) \
548 for (iter = ftrace_rec_iter_start(); \
549 iter; \
550 iter = ftrace_rec_iter_next(iter))
551
552
553int ftrace_update_record(struct dyn_ftrace *rec, bool enable);
554int ftrace_test_record(struct dyn_ftrace *rec, bool enable);
555void ftrace_run_stop_machine(int command);
556unsigned long ftrace_location(unsigned long ip);
557unsigned long ftrace_location_range(unsigned long start, unsigned long end);
558unsigned long ftrace_get_addr_new(struct dyn_ftrace *rec);
559unsigned long ftrace_get_addr_curr(struct dyn_ftrace *rec);
560
561extern ftrace_func_t ftrace_trace_function;
562
563int ftrace_regex_open(struct ftrace_ops *ops, int flag,
564 struct inode *inode, struct file *file);
565ssize_t ftrace_filter_write(struct file *file, const char __user *ubuf,
566 size_t cnt, loff_t *ppos);
567ssize_t ftrace_notrace_write(struct file *file, const char __user *ubuf,
568 size_t cnt, loff_t *ppos);
569int ftrace_regex_release(struct inode *inode, struct file *file);
570
571void __init
572ftrace_set_early_filter(struct ftrace_ops *ops, char *buf, int enable);
573
574
575extern int ftrace_ip_converted(unsigned long ip);
576extern int ftrace_dyn_arch_init(void);
577extern void ftrace_replace_code(int enable);
578extern int ftrace_update_ftrace_func(ftrace_func_t func);
579extern void ftrace_caller(void);
580extern void ftrace_regs_caller(void);
581extern void ftrace_call(void);
582extern void ftrace_regs_call(void);
583extern void mcount_call(void);
584
585void ftrace_modify_all_code(int command);
586
587#ifndef FTRACE_ADDR
588#define FTRACE_ADDR ((unsigned long)ftrace_caller)
589#endif
590
591#ifndef FTRACE_GRAPH_ADDR
592#define FTRACE_GRAPH_ADDR ((unsigned long)ftrace_graph_caller)
593#endif
594
595#ifndef FTRACE_REGS_ADDR
596#ifdef CONFIG_DYNAMIC_FTRACE_WITH_REGS
597# define FTRACE_REGS_ADDR ((unsigned long)ftrace_regs_caller)
598#else
599# define FTRACE_REGS_ADDR FTRACE_ADDR
600#endif
601#endif
602
603
604
605
606
607
608
609#ifndef FTRACE_GRAPH_TRAMP_ADDR
610#define FTRACE_GRAPH_TRAMP_ADDR ((unsigned long) 0)
611#endif
612
613#ifdef CONFIG_FUNCTION_GRAPH_TRACER
614extern void ftrace_graph_caller(void);
615extern int ftrace_enable_ftrace_graph_caller(void);
616extern int ftrace_disable_ftrace_graph_caller(void);
617#else
618static inline int ftrace_enable_ftrace_graph_caller(void) { return 0; }
619static inline int ftrace_disable_ftrace_graph_caller(void) { return 0; }
620#endif
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643extern int ftrace_make_nop(struct module *mod,
644 struct dyn_ftrace *rec, unsigned long addr);
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668#ifndef ftrace_init_nop
669static inline int ftrace_init_nop(struct module *mod, struct dyn_ftrace *rec)
670{
671 return ftrace_make_nop(mod, rec, MCOUNT_ADDR);
672}
673#endif
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695extern int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr);
696
697#ifdef CONFIG_DYNAMIC_FTRACE_WITH_REGS
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719extern int ftrace_modify_call(struct dyn_ftrace *rec, unsigned long old_addr,
720 unsigned long addr);
721#else
722
723static inline int ftrace_modify_call(struct dyn_ftrace *rec, unsigned long old_addr,
724 unsigned long addr)
725{
726 return -EINVAL;
727}
728#endif
729
730
731extern int ftrace_arch_read_dyn_info(char *buf, int size);
732
733extern int skip_trace(unsigned long ip);
734extern void ftrace_module_init(struct module *mod);
735extern void ftrace_module_enable(struct module *mod);
736extern void ftrace_release_mod(struct module *mod);
737
738extern void ftrace_disable_daemon(void);
739extern void ftrace_enable_daemon(void);
740#else
741static inline int skip_trace(unsigned long ip) { return 0; }
742static inline void ftrace_disable_daemon(void) { }
743static inline void ftrace_enable_daemon(void) { }
744static inline void ftrace_module_init(struct module *mod) { }
745static inline void ftrace_module_enable(struct module *mod) { }
746static inline void ftrace_release_mod(struct module *mod) { }
747static inline int ftrace_text_reserved(const void *start, const void *end)
748{
749 return 0;
750}
751static inline unsigned long ftrace_location(unsigned long ip)
752{
753 return 0;
754}
755
756
757
758
759
760
761#define ftrace_regex_open(ops, flag, inod, file) ({ -ENODEV; })
762#define ftrace_set_early_filter(ops, buf, enable) do { } while (0)
763#define ftrace_set_filter_ip(ops, ip, remove, reset) ({ -ENODEV; })
764#define ftrace_set_filter(ops, buf, len, reset) ({ -ENODEV; })
765#define ftrace_set_notrace(ops, buf, len, reset) ({ -ENODEV; })
766#define ftrace_free_filter(ops) do { } while (0)
767#define ftrace_ops_set_global_filter(ops) do { } while (0)
768
769static inline ssize_t ftrace_filter_write(struct file *file, const char __user *ubuf,
770 size_t cnt, loff_t *ppos) { return -ENODEV; }
771static inline ssize_t ftrace_notrace_write(struct file *file, const char __user *ubuf,
772 size_t cnt, loff_t *ppos) { return -ENODEV; }
773static inline int
774ftrace_regex_release(struct inode *inode, struct file *file) { return -ENODEV; }
775
776static inline bool is_ftrace_trampoline(unsigned long addr)
777{
778 return false;
779}
780#endif
781
782
783void ftrace_kill(void);
784
785static inline void tracer_disable(void)
786{
787#ifdef CONFIG_FUNCTION_TRACER
788 ftrace_enabled = 0;
789#endif
790}
791
792
793
794
795
796
797static inline int __ftrace_enabled_save(void)
798{
799#ifdef CONFIG_FUNCTION_TRACER
800 int saved_ftrace_enabled = ftrace_enabled;
801 ftrace_enabled = 0;
802 return saved_ftrace_enabled;
803#else
804 return 0;
805#endif
806}
807
808static inline void __ftrace_enabled_restore(int enabled)
809{
810#ifdef CONFIG_FUNCTION_TRACER
811 ftrace_enabled = enabled;
812#endif
813}
814
815
816#ifndef ftrace_return_address0
817# define ftrace_return_address0 __builtin_return_address(0)
818#endif
819
820
821#ifndef ftrace_return_address
822# ifdef CONFIG_FRAME_POINTER
823# define ftrace_return_address(n) __builtin_return_address(n)
824# else
825# define ftrace_return_address(n) 0UL
826# endif
827#endif
828
829#define CALLER_ADDR0 ((unsigned long)ftrace_return_address0)
830#define CALLER_ADDR1 ((unsigned long)ftrace_return_address(1))
831#define CALLER_ADDR2 ((unsigned long)ftrace_return_address(2))
832#define CALLER_ADDR3 ((unsigned long)ftrace_return_address(3))
833#define CALLER_ADDR4 ((unsigned long)ftrace_return_address(4))
834#define CALLER_ADDR5 ((unsigned long)ftrace_return_address(5))
835#define CALLER_ADDR6 ((unsigned long)ftrace_return_address(6))
836
837static inline unsigned long get_lock_parent_ip(void)
838{
839 unsigned long addr = CALLER_ADDR0;
840
841 if (!in_lock_functions(addr))
842 return addr;
843 addr = CALLER_ADDR1;
844 if (!in_lock_functions(addr))
845 return addr;
846 return CALLER_ADDR2;
847}
848
849#ifdef CONFIG_TRACE_PREEMPT_TOGGLE
850 extern void trace_preempt_on(unsigned long a0, unsigned long a1);
851 extern void trace_preempt_off(unsigned long a0, unsigned long a1);
852#else
853
854
855
856
857# define trace_preempt_on(a0, a1) do { } while (0)
858# define trace_preempt_off(a0, a1) do { } while (0)
859#endif
860
861#ifdef CONFIG_FTRACE_MCOUNT_RECORD
862extern void ftrace_init(void);
863#ifdef CC_USING_PATCHABLE_FUNCTION_ENTRY
864#define FTRACE_CALLSITE_SECTION "__patchable_function_entries"
865#else
866#define FTRACE_CALLSITE_SECTION "__mcount_loc"
867#endif
868#else
869static inline void ftrace_init(void) { }
870#endif
871
872
873
874
875
876
877struct ftrace_graph_ent {
878 unsigned long func;
879 int depth;
880} __packed;
881
882
883
884
885
886
887struct ftrace_graph_ret {
888 unsigned long func;
889 int depth;
890
891 unsigned int overrun;
892 unsigned long long calltime;
893 unsigned long long rettime;
894} __packed;
895
896
897typedef void (*trace_func_graph_ret_t)(struct ftrace_graph_ret *);
898typedef int (*trace_func_graph_ent_t)(struct ftrace_graph_ent *);
899
900extern int ftrace_graph_entry_stub(struct ftrace_graph_ent *trace);
901
902#ifdef CONFIG_FUNCTION_GRAPH_TRACER
903
904struct fgraph_ops {
905 trace_func_graph_ent_t entryfunc;
906 trace_func_graph_ret_t retfunc;
907};
908
909
910
911
912
913
914struct ftrace_ret_stack {
915 unsigned long ret;
916 unsigned long func;
917 unsigned long long calltime;
918#ifdef CONFIG_FUNCTION_PROFILER
919 unsigned long long subtime;
920#endif
921#ifdef HAVE_FUNCTION_GRAPH_FP_TEST
922 unsigned long fp;
923#endif
924#ifdef HAVE_FUNCTION_GRAPH_RET_ADDR_PTR
925 unsigned long *retp;
926#endif
927};
928
929
930
931
932
933
934extern void return_to_handler(void);
935
936extern int
937function_graph_enter(unsigned long ret, unsigned long func,
938 unsigned long frame_pointer, unsigned long *retp);
939
940struct ftrace_ret_stack *
941ftrace_graph_get_ret_stack(struct task_struct *task, int idx);
942
943unsigned long ftrace_graph_ret_addr(struct task_struct *task, int *idx,
944 unsigned long ret, unsigned long *retp);
945
946
947
948
949
950
951#define __notrace_funcgraph notrace
952
953#define FTRACE_RETFUNC_DEPTH 50
954#define FTRACE_RETSTACK_ALLOC_SIZE 32
955
956extern int register_ftrace_graph(struct fgraph_ops *ops);
957extern void unregister_ftrace_graph(struct fgraph_ops *ops);
958
959extern bool ftrace_graph_is_dead(void);
960extern void ftrace_graph_stop(void);
961
962
963extern trace_func_graph_ret_t ftrace_graph_return;
964extern trace_func_graph_ent_t ftrace_graph_entry;
965
966extern void ftrace_graph_init_task(struct task_struct *t);
967extern void ftrace_graph_exit_task(struct task_struct *t);
968extern void ftrace_graph_init_idle_task(struct task_struct *t, int cpu);
969
970static inline void pause_graph_tracing(void)
971{
972 atomic_inc(¤t->tracing_graph_pause);
973}
974
975static inline void unpause_graph_tracing(void)
976{
977 atomic_dec(¤t->tracing_graph_pause);
978}
979#else
980
981#define __notrace_funcgraph
982
983static inline void ftrace_graph_init_task(struct task_struct *t) { }
984static inline void ftrace_graph_exit_task(struct task_struct *t) { }
985static inline void ftrace_graph_init_idle_task(struct task_struct *t, int cpu) { }
986
987
988#define register_ftrace_graph(ops) ({ -1; })
989#define unregister_ftrace_graph(ops) do { } while (0)
990
991static inline unsigned long
992ftrace_graph_ret_addr(struct task_struct *task, int *idx, unsigned long ret,
993 unsigned long *retp)
994{
995 return ret;
996}
997
998static inline void pause_graph_tracing(void) { }
999static inline void unpause_graph_tracing(void) { }
1000#endif
1001
1002#ifdef CONFIG_TRACING
1003
1004
1005enum {
1006 TSK_TRACE_FL_TRACE_BIT = 0,
1007 TSK_TRACE_FL_GRAPH_BIT = 1,
1008};
1009enum {
1010 TSK_TRACE_FL_TRACE = 1 << TSK_TRACE_FL_TRACE_BIT,
1011 TSK_TRACE_FL_GRAPH = 1 << TSK_TRACE_FL_GRAPH_BIT,
1012};
1013
1014static inline void set_tsk_trace_trace(struct task_struct *tsk)
1015{
1016 set_bit(TSK_TRACE_FL_TRACE_BIT, &tsk->trace);
1017}
1018
1019static inline void clear_tsk_trace_trace(struct task_struct *tsk)
1020{
1021 clear_bit(TSK_TRACE_FL_TRACE_BIT, &tsk->trace);
1022}
1023
1024static inline int test_tsk_trace_trace(struct task_struct *tsk)
1025{
1026 return tsk->trace & TSK_TRACE_FL_TRACE;
1027}
1028
1029static inline void set_tsk_trace_graph(struct task_struct *tsk)
1030{
1031 set_bit(TSK_TRACE_FL_GRAPH_BIT, &tsk->trace);
1032}
1033
1034static inline void clear_tsk_trace_graph(struct task_struct *tsk)
1035{
1036 clear_bit(TSK_TRACE_FL_GRAPH_BIT, &tsk->trace);
1037}
1038
1039static inline int test_tsk_trace_graph(struct task_struct *tsk)
1040{
1041 return tsk->trace & TSK_TRACE_FL_GRAPH;
1042}
1043
1044enum ftrace_dump_mode;
1045
1046extern enum ftrace_dump_mode ftrace_dump_on_oops;
1047extern int tracepoint_printk;
1048
1049extern void disable_trace_on_warning(void);
1050extern int __disable_trace_on_warning;
1051
1052int tracepoint_printk_sysctl(struct ctl_table *table, int write,
1053 void *buffer, size_t *lenp, loff_t *ppos);
1054
1055#else
1056static inline void disable_trace_on_warning(void) { }
1057#endif
1058
1059#ifdef CONFIG_FTRACE_SYSCALLS
1060
1061unsigned long arch_syscall_addr(int nr);
1062
1063#endif
1064
1065#endif
1066