sched: Eliminate the ts->idle_lastupdate field
[safe/jmp/linux-2.6] / kernel / trace / trace_branch.c
index 4785a3b..b9bc4d4 100644 (file)
 #include <asm/local.h>
 
 #include "trace.h"
+#include "trace_stat.h"
 #include "trace_output.h"
 
-static struct tracer branch_trace;
-
 #ifdef CONFIG_BRANCH_TRACER
 
+static struct tracer branch_trace;
 static int branch_tracing_enabled __read_mostly;
 static DEFINE_MUTEX(branch_tracing_mutex);
 
@@ -30,10 +30,12 @@ static struct trace_array *branch_tracer;
 static void
 probe_likely_condition(struct ftrace_branch_data *f, int val, int expect)
 {
+       struct ftrace_event_call *call = &event_branch;
        struct trace_array *tr = branch_tracer;
        struct ring_buffer_event *event;
        struct trace_branch *entry;
-       unsigned long flags, irq_flags;
+       struct ring_buffer *buffer;
+       unsigned long flags;
        int cpu, pc;
        const char *p;
 
@@ -52,15 +54,14 @@ probe_likely_condition(struct ftrace_branch_data *f, int val, int expect)
        if (atomic_inc_return(&tr->data[cpu]->disabled) != 1)
                goto out;
 
-       event = ring_buffer_lock_reserve(tr->buffer, sizeof(*entry),
-                                        &irq_flags);
+       pc = preempt_count();
+       buffer = tr->buffer;
+       event = trace_buffer_lock_reserve(buffer, TRACE_BRANCH,
+                                         sizeof(*entry), flags, pc);
        if (!event)
                goto out;
 
-       pc = preempt_count();
        entry   = ring_buffer_event_data(event);
-       tracing_generic_entry_update(&entry->ent, flags, pc);
-       entry->ent.type         = TRACE_BRANCH;
 
        /* Strip off the path, only save the file */
        p = f->file + strlen(f->file);
@@ -75,7 +76,8 @@ probe_likely_condition(struct ftrace_branch_data *f, int val, int expect)
        entry->line = f->line;
        entry->correct = val == expect;
 
-       ring_buffer_unlock_commit(tr->buffer, event, irq_flags);
+       if (!filter_check_discard(call, entry, buffer, event))
+               ring_buffer_unlock_commit(buffer, event);
 
  out:
        atomic_dec(&tr->data[cpu]->disabled);
@@ -93,8 +95,6 @@ void trace_likely_condition(struct ftrace_branch_data *f, int val, int expect)
 
 int enable_branch_tracing(struct trace_array *tr)
 {
-       int ret = 0;
-
        mutex_lock(&branch_tracing_mutex);
        branch_tracer = tr;
        /*
@@ -105,7 +105,7 @@ int enable_branch_tracing(struct trace_array *tr)
        branch_tracing_enabled++;
        mutex_unlock(&branch_tracing_mutex);
 
-       return ret;
+       return 0;
 }
 
 void disable_branch_tracing(void)
@@ -133,11 +133,6 @@ static void stop_branch_trace(struct trace_array *tr)
 
 static int branch_trace_init(struct trace_array *tr)
 {
-       int cpu;
-
-       for_each_online_cpu(cpu)
-               tracing_reset(tr, cpu);
-
        start_branch_trace(tr);
        return 0;
 }
@@ -147,50 +142,61 @@ static void branch_trace_reset(struct trace_array *tr)
        stop_branch_trace(tr);
 }
 
-static int
-trace_print_print(struct trace_seq *s, struct trace_entry *entry, int flags)
-{
-       struct print_entry *field;
-
-       trace_assign_type(field, entry);
-
-       if (seq_print_ip_sym(s, field->ip, flags))
-               goto partial;
-
-       if (trace_seq_printf(s, ": %s", field->buf))
-               goto partial;
-
- partial:
-       return TRACE_TYPE_PARTIAL_LINE;
-}
-
-static int
-trace_branch_print(struct trace_seq *s, struct trace_entry *entry, int flags)
+static enum print_line_t trace_branch_print(struct trace_iterator *iter,
+                                           int flags)
 {
        struct trace_branch *field;
 
-       trace_assign_type(field, entry);
+       trace_assign_type(field, iter->ent);
 
-       if (trace_seq_printf(s, "[%s] %s:%s:%d\n",
+       if (trace_seq_printf(&iter->seq, "[%s] %s:%s:%d\n",
                             field->correct ? "  ok  " : " MISS ",
                             field->func,
                             field->file,
                             field->line))
                return TRACE_TYPE_PARTIAL_LINE;
 
-       return 0;
+       return TRACE_TYPE_HANDLED;
 }
 
+static void branch_print_header(struct seq_file *s)
+{
+       seq_puts(s, "#           TASK-PID    CPU#    TIMESTAMP  CORRECT"
+               "  FUNC:FILE:LINE\n");
+       seq_puts(s, "#              | |       |          |         |   "
+               "    |\n");
+}
 
 static struct trace_event trace_branch_event = {
-       .type           = TRACE_BRANCH,
+       .type           = TRACE_BRANCH,
        .trace          = trace_branch_print,
-       .latency_trace  = trace_branch_print,
-       .raw            = trace_nop_print,
-       .hex            = trace_nop_print,
-       .binary         = trace_nop_print,
 };
 
+static struct tracer branch_trace __read_mostly =
+{
+       .name           = "branch",
+       .init           = branch_trace_init,
+       .reset          = branch_trace_reset,
+#ifdef CONFIG_FTRACE_SELFTEST
+       .selftest       = trace_selftest_startup_branch,
+#endif /* CONFIG_FTRACE_SELFTEST */
+       .print_header   = branch_print_header,
+};
+
+__init static int init_branch_tracer(void)
+{
+       int ret;
+
+       ret = register_ftrace_event(&trace_branch_event);
+       if (!ret) {
+               printk(KERN_WARNING "Warning: could not register "
+                                   "branch events\n");
+               return 1;
+       }
+       return register_tracer(&branch_trace);
+}
+device_initcall(init_branch_tracer);
+
 #else
 static inline
 void trace_likely_condition(struct ftrace_branch_data *f, int val, int expect)
@@ -269,7 +275,7 @@ static int branch_stat_show(struct seq_file *m, void *v)
        return 0;
 }
 
