ftrace: bin-output
authorIngo Molnar <mingo@elte.hu>
Mon, 12 May 2008 19:20:47 +0000 (21:20 +0200)
committerThomas Gleixner <tglx@linutronix.de>
Fri, 23 May 2008 18:43:23 +0000 (20:43 +0200)
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
kernel/trace/trace.c

index bebd263f582f6661ff1acdc980c527a1dea9e4f5..d78cbc4fc519d2f9f68033fd4b2991f22e7fb3b1 100644 (file)
@@ -154,6 +154,7 @@ enum trace_iterator_flags {
        TRACE_ITER_SYM_ADDR             = 0x04,
        TRACE_ITER_VERBOSE              = 0x08,
        TRACE_ITER_RAW                  = 0x10,
+       TRACE_ITER_BIN                  = 0x20,
 };
 
 #define TRACE_ITER_SYM_MASK \
@@ -166,6 +167,7 @@ static const char *trace_options[] = {
        "sym-addr",
        "verbose",
        "raw",
+       "bin",
        NULL
 };
 
@@ -275,6 +277,18 @@ trace_seq_putc(struct trace_seq *s, unsigned char c)
        return 1;
 }
 
+static notrace 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;
+}
+
 static notrace void
 trace_seq_reset(struct trace_seq *s)
 {
@@ -1261,6 +1275,39 @@ static notrace int print_raw_fmt(struct trace_iterator *iter)
        return 1;
 }
 
+#define SEQ_PUT_FIELD_RET(s, x)                                \
+do {                                                   \
+       if (!trace_seq_putmem(s, &(x), sizeof(x)))      \
+               return 0;                               \
+} while (0)
+
+static notrace int print_bin_fmt(struct trace_iterator *iter)
+{
+       struct trace_seq *s = &iter->seq;
+       struct trace_entry *entry;
+
+       entry = iter->ent;
+
+       SEQ_PUT_FIELD_RET(s, entry->pid);
+       SEQ_PUT_FIELD_RET(s, entry->cpu);
+       SEQ_PUT_FIELD_RET(s, entry->t);
+
+       switch (entry->type) {
+       case TRACE_FN:
+               SEQ_PUT_FIELD_RET(s, entry->fn.ip);
+               SEQ_PUT_FIELD_RET(s, entry->fn.parent_ip);
+               break;
+       case TRACE_CTX:
+               SEQ_PUT_FIELD_RET(s, entry->ctx.prev_pid);
+               SEQ_PUT_FIELD_RET(s, entry->ctx.prev_prio);
+               SEQ_PUT_FIELD_RET(s, entry->ctx.prev_state);
+               SEQ_PUT_FIELD_RET(s, entry->ctx.next_pid);
+               SEQ_PUT_FIELD_RET(s, entry->ctx.next_prio);
+               break;
+       }
+       return 1;
+}
+
 static int trace_empty(struct trace_iterator *iter)
 {
        struct trace_array_cpu *data;
@@ -1279,6 +1326,9 @@ static int trace_empty(struct trace_iterator *iter)
 
 static int print_trace_line(struct trace_iterator *iter)
 {
+       if (trace_flags & TRACE_ITER_BIN)
+               return print_bin_fmt(iter);
+
        if (trace_flags & TRACE_ITER_RAW)
                return print_raw_fmt(iter);