Merge branches 'tracing/branch-tracer', 'tracing/fastboot', 'tracing/ftrace', 'tracin...
authorIngo Molnar <mingo@elte.hu>
Mon, 24 Nov 2008 16:46:24 +0000 (17:46 +0100)
committerIngo Molnar <mingo@elte.hu>
Mon, 24 Nov 2008 16:46:24 +0000 (17:46 +0100)
1  2  3  4  5  6  7  8  9 
include/linux/ftrace.h
kernel/trace/Kconfig
kernel/trace/trace.c
kernel/trace/trace_mmiotrace.c

index f7ba4ea5e128dca40746569fb580965cd12f9faf,f7ba4ea5e128dca40746569fb580965cd12f9faf,13e9cfc099282e0bb3439e15d3a5556b25ed45d7,938ca194264128706fdd6ac48c2fda16c3635476,f7ba4ea5e128dca40746569fb580965cd12f9faf,703eb53cfa2b2a1512b7ce97d9c1da218ad9ac0f,f7ba4ea5e128dca40746569fb580965cd12f9faf,f7ba4ea5e128dca40746569fb580965cd12f9faf,703eb53cfa2b2a1512b7ce97d9c1da218ad9ac0f..7854d87b97b20332040354f085002f9053f36e9a
@@@@@@@@@@ -253,11 -253,11 -253,12 -253,11 -253,11 -181,6 -253,11 -253,11 -181,6 +253,12 @@@@@@@@@@ static inline void __ftrace_enabled_res
         #endif
         
         #ifdef CONFIG_TRACING
     +  +extern int ftrace_dump_on_oops;
     +  +
     +  +extern void tracing_start(void);
     +  +extern void tracing_stop(void);
++ ++++++extern void ftrace_off_permanent(void);
     +  +
         extern void
         ftrace_special(unsigned long arg1, unsigned long arg2, unsigned long arg3);
         