-static void *annotated_branch_stat_start(void)
+static void *annotated_branch_stat_start(struct tracer_stat *trace)
 {
        return __start_annotated_branch_profile;
 }
@@ -301,24 +307,49 @@ static int annotated_branch_stat_cmp(void *p1, void *p2)
                return -1;
        if (percent_a > percent_b)
                return 1;
-       else
-               return 0;
+
+       if (a->incorrect < b->incorrect)
+               return -1;
+       if (a->incorrect > b->incorrect)
+               return 1;
+
+       /*
+        * Since the above shows worse (incorrect) cases
+        * first, we continue that by showing best (correct)
+        * cases last.
+        */
+       if (a->correct > b->correct)
+               return -1;
+       if (a->correct < b->correct)
+               return 1;
+
+       return 0;
 }
 
-#ifdef CONFIG_PROFILE_ALL_BRANCHES
-enum {
-       TRACE_BRANCH_OPT_ALL = 0x1
+static struct tracer_stat annotated_branch_stats = {
+       .name = "branch_annotated",
+       .stat_start = annotated_branch_stat_start,
+       .stat_next = annotated_branch_stat_next,
+       .stat_cmp = annotated_branch_stat_cmp,
+       .stat_headers = annotated_branch_stat_headers,
+       .stat_show = branch_stat_show
 };
 
-static struct tracer_opt branch_opts[] = {
-       { TRACER_OPT(stat_all_branch, TRACE_BRANCH_OPT_ALL) },
-       { }
-};
+__init static int init_annotated_branch_stats(void)
+{
+       int ret;
 
-static struct tracer_flags branch_flags = {
-       .val = 0,
-       .opts = branch_opts
-};
+       ret = register_stat_tracer(&annotated_branch_stats);
+       if (!ret) {
+               printk(KERN_WARNING "Warning: could not register "
+                                   "annotated branches stats\n");
+               return 1;
+       }
+       return 0;
+}
+fs_initcall(init_annotated_branch_stats);
+
+#ifdef CONFIG_PROFILE_ALL_BRANCHES
 
 extern unsigned long __start_branch_profile[];
 extern unsigned long __stop_branch_profile[];
@@ -334,7 +365,7 @@ static int all_branch_stat_headers(struct seq_file *m)
        return 0;
 }
 
