Merge branches 'tracing/kmemtrace2' and 'tracing/ftrace' into tracing/urgent
[sfrench/cifs-2.6.git] / kernel / trace / trace.c
index c580233add95a0915f4797b84ae05a728aa986c6..0418fc338b5c2d2d36cdc2987e7e7d4666126929 100644 (file)
@@ -37,6 +37,7 @@
 #include <linux/irqflags.h>
 
 #include "trace.h"
+#include "trace_output.h"
 
 #define TRACE_BUFFER_FLAGS     (RB_FL_OVERWRITE)
 
@@ -329,132 +330,6 @@ __update_max_tr(struct trace_array *tr, struct task_struct *tsk, int cpu)
        tracing_record_cmdline(current);
 }
 
-/**
- * trace_seq_printf - sequence printing of trace information
- * @s: trace sequence descriptor
- * @fmt: printf format string
- *
- * The tracer may use either sequence operations or its own
- * copy to user routines. To simplify formating of a trace
- * trace_seq_printf is used to store strings into a special
- * buffer (@s). Then the output may be either used by
- * the sequencer or pulled into another buffer.
- */
-int
-trace_seq_printf(struct trace_seq *s, const char *fmt, ...)
-{
-       int len = (PAGE_SIZE - 1) - s->len;
-       va_list ap;
-       int ret;
-
-       if (!len)
-               return 0;
-
-       va_start(ap, fmt);
-       ret = vsnprintf(s->buffer + s->len, len, fmt, ap);
-       va_end(ap);
-
-       /* If we can't write it all, don't bother writing anything */
-       if (ret >= len)
-               return 0;
-
-       s->len += ret;
-
-       return len;
-}
-
-/**
- * trace_seq_puts - trace sequence printing of simple string
- * @s: trace sequence descriptor
- * @str: simple string to record
- *
- * The tracer may use either the sequence operations or its own
- * copy to user routines. This function records a simple string
- * into a special buffer (@s) for later retrieval by a sequencer
- * or other mechanism.
- */
-static int
-trace_seq_puts(struct trace_seq *s, const char *str)
-{
-       int len = strlen(str);
-
-       if (len > ((PAGE_SIZE - 1) - s->len))
-               return 0;
-
-       memcpy(s->buffer + s->len, str, len);
-       s->len += len;
-
-       return len;
-}
-
-static int
-trace_seq_putc(struct trace_seq *s, unsigned char c)
-{
-       if (s->len >= (PAGE_SIZE - 1))
-               return 0;
-
-       s->buffer[s->len++] = c;
-
-       return 1;
-}
-
-static int
-trace_seq_putmem(struct trace_seq *s, void *mem, size_t len)
-{
-       if (len > ((PAGE_SIZE - 1) - s->len))
-               return 0;
-
-       memcpy(s->buffer + s->len, mem, len);
-       s->len += len;
-
-       return len;
-}
-
-#define MAX_MEMHEX_BYTES       8
-#define HEX_CHARS              (MAX_MEMHEX_BYTES*2 + 1)
-
-static int
-trace_seq_putmem_hex(struct trace_seq *s, void *mem, size_t len)
-{
-       unsigned char hex[HEX_CHARS];
-       unsigned char *data = mem;
-       int i, j;
-
-#ifdef __BIG_ENDIAN
-       for (i = 0, j = 0; i < len; i++) {
-#else
-       for (i = len-1, j = 0; i >= 0; i--) {
-#endif
-               hex[j++] = hex_asc_hi(data[i]);
-               hex[j++] = hex_asc_lo(data[i]);
-       }
-       hex[j++] = ' ';
-
-       return trace_seq_putmem(s, hex, j);
-}
-
-static int
-trace_seq_path(struct trace_seq *s, struct path *path)
-{
-       unsigned char *p;
-
-       if (s->len >= (PAGE_SIZE - 1))
-               return 0;
-       p = d_path(path, s->buffer + s->len, PAGE_SIZE - s->len);
-       if (!IS_ERR(p)) {
-               p = mangle_path(s->buffer + s->len, p, "\n");
-               if (p) {
-                       s->len = p - s->buffer;
-                       return 1;
-               }
-       } else {
-               s->buffer[s->len++] = '?';
-               return 1;
-       }
-
-       return 0;
-}
-
 static void
 trace_seq_reset(struct trace_seq *s)
 {
@@ -1472,154 +1347,6 @@ static void s_stop(struct seq_file *m, void *p)
        mutex_unlock(&trace_types_lock);
 }
 
-#ifdef CONFIG_KRETPROBES
-static inline const char *kretprobed(const char *name)
-{
-       static const char tramp_name[] = "kretprobe_trampoline";
-       int size = sizeof(tramp_name);
-
-       if (strncmp(tramp_name, name, size) == 0)
-               return "[unknown/kretprobe'd]";
-       return name;
-}
-#else
-static inline const char *kretprobed(const char *name)
-{
-       return name;
-}
-#endif /* CONFIG_KRETPROBES */
-
-static int
-seq_print_sym_short(struct trace_seq *s, const char *fmt, unsigned long address)
-{
-#ifdef CONFIG_KALLSYMS
-       char str[KSYM_SYMBOL_LEN];
-       const char *name;
-
-       kallsyms_lookup(address, NULL, NULL, NULL, str);
-
-       name = kretprobed(str);
-
-       return trace_seq_printf(s, fmt, name);
-#endif
-       return 1;
-}
-
-static int
-seq_print_sym_offset(struct trace_seq *s, const char *fmt,
-                    unsigned long address)
-{
-#ifdef CONFIG_KALLSYMS
-       char str[KSYM_SYMBOL_LEN];
-       const char *name;
-
-       sprint_symbol(str, address);
-       name = kretprobed(str);
-
-       return trace_seq_printf(s, fmt, name);
-#endif
-       return 1;
-}
-
-#ifndef CONFIG_64BIT
-# define IP_FMT "%08lx"
-#else
-# define IP_FMT "%016lx"
-#endif
-
-int
-seq_print_ip_sym(struct trace_seq *s, unsigned long ip, unsigned long sym_flags)
-{
-       int ret;
-
-       if (!ip)
-               return trace_seq_printf(s, "0");
-
-       if (sym_flags & TRACE_ITER_SYM_OFFSET)
-               ret = seq_print_sym_offset(s, "%s", ip);
-       else
-               ret = seq_print_sym_short(s, "%s", ip);
-
-       if (!ret)
-               return 0;
-
-       if (sym_flags & TRACE_ITER_SYM_ADDR)
-               ret = trace_seq_printf(s, " <" IP_FMT ">", ip);
-       return ret;
-}
-
-static inline int seq_print_user_ip(struct trace_seq *s, struct mm_struct *mm,
-                                   unsigned long ip, unsigned long sym_flags)
-{
-       struct file *file = NULL;
-       unsigned long vmstart = 0;
-       int ret = 1;
-
-       if (mm) {
-               const struct vm_area_struct *vma;
-
-               down_read(&mm->mmap_sem);
-               vma = find_vma(mm, ip);
-               if (vma) {
-                       file = vma->vm_file;
-                       vmstart = vma->vm_start;
-               }
-               if (file) {
-                       ret = trace_seq_path(s, &file->f_path);
-                       if (ret)
-                               ret = trace_seq_printf(s, "[+0x%lx]", ip - vmstart);
-               }
-               up_read(&mm->mmap_sem);
-       }
-       if (ret && ((sym_flags & TRACE_ITER_SYM_ADDR) || !file))
-               ret = trace_seq_printf(s, " <" IP_FMT ">", ip);
-       return ret;
-}
-
-static int
-seq_print_userip_objs(const struct userstack_entry *entry, struct trace_seq *s,
-                     unsigned long sym_flags)
-{
-       struct mm_struct *mm = NULL;
-       int ret = 1;
-       unsigned int i;
-
-       if (trace_flags & TRACE_ITER_SYM_USEROBJ) {
-               struct task_struct *task;
-               /*
-                * we do the lookup on the thread group leader,
-                * since individual threads might have already quit!
-                */
-               rcu_read_lock();
-               task = find_task_by_vpid(entry->ent.tgid);
-               if (task)
-                       mm = get_task_mm(task);
-               rcu_read_unlock();
-       }
-
-       for (i = 0; i < FTRACE_STACK_ENTRIES; i++) {
-               unsigned long ip = entry->caller[i];
-
-               if (ip == ULONG_MAX || !ret)
-                       break;
-               if (i && ret)
-                       ret = trace_seq_puts(s, " <- ");
-               if (!ip) {
-                       if (ret)
-                               ret = trace_seq_puts(s, "??");
-                       continue;
-               }
-               if (!ret)
-                       break;
-               if (ret)
-                       ret = seq_print_user_ip(s, mm, ip, sym_flags);
-       }
-
-       if (mm)
-               mmput(mm);
-       return ret;
-}
-
 static void print_lat_help_header(struct seq_file *m)
 {
        seq_puts(m, "#                  _------=> CPU#            \n");
@@ -1755,52 +1482,6 @@ lat_print_timestamp(struct trace_seq *s, u64 abs_usecs,
                trace_seq_puts(s, " : ");
 }
 
-static const char state_to_char[] = TASK_STATE_TO_CHAR_STR;
-
-static int task_state_char(unsigned long state)
-{
-       int bit = state ? __ffs(state) + 1 : 0;
-
-       return bit < sizeof(state_to_char) - 1 ? state_to_char[bit] : '?';
-}
-
-/*
- * The message is supposed to contain an ending newline.
- * If the printing stops prematurely, try to add a newline of our own.
- */
-void trace_seq_print_cont(struct trace_seq *s, struct trace_iterator *iter)
-{
-       struct trace_entry *ent;
-       struct trace_field_cont *cont;
-       bool ok = true;
-
-       ent = peek_next_entry(iter, iter->cpu, NULL);
-       if (!ent || ent->type != TRACE_CONT) {
-               trace_seq_putc(s, '\n');
-               return;
-       }
-
-       do {
-               cont = (struct trace_field_cont *)ent;
-               if (ok)
-                       ok = (trace_seq_printf(s, "%s", cont->buf) > 0);
-
-               ftrace_disable_cpu();
-
-               if (iter->buffer_iter[iter->cpu])
-                       ring_buffer_read(iter->buffer_iter[iter->cpu], NULL);
-               else
-                       ring_buffer_consume(iter->tr->buffer, iter->cpu, NULL);
-
-               ftrace_enable_cpu();
-
-               ent = peek_next_entry(iter, iter->cpu, NULL);
-       } while (ent && ent->type == TRACE_CONT);
-
-       if (!ok)
-               trace_seq_putc(s, '\n');
-}
-
 static void test_cpu_buff_start(struct trace_iterator *iter)
 {
        struct trace_seq *s = &iter->seq;
@@ -1824,17 +1505,14 @@ print_lat_fmt(struct trace_iterator *iter, unsigned int trace_idx, int cpu)
        struct trace_seq *s = &iter->seq;
        unsigned long sym_flags = (trace_flags & TRACE_ITER_SYM_MASK);
        struct trace_entry *next_entry;
+       struct trace_event *event;
        unsigned long verbose = (trace_flags & TRACE_ITER_VERBOSE);
        struct trace_entry *entry = iter->ent;
        unsigned long abs_usecs;
        unsigned long rel_usecs;
        u64 next_ts;
        char *comm;
-       int S, T;
-       int i;
-
-       if (entry->type == TRACE_CONT)
-               return TRACE_TYPE_HANDLED;
+       int ret;
 
        test_cpu_buff_start(iter);
 
@@ -1859,96 +1537,16 @@ print_lat_fmt(struct trace_iterator *iter, unsigned int trace_idx, int cpu)
                lat_print_generic(s, entry, cpu);
                lat_print_timestamp(s, abs_usecs, rel_usecs);
        }
-       switch (entry->type) {
-       case TRACE_FN: {
-               struct ftrace_entry *field;
-
-               trace_assign_type(field, entry);
-
-               seq_print_ip_sym(s, field->ip, sym_flags);
-               trace_seq_puts(s, " (");
-               seq_print_ip_sym(s, field->parent_ip, sym_flags);
-               trace_seq_puts(s, ")\n");
-               break;
-       }
-       case TRACE_CTX:
-       case TRACE_WAKE: {
-               struct ctx_switch_entry *field;
-
-               trace_assign_type(field, entry);
-
-               T = task_state_char(field->next_state);
-               S = task_state_char(field->prev_state);
-               comm = trace_find_cmdline(field->next_pid);
-               trace_seq_printf(s, " %5d:%3d:%c %s [%03d] %5d:%3d:%c %s\n",
-                                field->prev_pid,
-                                field->prev_prio,
-                                S, entry->type == TRACE_CTX ? "==>" : "  +",
-                                field->next_cpu,
-                                field->next_pid,
-                                field->next_prio,
-                                T, comm);
-               break;
-       }
-       case TRACE_SPECIAL: {
-               struct special_entry *field;
-
-               trace_assign_type(field, entry);
-
-               trace_seq_printf(s, "# %ld %ld %ld\n",
-                                field->arg1,
-                                field->arg2,
-                                field->arg3);
-               break;
-       }
-       case TRACE_STACK: {
-               struct stack_entry *field;
-
-               trace_assign_type(field, entry);
-
-               for (i = 0; i < FTRACE_STACK_ENTRIES; i++) {
-                       if (i)
-                               trace_seq_puts(s, " <= ");
-                       seq_print_ip_sym(s, field->caller[i], sym_flags);
-               }
-               trace_seq_puts(s, "\n");
-               break;
-       }
-       case TRACE_PRINT: {
-               struct print_entry *field;
-
-               trace_assign_type(field, entry);
 
-               seq_print_ip_sym(s, field->ip, sym_flags);
-               trace_seq_printf(s, ": %s", field->buf);
-               if (entry->flags & TRACE_FLAG_CONT)
-                       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;
+       event = ftrace_find_event(entry->type);
+       if (event && event->latency_trace) {
+               ret = event->latency_trace(s, entry, sym_flags);
+               if (ret)
+                       return ret;
+               return TRACE_TYPE_HANDLED;
        }
-       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);
-       }
+       trace_seq_printf(s, "Unknown type %d\n", entry->type);
        return TRACE_TYPE_HANDLED;
 }
 
@@ -1957,19 +1555,15 @@ static enum print_line_t print_trace_fmt(struct trace_iterator *iter)
        struct trace_seq *s = &iter->seq;
        unsigned long sym_flags = (trace_flags & TRACE_ITER_SYM_MASK);
        struct trace_entry *entry;
+       struct trace_event *event;
        unsigned long usec_rem;
        unsigned long long t;
        unsigned long secs;
        char *comm;
        int ret;
-       int S, T;
-       int i;
 
        entry = iter->ent;
 
-       if (entry->type == TRACE_CONT)
-               return TRACE_TYPE_HANDLED;
-
        test_cpu_buff_start(iter);
 
        comm = trace_find_cmdline(iter->ent->pid);
@@ -1988,129 +1582,17 @@ static enum print_line_t print_trace_fmt(struct trace_iterator *iter)
        if (!ret)
                return TRACE_TYPE_PARTIAL_LINE;
 
-       switch (entry->type) {
-       case TRACE_FN: {
-               struct ftrace_entry *field;
-
-               trace_assign_type(field, entry);
-
-               ret = seq_print_ip_sym(s, field->ip, sym_flags);
-               if (!ret)
-                       return TRACE_TYPE_PARTIAL_LINE;
-               if ((sym_flags & TRACE_ITER_PRINT_PARENT) &&
-                                               field->parent_ip) {
-                       ret = trace_seq_printf(s, " <-");
-                       if (!ret)
-                               return TRACE_TYPE_PARTIAL_LINE;
-                       ret = seq_print_ip_sym(s,
-                                              field->parent_ip,
-                                              sym_flags);
-                       if (!ret)
-                               return TRACE_TYPE_PARTIAL_LINE;
-               }
-               ret = trace_seq_printf(s, "\n");
-               if (!ret)
-                       return TRACE_TYPE_PARTIAL_LINE;
-               break;
-       }
-       case TRACE_CTX:
-       case TRACE_WAKE: {
-               struct ctx_switch_entry *field;
-
-               trace_assign_type(field, entry);
-
-               T = task_state_char(field->next_state);
-               S = task_state_char(field->prev_state);
-               ret = trace_seq_printf(s, " %5d:%3d:%c %s [%03d] %5d:%3d:%c\n",
-                                      field->prev_pid,
-                                      field->prev_prio,
-                                      S,
-                                      entry->type == TRACE_CTX ? "==>" : "  +",
-                                      field->next_cpu,
-                                      field->next_pid,
-                                      field->next_prio,
-                                      T);
-               if (!ret)
-                       return TRACE_TYPE_PARTIAL_LINE;
-               break;
-       }
-       case TRACE_SPECIAL: {
-               struct special_entry *field;
-
-               trace_assign_type(field, entry);
-
-               ret = trace_seq_printf(s, "# %ld %ld %ld\n",
-                                field->arg1,
-                                field->arg2,
-                                field->arg3);
-               if (!ret)
-                       return TRACE_TYPE_PARTIAL_LINE;
-               break;
-       }
-       case TRACE_STACK: {
-               struct stack_entry *field;
-
-               trace_assign_type(field, entry);
-
-               for (i = 0; i < FTRACE_STACK_ENTRIES; i++) {
-                       if (i) {
-                               ret = trace_seq_puts(s, " <= ");
-                               if (!ret)
-                                       return TRACE_TYPE_PARTIAL_LINE;
-                       }
-                       ret = seq_print_ip_sym(s, field->caller[i],
-                                              sym_flags);
-                       if (!ret)
-                               return TRACE_TYPE_PARTIAL_LINE;
-               }
-               ret = trace_seq_puts(s, "\n");
-               if (!ret)
-                       return TRACE_TYPE_PARTIAL_LINE;
-               break;
-       }
-       case TRACE_PRINT: {
-               struct print_entry *field;
-
-               trace_assign_type(field, entry);
-
-               seq_print_ip_sym(s, field->ip, sym_flags);
-               trace_seq_printf(s, ": %s", field->buf);
-               if (entry->flags & TRACE_FLAG_CONT)
-                       trace_seq_print_cont(s, iter);
-               break;
-       }
-       case TRACE_GRAPH_RET: {
-               return print_graph_function(iter);
-       }
-       case TRACE_GRAPH_ENT: {
-               return print_graph_function(iter);
-       }
-       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;
+       event = ftrace_find_event(entry->type);
+       if (event && event->trace) {
+               ret = event->trace(s, entry, sym_flags);
+               if (ret)
+                       return ret;
+               return TRACE_TYPE_HANDLED;
        }
-       case TRACE_USER_STACK: {
-               struct userstack_entry *field;
-
-               trace_assign_type(field, entry);
+       ret = trace_seq_printf(s, "Unknown type %d\n", entry->type);
+       if (!ret)
+               return TRACE_TYPE_PARTIAL_LINE;
 
-               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;
 }
 
@@ -2118,152 +1600,47 @@ static enum print_line_t print_raw_fmt(struct trace_iterator *iter)
 {
        struct trace_seq *s = &iter->seq;
        struct trace_entry *entry;
+       struct trace_event *event;
        int ret;
-       int S, T;
 
        entry = iter->ent;
 
-       if (entry->type == TRACE_CONT)
-               return TRACE_TYPE_HANDLED;
-
        ret = trace_seq_printf(s, "%d %d %llu ",
                entry->pid, iter->cpu, iter->ts);
        if (!ret)
                return TRACE_TYPE_PARTIAL_LINE;
 
-       switch (entry->type) {
-       case TRACE_FN: {
-               struct ftrace_entry *field;
-
-               trace_assign_type(field, entry);
-
-               ret = trace_seq_printf(s, "%x %x\n",
-                                       field->ip,
-                                       field->parent_ip);
-               if (!ret)
-                       return TRACE_TYPE_PARTIAL_LINE;
-               break;
-       }
-       case TRACE_CTX:
-       case TRACE_WAKE: {
-               struct ctx_switch_entry *field;
-
-               trace_assign_type(field, entry);
-
-               T = task_state_char(field->next_state);
-               S = entry->type == TRACE_WAKE ? '+' :
-                       task_state_char(field->prev_state);
-               ret = trace_seq_printf(s, "%d %d %c %d %d %d %c\n",
-                                      field->prev_pid,
-                                      field->prev_prio,
-                                      S,
-                                      field->next_cpu,
-                                      field->next_pid,
-                                      field->next_prio,
-                                      T);
-               if (!ret)
-                       return TRACE_TYPE_PARTIAL_LINE;
-               break;
-       }
-       case TRACE_SPECIAL:
-       case TRACE_USER_STACK:
-       case TRACE_STACK: {
-               struct special_entry *field;
-
-               trace_assign_type(field, entry);
-
-               ret = trace_seq_printf(s, "# %ld %ld %ld\n",
-                                field->arg1,
-                                field->arg2,
-                                field->arg3);
-               if (!ret)
-                       return TRACE_TYPE_PARTIAL_LINE;
-               break;
+       event = ftrace_find_event(entry->type);
+       if (event && event->raw) {
+               ret = event->raw(s, entry, 0);
+               if (ret)
+                       return ret;
+               return TRACE_TYPE_HANDLED;
        }
-       case TRACE_PRINT: {
-               struct print_entry *field;
-
-               trace_assign_type(field, entry);
+       ret = trace_seq_printf(s, "%d ?\n", entry->type);
+       if (!ret)
+               return TRACE_TYPE_PARTIAL_LINE;
 
-               trace_seq_printf(s, "# %lx %s", field->ip, field->buf);
-               if (entry->flags & TRACE_FLAG_CONT)
-                       trace_seq_print_cont(s, iter);
-               break;
-       }
-       }
        return TRACE_TYPE_HANDLED;
 }
 
-#define SEQ_PUT_FIELD_RET(s, x)                                \
-do {                                                   \
-       if (!trace_seq_putmem(s, &(x), sizeof(x)))      \
-               return 0;                               \
-} while (0)
-
-#define SEQ_PUT_HEX_FIELD_RET(s, x)                    \
-do {                                                   \
-       BUILD_BUG_ON(sizeof(x) > MAX_MEMHEX_BYTES);     \
-       if (!trace_seq_putmem_hex(s, &(x), sizeof(x)))  \
-               return 0;                               \
-} while (0)
-
 static enum print_line_t print_hex_fmt(struct trace_iterator *iter)
 {
        struct trace_seq *s = &iter->seq;
        unsigned char newline = '\n';
        struct trace_entry *entry;
-       int S, T;
+       struct trace_event *event;
 
        entry = iter->ent;
 
-       if (entry->type == TRACE_CONT)
-               return TRACE_TYPE_HANDLED;
-
        SEQ_PUT_HEX_FIELD_RET(s, entry->pid);
        SEQ_PUT_HEX_FIELD_RET(s, iter->cpu);
        SEQ_PUT_HEX_FIELD_RET(s, iter->ts);
 
-       switch (entry->type) {
-       case TRACE_FN: {
-               struct ftrace_entry *field;
+       event = ftrace_find_event(entry->type);
+       if (event && event->hex)
+               event->hex(s, entry, 0);
 
-               trace_assign_type(field, entry);
-
-               SEQ_PUT_HEX_FIELD_RET(s, field->ip);
-               SEQ_PUT_HEX_FIELD_RET(s, field->parent_ip);
-               break;
-       }
-       case TRACE_CTX:
-       case TRACE_WAKE: {
-               struct ctx_switch_entry *field;
-
-               trace_assign_type(field, entry);
-
-               T = task_state_char(field->next_state);
-               S = entry->type == TRACE_WAKE ? '+' :
-                       task_state_char(field->prev_state);
-               SEQ_PUT_HEX_FIELD_RET(s, field->prev_pid);
-               SEQ_PUT_HEX_FIELD_RET(s, field->prev_prio);
-               SEQ_PUT_HEX_FIELD_RET(s, S);
-               SEQ_PUT_HEX_FIELD_RET(s, field->next_cpu);
-               SEQ_PUT_HEX_FIELD_RET(s, field->next_pid);
-               SEQ_PUT_HEX_FIELD_RET(s, field->next_prio);
-               SEQ_PUT_HEX_FIELD_RET(s, T);
-               break;
-       }
-       case TRACE_SPECIAL:
-       case TRACE_USER_STACK:
-       case TRACE_STACK: {
-               struct special_entry *field;
-
-               trace_assign_type(field, entry);
-
-               SEQ_PUT_HEX_FIELD_RET(s, field->arg1);
-               SEQ_PUT_HEX_FIELD_RET(s, field->arg2);
-               SEQ_PUT_HEX_FIELD_RET(s, field->arg3);
-               break;
-       }
-       }
        SEQ_PUT_FIELD_RET(s, newline);
 
        return TRACE_TYPE_HANDLED;
@@ -2282,9 +1659,6 @@ static enum print_line_t print_printk_msg_only(struct trace_iterator *iter)
        if (!ret)
                return TRACE_TYPE_PARTIAL_LINE;
 
-       if (entry->flags & TRACE_FLAG_CONT)
-               trace_seq_print_cont(s, iter);
-
        return TRACE_TYPE_HANDLED;
 }
 
@@ -2292,53 +1666,19 @@ static enum print_line_t print_bin_fmt(struct trace_iterator *iter)
 {
        struct trace_seq *s = &iter->seq;
        struct trace_entry *entry;
+       struct trace_event *event;
 
        entry = iter->ent;
 
-       if (entry->type == TRACE_CONT)
-               return TRACE_TYPE_HANDLED;
-
        SEQ_PUT_FIELD_RET(s, entry->pid);
        SEQ_PUT_FIELD_RET(s, entry->cpu);
        SEQ_PUT_FIELD_RET(s, iter->ts);
 
-       switch (entry->type) {
-       case TRACE_FN: {
-               struct ftrace_entry *field;
-
-               trace_assign_type(field, entry);
-
-               SEQ_PUT_FIELD_RET(s, field->ip);
-               SEQ_PUT_FIELD_RET(s, field->parent_ip);
-               break;
-       }
-       case TRACE_CTX: {
-               struct ctx_switch_entry *field;
-
-               trace_assign_type(field, entry);
-
-               SEQ_PUT_FIELD_RET(s, field->prev_pid);
-               SEQ_PUT_FIELD_RET(s, field->prev_prio);
-               SEQ_PUT_FIELD_RET(s, field->prev_state);
-               SEQ_PUT_FIELD_RET(s, field->next_pid);
-               SEQ_PUT_FIELD_RET(s, field->next_prio);
-               SEQ_PUT_FIELD_RET(s, field->next_state);
-               break;
-       }
-       case TRACE_SPECIAL:
-       case TRACE_USER_STACK:
-       case TRACE_STACK: {
-               struct special_entry *field;
-
-               trace_assign_type(field, entry);
+       event = ftrace_find_event(entry->type);
+       if (event && event->binary)
+               event->binary(s, entry, 0);
 
-               SEQ_PUT_FIELD_RET(s, field->arg1);
-               SEQ_PUT_FIELD_RET(s, field->arg2);
-               SEQ_PUT_FIELD_RET(s, field->arg3);
-               break;
-       }
-       }
-       return 1;
+       return TRACE_TYPE_HANDLED;
 }
 
 static int trace_empty(struct trace_iterator *iter)
@@ -3013,6 +2353,7 @@ static int tracing_set_tracer(char *buf)
                if (ret)
                        goto out;
        }
+       init_tracer_stat(t);
 
        trace_branch_enable(tr);
  out:
@@ -3877,7 +3218,7 @@ __init static int tracer_alloc_buffers(void)
 #else
        current_trace = &nop_trace;
 #endif
-
+       init_tracer_stat(current_trace);
        /* All seems OK, enable tracing */
        tracing_disabled = 0;