Update /debug/tracing/README
[safe/jmp/linux-2.6] / kernel / trace / trace.c
index 6bad128..9d28476 100644 (file)
@@ -30,6 +30,7 @@
 #include <linux/percpu.h>
 #include <linux/splice.h>
 #include <linux/kdebug.h>
+#include <linux/string.h>
 #include <linux/ctype.h>
 #include <linux/init.h>
 #include <linux/poll.h>
@@ -147,8 +148,7 @@ static int __init set_ftrace_dump_on_oops(char *str)
 }
 __setup("ftrace_dump_on_oops", set_ftrace_dump_on_oops);
 
-long
-ns2usecs(cycle_t nsec)
+unsigned long long ns2usecs(cycle_t nsec)
 {
        nsec += 500;
        do_div(nsec, 1000);
@@ -255,7 +255,7 @@ static DECLARE_WAIT_QUEUE_HEAD(trace_wait);
 
 /* trace_flags holds trace_options default values */
 unsigned long trace_flags = TRACE_ITER_PRINT_PARENT | TRACE_ITER_PRINTK |
-       TRACE_ITER_ANNOTATE | TRACE_ITER_CONTEXT_INFO;
+       TRACE_ITER_ANNOTATE | TRACE_ITER_CONTEXT_INFO | TRACE_ITER_SLEEP_TIME;
 
 /**
  * trace_wake_up - wake up tasks waiting for trace input
@@ -316,6 +316,7 @@ static const char *trace_options[] = {
        "context-info",
        "latency-format",
        "global-clock",
+       "sleep-time",
        NULL
 };
 
@@ -382,7 +383,7 @@ ssize_t trace_seq_to_user(struct trace_seq *s, char __user *ubuf, size_t cnt)
        return cnt;
 }
 
-ssize_t trace_seq_to_buffer(struct trace_seq *s, void *buf, size_t cnt)
+static ssize_t trace_seq_to_buffer(struct trace_seq *s, void *buf, size_t cnt)
 {
        int len;
        void *ret;
@@ -924,7 +925,7 @@ trace_function(struct trace_array *tr,
 }
 
 #ifdef CONFIG_FUNCTION_GRAPH_TRACER
-static void __trace_graph_entry(struct trace_array *tr,
+static int __trace_graph_entry(struct trace_array *tr,
                                struct ftrace_graph_ent *trace,
                                unsigned long flags,
                                int pc)
@@ -933,15 +934,17 @@ static void __trace_graph_entry(struct trace_array *tr,
        struct ftrace_graph_ent_entry *entry;
 
        if (unlikely(local_read(&__get_cpu_var(ftrace_cpu_disabled))))
-               return;
+               return 0;
 
        event = trace_buffer_lock_reserve(&global_trace, TRACE_GRAPH_ENT,
                                          sizeof(*entry), flags, pc);
        if (!event)
-               return;
+               return 0;
        entry   = ring_buffer_event_data(event);
        entry->graph_ent                        = *trace;
        ring_buffer_unlock_commit(global_trace.buffer, event);
+
+       return 1;
 }
 
 static void __trace_graph_return(struct trace_array *tr,
@@ -1162,6 +1165,7 @@ int trace_graph_entry(struct ftrace_graph_ent *trace)
        struct trace_array_cpu *data;
        unsigned long flags;
        long disabled;
+       int ret;
        int cpu;
        int pc;
 
@@ -1177,15 +1181,18 @@ int trace_graph_entry(struct ftrace_graph_ent *trace)
        disabled = atomic_inc_return(&data->disabled);
        if (likely(disabled == 1)) {
                pc = preempt_count();
-               __trace_graph_entry(tr, trace, flags, pc);
+               ret = __trace_graph_entry(tr, trace, flags, pc);
+       } else {
+               ret = 0;
        }
        /* Only do the atomic if it is not already set */
        if (!test_tsk_trace_graph(current))
                set_tsk_trace_graph(current);
+
        atomic_dec(&data->disabled);
        local_irq_restore(flags);
 
-       return 1;
+       return ret;
 }
 
 void trace_graph_return(struct ftrace_graph_ret *trace)
@@ -1625,7 +1632,11 @@ static void test_cpu_buff_start(struct trace_iterator *iter)
                return;
 
        cpumask_set_cpu(iter->cpu, iter->started);
-       trace_seq_printf(s, "##### CPU %u buffer started ####\n", iter->cpu);
+
+       /* Don't print started cpu buffer for the first entry of the trace */
+       if (iter->idx > 1)
+               trace_seq_printf(s, "##### CPU %u buffer started ####\n",
+                               iter->cpu);
 }
 
 static enum print_line_t print_trace_fmt(struct trace_iterator *iter)
@@ -1860,6 +1871,11 @@ __tracing_open(struct inode *inode, struct file *file)
        if (current_trace)
                *iter->trace = *current_trace;
 
+       if (!alloc_cpumask_var(&iter->started, GFP_KERNEL))
+               goto fail;
+
+       cpumask_clear(iter->started);
+
        if (current_trace && current_trace->print_max)
                iter->tr = &max_tr;
        else
@@ -1910,6 +1926,7 @@ __tracing_open(struct inode *inode, struct file *file)
                if (iter->buffer_iter[cpu])
                        ring_buffer_read_finish(iter->buffer_iter[cpu]);
        }
+       free_cpumask_var(iter->started);
  fail:
        mutex_unlock(&trace_types_lock);
        kfree(iter->trace);
@@ -1953,6 +1970,7 @@ static int tracing_release(struct inode *inode, struct file *file)
 
        seq_release(inode, file);
        mutex_destroy(&iter->mutex);
+       free_cpumask_var(iter->started);
        kfree(iter->trace);
        kfree(iter);
        return 0;
@@ -2351,9 +2369,9 @@ static const char readme_msg[] =
        "# mkdir /debug\n"
        "# mount -t debugfs nodev /debug\n\n"
        "# cat /debug/tracing/available_tracers\n"
-       "wakeup preemptirqsoff preemptoff irqsoff ftrace sched_switch none\n\n"
+       "wakeup preemptirqsoff preemptoff irqsoff function sched_switch nop\n\n"
        "# cat /debug/tracing/current_tracer\n"
-       "none\n"
+       "nop\n"
        "# echo sched_switch > /debug/tracing/current_tracer\n"
        "# cat /debug/tracing/current_tracer\n"
        "sched_switch\n"
@@ -3529,6 +3547,9 @@ struct dentry *tracing_init_dentry(void)
        if (d_tracer)
                return d_tracer;
 
+       if (!debugfs_initialized())
+               return NULL;
+
        d_tracer = debugfs_create_dir("tracing", NULL);
 
        if (!d_tracer && !once) {