@@@@@@@@@@ -288,8 -288,8 -289,9 -288,8 -288,8 -211,6 -288,8 -288,8 -211,6 +289,9 @@@@@@@@@@ ftrace_special(unsigned long arg1, unsi
         static inline int
         ftrace_printk(const char *fmt, ...) __attribute__ ((format (printf, 1, 0)));
         
     +  +static inline void tracing_start(void) { }
     +  +static inline void tracing_stop(void) { }
++ ++++++static inline void ftrace_off_permanent(void) { }
         static inline int
         ftrace_printk(const char *fmt, ...)
         {
@@@@@@@@@@ -310,26 -310,26 -312,26 -310,34 -310,26 -229,25 -310,26 -310,26 -229,25 +312,34 @@@@@@@@@@ ftrace_init_module(struct module *mod
         #endif
         
         
     -  -struct boot_trace {
     -  -       pid_t                   caller;
     -  -       char                    func[KSYM_NAME_LEN];
     -  -       int                     result;
     -  -       unsigned long long      duration;               /* usecs */
     -  -       ktime_t                 calltime;
     -  -       ktime_t                 rettime;
     +  +/*
     +  + * Structure that defines a return function trace.
     +  + */
     +  +struct ftrace_retfunc {
     +  +       unsigned long ret; /* Return address */
     +  +       unsigned long func; /* Current function */
     +  +       unsigned long long calltime;
     +  +       unsigned long long rettime;
     +  +       /* Number of functions that overran the depth limit for current task */
     +  +       unsigned long overrun;
         };
         
     -  -#ifdef CONFIG_BOOT_TRACER
     -  -extern void trace_boot(struct boot_trace *it, initcall_t fn);
     -  -extern void start_boot_trace(void);
     -  -extern void stop_boot_trace(void);
     -  -#else
     -  -static inline void trace_boot(struct boot_trace *it, initcall_t fn) { }
     -  -static inline void start_boot_trace(void) { }
     -  -static inline void stop_boot_trace(void) { }
     -  -#endif
     +  +#ifdef CONFIG_FUNCTION_RET_TRACER
+++ +++++#define FTRACE_RETFUNC_DEPTH 50
+++ +++++#define FTRACE_RETSTACK_ALLOC_SIZE 32
     +  +/* Type of a callback handler of tracing return function */
     +  +typedef void (*trace_function_return_t)(struct ftrace_retfunc *);
         
     +  +extern int register_ftrace_return(trace_function_return_t func);
     +  +/* The current handler in use */
     +  +extern trace_function_return_t ftrace_function_return;
     +  +extern void unregister_ftrace_return(void);
+++ + ++ 
+++ +++++extern void ftrace_retfunc_init_task(struct task_struct *t);
+++ +++++extern void ftrace_retfunc_exit_task(struct task_struct *t);
+++ +++++#else
+++ +++++static inline void ftrace_retfunc_init_task(struct task_struct *t) { }
+++ +++++static inline void ftrace_retfunc_exit_task(struct task_struct *t) { }
     +  +#endif
         
         #endif /* _LINUX_FTRACE_H */
index 61e8cca6ff456dece688660caee325b124dccd98,b8378fad29a36602e951d6d0d59afbec5a357aa8,b8378fad29a36602e951d6d0d59afbec5a357aa8,b8378fad29a36602e951d6d0d59afbec5a357aa8,b8378fad29a36602e951d6d0d59afbec5a357aa8,33dbefd471e88f9571f299f92b433188dd6697de,b8378fad29a36602e951d6d0d59afbec5a357aa8,87fc34a1bb912b2ffe2eb5dd23ccf24d1c78fb76,33dbefd471e88f9571f299f92b433188dd6697de..9cbf7761f498db3e12819f359f77ef9a8b47e90a
@@@@@@@@@@ -158,59 -158,44 -158,44 -158,44 -158,44 -138,6 -158,44 -161,44 -138,6 +161,59 @@@@@@@@@@ config BOOT_TRACE
                    selected, because the self-tests are an initcall as well and that
                    would invalidate the boot trace. )
         
 ---- --          /debugfs/tracing/profile_likely
 ---- --          /debugfs/tracing/profile_unlikely
     +  +config TRACE_BRANCH_PROFILING
     +  +       bool "Trace likely/unlikely profiler"
     +  +       depends on DEBUG_KERNEL
     +  +       select TRACING
     +  +       help
     +  +         This tracer profiles all the the likely and unlikely macros
     +  +         in the kernel. It will display the results in:
     +  +
 ++++++++         /debugfs/tracing/profile_annotated_branch
     +  +
     +  +         Note: this will add a significant overhead, only turn this
     +  +         on if you need to profile the system's use of these macros.
     +  +
     +  +         Say N if unsure.
     +  +
 ++++++++config PROFILE_ALL_BRANCHES
 ++++++++       bool "Profile all if conditionals"
 ++++++++       depends on TRACE_BRANCH_PROFILING
 ++++++++       help
 ++++++++         This tracer profiles all branch conditions. Every if ()
 ++++++++         taken in the kernel is recorded whether it hit or miss.
 ++++++++         The results will be displayed in:
 ++++++++
 ++++++++         /debugfs/tracing/profile_branch
 ++++++++
 ++++++++         This configuration, when enabled, will impose a great overhead
 ++++++++         on the system. This should only be enabled when the system
 ++++++++         is to be analyzed
 ++++++++
 ++++++++         Say N if unsure.
 ++++++++
     +  +config TRACING_BRANCHES
     +  +       bool
     +  +       help
     +  +         Selected by tracers that will trace the likely and unlikely
     +  +         conditions. This prevents the tracers themselves from being
     +  +         profiled. Profiling the tracing infrastructure can only happen
     +  +         when the likelys and unlikelys are not being traced.
     +  +
     +  +config BRANCH_TRACER
     +  +       bool "Trace likely/unlikely instances"
     +  +       depends on TRACE_BRANCH_PROFILING
     +  +       select TRACING_BRANCHES
     +  +       help
     +  +         This traces the events of likely and unlikely condition
     +  +         calls in the kernel.  The difference between this and the
     +  +         "Trace likely/unlikely profiler" is that this is not a
     +  +         histogram of the callers, but actually places the calling
     +  +         events into a running trace buffer to see when and where the
     +  +         events happened, as well as their results.
     +  +
     +  +         Say N if unsure.
     +  +
         config STACK_TRACER
                bool "Trace max stack"
                depends on HAVE_FUNCTION_TRACER
index 4ee6f0375222e5d274a045f3ea6617836dab093c,4ee6f0375222e5d274a045f3ea6617836dab093c,0dbfb23ced97a423f5ae495f7f62cfd25bf6104c,4ee6f0375222e5d274a045f3ea6617836dab093c,4ee6f0375222e5d274a045f3ea6617836dab093c,d86e3252f3000024cfaf31c63ffbee765dafac53,4ee6f0375222e5d274a045f3ea6617836dab093c,48d1536f1ca44c259eb3d4c4d61048061f5313b8,d86e3252f3000024cfaf31c63ffbee765dafac53..a45b59e53fbc240f5cb1d29fb09ae5c0b1cfe62d
@@@@@@@@@@ -272,9 -272,9 -272,9 -272,9 -272,9 -213,6 -272,9 -273,11 -213,6 +273,11 @@@@@@@@@@ static const char *trace_options[] = 
                "stacktrace",
                "sched-tree",
                "ftrace_printk",
     +  +       "ftrace_preempt",
     +  +       "branch",
     +  +       "annotate",
+++++++ +       "userstacktrace",
+++++++ +       "sym-userobj",
                NULL
         };
         
@@@@@@@@@@ -657,76 -657,76 -657,91 -657,76 -657,76 -581,6 -657,76 -682,76 -581,6 +682,91 @@@@@@@@@@ static void trace_init_cmdlines(void
                cmdline_idx = 0;
         }
         
     +  +static int trace_stop_count;
     +  +static DEFINE_SPINLOCK(tracing_start_lock);
     +  +
++ ++++++/**
++ ++++++ * ftrace_off_permanent - disable all ftrace code permanently
++ ++++++ *
++ ++++++ * This should only be called when a serious anomally has
++ ++++++ * been detected.  This will turn off the function tracing,
++ ++++++ * ring buffers, and other tracing utilites. It takes no
++ ++++++ * locks and can be called from any context.
++ ++++++ */
++ ++++++void ftrace_off_permanent(void)
++ ++++++{
++ ++++++       tracing_disabled = 1;
++ ++++++       ftrace_stop();
++ ++++++       tracing_off_permanent();
++ ++++++}
++ ++++++
     +  +/**
     +  + * tracing_start - quick start of the tracer
     +  + *
     +  + * If tracing is enabled but was stopped by tracing_stop,
     +  + * this will start the tracer back up.
     +  + */
     +  +void tracing_start(void)
     +  +{
     +  +       struct ring_buffer *buffer;
     +  +       unsigned long flags;
     +  +
     +  +       if (tracing_disabled)
     +  +               return;
     +  +
     +  +       spin_lock_irqsave(&tracing_start_lock, flags);
     +  +       if (--trace_stop_count)
     +  +               goto out;
     +  +
     +  +       if (trace_stop_count < 0) {
     +  +               /* Someone screwed up their debugging */
     +  +               WARN_ON_ONCE(1);
     +  +               trace_stop_count = 0;
     +  +               goto out;
     +  +       }
     +  +
     +  +
     +  +       buffer = global_trace.buffer;
     +  +       if (buffer)
     +  +               ring_buffer_record_enable(buffer);
     +  +
     +  +       buffer = max_tr.buffer;
     +  +       if (buffer)
     +  +               ring_buffer_record_enable(buffer);
     +  +
     +  +       ftrace_start();
     +  + out:
     +  +       spin_unlock_irqrestore(&tracing_start_lock, flags);
     +  +}
     +  +
     +  +/**
     +  + * tracing_stop - quick stop of the tracer
     +  + *
     +  + * Light weight way to stop tracing. Use in conjunction with
     +  + * tracing_start.
     +  + */
     +  +void tracing_stop(void)
     +  +{
     +  +       struct ring_buffer *buffer;
     +  +       unsigned long flags;
     +  +
     +  +       ftrace_stop();
     +  +       spin_lock_irqsave(&tracing_start_lock, flags);
     +  +       if (trace_stop_count++)
     +  +               goto out;
     +  +
     +  +       buffer = global_trace.buffer;
     +  +       if (buffer)
     +  +               ring_buffer_record_disable(buffer);
     +  +
     +  +       buffer = max_tr.buffer;
     +  +       if (buffer)
     +  +               ring_buffer_record_disable(buffer);
     +  +
     +  + out:
     +  +       spin_unlock_irqrestore(&tracing_start_lock, flags);
     +  +}
     +  +
         void trace_stop_cmdline_recording(void);
         
         static void trace_save_cmdline(struct task_struct *tsk)
@@@@@@@@@@ -1690,18 -1690,18 -1705,18 -1690,18 -1690,18 -1448,6 -1690,18 -1829,27 -1448,6 +1844,27 @@@@@@@@@@ print_lat_fmt(struct trace_iterator *it
                                trace_seq_print_cont(s, iter);
                        break;
                }
     +  +       case TRACE_BRANCH: {
     +  +               struct trace_branch *field;
     +  +
     +  +               trace_assign_type(field, entry);
     +  +
     +  +               trace_seq_printf(s, "[%s] %s:%s:%d\n",
     +  +                                field->correct ? "  ok  " : " MISS ",
     +  +                                field->func,
     +  +                                field->file,
     +  +                                field->line);
     +  +               break;
     +  +       }
+++++++ +       case TRACE_USER_STACK: {
+++++++ +               struct userstack_entry *field;
+++++++ +
+++++++ +               trace_assign_type(field, entry);
+++++++ +
+++++++ +               seq_print_userip_objs(field, s, sym_flags);
+++++++ +               trace_seq_putc(s, '\n');
+++++++ +               break;
+++++++ +       }
                default:
                        trace_seq_printf(s, "Unknown type %d\n", entry->type);
                }
@@@@@@@@@@ -1837,22 -1837,22 -1852,22 -1837,22 -1837,22 -1581,6 -1837,22 -1985,35 -1581,6 +2000,35 @@@@@@@@@@ static enum print_line_t print_trace_fm
                                trace_seq_print_cont(s, iter);
                        break;
                }
     +  +       case TRACE_FN_RET: {
     +  +               return print_return_function(iter);
     +  +               break;
     +  +       }
     +  +       case TRACE_BRANCH: {
     +  +               struct trace_branch *field;
     +  +
     +  +               trace_assign_type(field, entry);
     +  +
     +  +               trace_seq_printf(s, "[%s] %s:%s:%d\n",
     +  +                                field->correct ? "  ok  " : " MISS ",
     +  +                                field->func,
     +  +                                field->file,
     +  +                                field->line);
     +  +               break;
     +  +       }
+++++++ +       case TRACE_USER_STACK: {
+++++++ +               struct userstack_entry *field;
+++++++ +
+++++++ +               trace_assign_type(field, entry);
+++++++ +
+++++++ +               ret = seq_print_userip_objs(field, s, sym_flags);
+++++++ +               if (!ret)
+++++++ +                       return TRACE_TYPE_PARTIAL_LINE;
+++++++ +               ret = trace_seq_putc(s, '\n');
+++++++ +               if (!ret)
+++++++ +                       return TRACE_TYPE_PARTIAL_LINE;
+++++++ +               break;
+++++++ +       }
                }
                return TRACE_TYPE_HANDLED;
         }
Simple merge