Merge branches 'tracing/blktrace', 'tracing/ftrace' and 'tracing/urgent' into tracing...
authorIngo Molnar <mingo@elte.hu>
Thu, 19 Feb 2009 09:20:17 +0000 (10:20 +0100)
committerIngo Molnar <mingo@elte.hu>
Thu, 19 Feb 2009 09:20:17 +0000 (10:20 +0100)
1  2  3 
kernel/trace/Kconfig
kernel/trace/trace_selftest.c

diff --combined kernel/trace/Kconfig
@@@@ -9,9 -9,9 -9,6 +9,9 @@@@ config USER_STACKTRACE_SUPPOR
   config NOP_TRACER
        bool
   
  +config HAVE_FTRACE_NMI_ENTER
  +     bool
  +
   config HAVE_FUNCTION_TRACER
        bool
   
@@@@ -40,11 -40,11 -37,6 +40,11 @@@@ config TRACER_MAX_TRAC
   config RING_BUFFER
        bool
   
  +config FTRACE_NMI_ENTER
  +       bool
  +       depends on HAVE_FTRACE_NMI_ENTER
  +       default y
  +
   config TRACING
        bool
        select DEBUG_FS
@@@@ -60,6 -60,6 -52,7 +60,7 @@@@ config FUNCTION_TRACE
        depends on HAVE_FUNCTION_TRACER
        depends on DEBUG_KERNEL
        select FRAME_POINTER
++      select KALLSYMS
        select TRACING
        select CONTEXT_SWITCH_TRACER
        help
@@@@ -134,7 -134,7 -127,6 +135,7 @@@@ config SYSPROF_TRACE
        bool "Sysprof Tracer"
        depends on X86
        select TRACING
  +     select CONTEXT_SWITCH_TRACER
        help
          This tracer provides the trace needed by the 'Sysprof' userspace
          tool.
@@@@ -173,8 -173,8 -165,9 +174,8 @@@@ config BOOT_TRACE
          representation of the delays during initcalls - but the raw
          /debug/tracing/trace text output is readable too.
   
  -       ( Note that tracing self tests can't be enabled if this tracer is
  -         selected, because the self-tests are an initcall as well and that
  -         would invalidate the boot trace. )
  +       You must pass in ftrace=initcall to the kernel command line
  +       to enable this on bootup.
   
   config TRACE_BRANCH_PROFILING
        bool "Trace likely/unlikely profiler"
@@@@ -246,6 -246,6 -239,7 +247,7 @@@@ config STACK_TRACE
        depends on DEBUG_KERNEL
        select FUNCTION_TRACER
        select STACKTRACE
++      select KALLSYMS
        help
          This special tracer records the maximum stack footprint of the
          kernel and displays it in debugfs/tracing/stack_trace.
@@@@ -272,62 -272,62 -266,6 +274,62 @@@@ config HW_BRANCH_TRACE
          This tracer records all branches on the system in a circular
          buffer giving access to the last N branches for each cpu.
   
  +config KMEMTRACE
  +     bool "Trace SLAB allocations"
  +     select TRACING
  +     help
  +       kmemtrace provides tracing for slab allocator functions, such as
  +       kmalloc, kfree, kmem_cache_alloc, kmem_cache_free etc.. Collected
  +       data is then fed to the userspace application in order to analyse
  +       allocation hotspots, internal fragmentation and so on, making it
  +       possible to see how well an allocator performs, as well as debug
  +       and profile kernel code.
  +
  +       This requires an userspace application to use. See
  +       Documentation/vm/kmemtrace.txt for more information.
  +
  +       Saying Y will make the kernel somewhat larger and slower. However,
  +       if you disable kmemtrace at run-time or boot-time, the performance
  +       impact is minimal (depending on the arch the kernel is built for).
  +
  +       If unsure, say N.
  +
  +config WORKQUEUE_TRACER
  +     bool "Trace workqueues"
  +     select TRACING
  +     help
  +       The workqueue tracer provides some statistical informations
  +          about each cpu workqueue thread such as the number of the
  +          works inserted and executed since their creation. It can help
  +          to evaluate the amount of work each of them have to perform.
  +          For example it can help a developer to decide whether he should
  +          choose a per cpu workqueue instead of a singlethreaded one.
  +
  +config BLK_DEV_IO_TRACE
  +     bool "Support for tracing block io actions"
  +     depends on SYSFS
  +     depends on BLOCK
  +     select RELAY
  +     select DEBUG_FS
  +     select TRACEPOINTS
  +     select TRACING
  +     select STACKTRACE
  +     help
  +       Say Y here if you want to be able to trace the block layer actions
  +       on a given queue. Tracing allows you to see any traffic happening
  +       on a block device queue. For more information (and the userspace
  +       support tools needed), fetch the blktrace tools from:
  +
  +       git://git.kernel.dk/blktrace.git
  +
  +       Tracing also is possible using the ftrace interface, e.g.:
  +
  +         echo 1 > /sys/block/sda/sda1/trace/enable
  +         echo blk > /sys/kernel/debug/tracing/current_tracer
  +         cat /sys/kernel/debug/tracing/trace_pipe
  +
  +       If unsure, say N.
  +
   config DYNAMIC_FTRACE
        bool "enable/disable ftrace tracepoints dynamically"
        depends on FUNCTION_TRACER