-static void *all_branch_stat_start(void)
+static void *all_branch_stat_start(struct tracer_stat *trace)
 {
        return __start_branch_profile;
 }
@@ -352,60 +383,25 @@ all_branch_stat_next(void *v, int idx)
        return p;
 }
 
-static int branch_set_flag(u32 old_flags, u32 bit, int set)
-{
-       if (bit == TRACE_BRANCH_OPT_ALL) {
-               if (set) {
-                       branch_trace.stat_headers = all_branch_stat_headers;
-                       branch_trace.stat_start = all_branch_stat_start;
-                       branch_trace.stat_next = all_branch_stat_next;
-                       branch_trace.stat_cmp = NULL;
-               } else {
-                       branch_trace.stat_headers =
-                               annotated_branch_stat_headers;
-                       branch_trace.stat_start = annotated_branch_stat_start;
-                       branch_trace.stat_next = annotated_branch_stat_next;
-                       branch_trace.stat_cmp = annotated_branch_stat_cmp;
-               }
-               init_tracer_stat(&branch_trace);
-       }
-       return 0;
-}
-
-#endif /* CONFIG_PROFILE_ALL_BRANCHES */
-
-static struct tracer branch_trace __read_mostly =
-{
-       .name           = "branch",
-#ifdef CONFIG_BRANCH_TRACER
-       .init           = branch_trace_init,
-       .reset          = branch_trace_reset,
-#ifdef CONFIG_FTRACE_SELFTEST
-       .selftest       = trace_selftest_startup_branch,
-#endif /* CONFIG_FTRACE_SELFTEST */
-#endif /* CONFIG_BRANCH_TRACER */
-       .stat_start     =       annotated_branch_stat_start,
-       .stat_next      = annotated_branch_stat_next,
-       .stat_show      = branch_stat_show,
-       .stat_headers   = annotated_branch_stat_headers,
-       .stat_cmp       = annotated_branch_stat_cmp,
-#ifdef CONFIG_PROFILE_ALL_BRANCHES
-       .flags  = &branch_flags,
-       .set_flag       = branch_set_flag,
-#endif
+static struct tracer_stat all_branch_stats = {
+       .name = "branch_all",
+       .stat_start = all_branch_stat_start,
+       .stat_next = all_branch_stat_next,
+       .stat_headers = all_branch_stat_headers,
+       .stat_show = branch_stat_show
 };
 
-__init static int init_branch_trace(void)
+__init static int all_annotated_branch_stats(void)
 {
-#ifdef CONFIG_BRANCH_TRACER
        int ret;
-       ret = register_ftrace_event(&trace_branch_event);
+
+       ret = register_stat_tracer(&all_branch_stats);
        if (!ret) {
-               printk(KERN_WARNING "Warning: could not register branch events\n");
+               printk(KERN_WARNING "Warning: could not register "
+                                   "all branches stats\n");
                return 1;
        }
-#endif
-
-       return register_tracer(&branch_trace);
+       return 0;
 }
-device_initcall(init_branch_trace);
+fs_initcall(all_annotated_branch_stats);
+#endif /* CONFIG_PROFILE_ALL_BRANCHES */