@@@@ -358,7 -358,7 -296,7 +360,7 @@@@ config FTRACE_SELFTES
   
   config FTRACE_STARTUP_TEST
        bool "Perform a startup test on ftrace"
  -     depends on TRACING && DEBUG_KERNEL && !BOOT_TRACER
  +     depends on TRACING && DEBUG_KERNEL
        select FTRACE_SELFTEST
        help
          This option performs a series of startup tests on ftrace. On bootup
@@@@ -9,12 -9,12 -9,11 +9,12 @@@@ static inline int trace_valid_entry(str
        case TRACE_FN:
        case TRACE_CTX:
        case TRACE_WAKE:
  -     case TRACE_CONT:
        case TRACE_STACK:
        case TRACE_PRINT:
        case TRACE_SPECIAL:
        case TRACE_BRANCH:
  +     case TRACE_GRAPH_ENT:
  +     case TRACE_GRAPH_RET:
                return 1;
        }
        return 0;
@@@@ -24,10 -24,10 -23,20 +24,20 @@@@ static int trace_test_buffer_cpu(struc
   {
        struct ring_buffer_event *event;
        struct trace_entry *entry;
++      unsigned int loops = 0;
   
        while ((event = ring_buffer_consume(tr->buffer, cpu, NULL))) {
                entry = ring_buffer_event_data(event);
   
++              /*
++               * The ring buffer is a size of trace_buf_size, if
++               * we loop more than the size, there's something wrong
++               * with the ring buffer.
++               */
++              if (loops++ > trace_buf_size) {
++                      printk(KERN_CONT ".. bad ring buffer ");
++                      goto failed;
++              }
                if (!trace_valid_entry(entry)) {
                        printk(KERN_CONT ".. invalid entry %d ",
                                entry->type);
@@@@ -58,11 -58,11 -67,20 +68,20 @@@@ static int trace_test_buffer(struct tra
   
        cnt = ring_buffer_entries(tr->buffer);
   
++      /*
++       * The trace_test_buffer_cpu runs a while loop to consume all data.
++       * If the calling tracer is broken, and is constantly filling
++       * the buffer, this will run forever, and hard lock the box.
++       * We disable the ring buffer while we do this test to prevent
++       * a hard lock up.
++       */
++      tracing_off();
        for_each_possible_cpu(cpu) {
                ret = trace_test_buffer_cpu(tr, cpu);
                if (ret)
                        break;
        }
++      tracing_on();
        __raw_spin_unlock(&ftrace_max_lock);
        local_irq_restore(flags);
   
@@@@ -107,9 -107,9 -125,9 +126,9 @@@@ int trace_selftest_startup_dynamic_trac
        func();
   
        /*
- -      * Some archs *cough*PowerPC*cough* add charachters to the
+ +      * Some archs *cough*PowerPC*cough* add characters to the
         * start of the function names. We simply put a '*' to
- -      * accomodate them.
+ +      * accommodate them.
         */
        func_name = "*" STR(DYN_FTRACE_TEST_NAME);
   
        ftrace_set_filter(func_name, strlen(func_name), 1);
   
        /* enable tracing */
  -     ret = trace->init(tr);
  +     ret = tracer_init(trace, tr);
        if (ret) {
                warn_failed_init_tracer(trace, ret);
                goto out;
@@@@ -191,7 -191,7 -209,7 +210,7 @@@@ trace_selftest_startup_function(struct 
        ftrace_enabled = 1;
        tracer_enabled = 1;
   
  -     ret = trace->init(tr);
  +     ret = tracer_init(trace, tr);
        if (ret) {
                warn_failed_init_tracer(trace, ret);
                goto out;
   }
   #endif /* CONFIG_FUNCTION_TRACER */
   
  +
  +#ifdef CONFIG_FUNCTION_GRAPH_TRACER
  +/*
  + * Pretty much the same than for the function tracer from which the selftest
  + * has been borrowed.
  + */
  +int
  +trace_selftest_startup_function_graph(struct tracer *trace,
  +                                     struct trace_array *tr)
  +{
  +     int ret;
  +     unsigned long count;
  +
  +     ret = tracer_init(trace, tr);
  +     if (ret) {
  +             warn_failed_init_tracer(trace, ret);
  +             goto out;
  +     }
  +
  +     /* Sleep for a 1/10 of a second */
  +     msleep(100);
  +
  +     tracing_stop();
  +
  +     /* check the trace buffer */
  +     ret = trace_test_buffer(tr, &count);
  +
  +     trace->reset(tr);
  +     tracing_start();
  +
  +     if (!ret && !count) {
  +             printk(KERN_CONT ".. no entries found ..");
  +             ret = -1;
  +             goto out;
  +     }
  +
  +     /* Don't test dynamic tracing, the function tracer already did */
  +
  +out:
  +     /* Stop it if we failed */
  +     if (ret)
  +             ftrace_graph_stop();
  +
  +     return ret;
  +}
  +#endif /* CONFIG_FUNCTION_GRAPH_TRACER */
  +
  +
   #ifdef CONFIG_IRQSOFF_TRACER
   int
   trace_selftest_startup_irqsoff(struct tracer *trace, struct trace_array *tr)
        int ret;
   
        /* start the tracing */
  -     ret = trace->init(tr);
  +     ret = tracer_init(trace, tr);
        if (ret) {
                warn_failed_init_tracer(trace, ret);
                return ret;
@@@@ -340,7 -340,7 -310,7 +359,7 @@@@ trace_selftest_startup_preemptoff(struc
        }
   
        /* start the tracing */
  -     ret = trace->init(tr);
  +     ret = tracer_init(trace, tr);
        if (ret) {
                warn_failed_init_tracer(trace, ret);
                return ret;
@@@@ -394,7 -394,7 -364,7 +413,7 @@@@ trace_selftest_startup_preemptirqsoff(s
        }
   
        /* start the tracing */
  -     ret = trace->init(tr);
  +     ret = tracer_init(trace, tr);
        if (ret) {
                warn_failed_init_tracer(trace, ret);
                goto out;
@@@@ -526,7 -526,7 -496,7 +545,7 @@@@ trace_selftest_startup_wakeup(struct tr
        wait_for_completion(&isrt);
   
        /* start the tracing */
  -     ret = trace->init(tr);
  +     ret = tracer_init(trace, tr);
        if (ret) {
                warn_failed_init_tracer(trace, ret);
                return ret;
@@@@ -587,7 -587,7 -557,7 +606,7 @@@@ trace_selftest_startup_sched_switch(str
        int ret;
   
        /* start the tracing */
  -     ret = trace->init(tr);
  +     ret = tracer_init(trace, tr);
        if (ret) {
                warn_failed_init_tracer(trace, ret);
                return ret;
@@@@ -619,10 -619,10 -589,10 +638,10 @@@@ trace_selftest_startup_sysprof(struct t
        int ret;
   
        /* start the tracing */
  -     ret = trace->init(tr);
  +     ret = tracer_init(trace, tr);
        if (ret) {
                warn_failed_init_tracer(trace, ret);
- -             return 0;
+ +             return ret;
        }
   
        /* Sleep for a 1/10 of a second */
        trace->reset(tr);
        tracing_start();
   
+ +     if (!ret && !count) {
+ +             printk(KERN_CONT ".. no entries found ..");
+ +             ret = -1;
+ +     }
+ +
        return ret;
   }
   #endif /* CONFIG_SYSPROF_TRACER */
@@@@ -646,7 -651,7 -616,7 +670,7 @@@@ trace_selftest_startup_branch(struct tr
        int ret;
   
        /* start the tracing */
  -     ret = trace->init(tr);
  +     ret = tracer_init(trace, tr);
        if (ret) {
                warn_failed_init_tracer(trace, ret);
                return ret;
        trace->reset(tr);
        tracing_start();
   
+ +     if (!ret && !count) {
+ +             printk(KERN_CONT ".. no entries found ..");
+ +             ret = -1;
+ +     }
+ +
        return ret;
   }
   #endif /* CONFIG_BRANCH_TRACER */