Merge branch 'perf-fixes-for-linus-2' of git://git.kernel.org/pub/scm/linux/kernel...
[linux-2.6.git] / tools / perf / builtin-trace.c
index 88eef71..0c5e4f7 100644 (file)
@@ -35,14 +35,14 @@ process_comm_event(event_t *event, unsigned long offset, unsigned long head)
 
        thread = threads__findnew(event->comm.pid, &threads, &last_match);
 
-       dump_printf("%p [%p]: PERF_EVENT_COMM: %s:%d\n",
+       dump_printf("%p [%p]: PERF_RECORD_COMM: %s:%d\n",
                (void *)(offset + head),
                (void *)(long)(event->header.size),
                event->comm.comm, event->comm.pid);
 
        if (thread == NULL ||
            thread__set_comm(thread, event->comm.comm)) {
-               dump_printf("problem processing PERF_EVENT_COMM, skipping event.\n");
+               dump_printf("problem processing PERF_RECORD_COMM, skipping event.\n");
                return -1;
        }
        total_comm++;
@@ -58,18 +58,31 @@ process_sample_event(event_t *event, unsigned long offset, unsigned long head)
        struct dso *dso = NULL;
        struct thread *thread;
        u64 ip = event->ip.ip;
+       u64 timestamp = -1;
+       u32 cpu = -1;
        u64 period = 1;
        void *more_data = event->ip.__more_data;
        int cpumode;
 
        thread = threads__findnew(event->ip.pid, &threads, &last_match);
 
+       if (sample_type & PERF_SAMPLE_TIME) {
+               timestamp = *(u64 *)more_data;
+               more_data += sizeof(u64);
+       }
+
+       if (sample_type & PERF_SAMPLE_CPU) {
+               cpu = *(u32 *)more_data;
+               more_data += sizeof(u32);
+               more_data += sizeof(u32); /* reserved */
+       }
+
        if (sample_type & PERF_SAMPLE_PERIOD) {
                period = *(u64 *)more_data;
                more_data += sizeof(u64);
        }
 
-       dump_printf("%p [%p]: PERF_EVENT_SAMPLE (IP, %d): %d/%d: %p period: %Ld\n",
+       dump_printf("%p [%p]: PERF_RECORD_SAMPLE (IP, %d): %d/%d: %p period: %Ld\n",
                (void *)(offset + head),
                (void *)(long)(event->header.size),
                event->header.misc,
@@ -85,9 +98,9 @@ process_sample_event(event_t *event, unsigned long offset, unsigned long head)
                return -1;
        }
 
-       cpumode = event->header.misc & PERF_EVENT_MISC_CPUMODE_MASK;
+       cpumode = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK;
 
-       if (cpumode == PERF_EVENT_MISC_KERNEL) {
+       if (cpumode == PERF_RECORD_MISC_KERNEL) {
                show = SHOW_KERNEL;
                level = 'k';
 
@@ -95,7 +108,7 @@ process_sample_event(event_t *event, unsigned long offset, unsigned long head)
 
                dump_printf(" ...... dso: %s\n", dso->name);
 
-       } else if (cpumode == PERF_EVENT_MISC_USER) {
+       } else if (cpumode == PERF_RECORD_MISC_USER) {
 
                show = SHOW_USER;
                level = '.';
@@ -120,7 +133,7 @@ process_sample_event(event_t *event, unsigned long offset, unsigned long head)
                 * field, although it should be the same than this perf
                 * event pid
                 */
-               print_event(0, raw->data, raw->size, 0, thread->comm);
+               print_event(cpu, raw->data, raw->size, timestamp, thread->comm);
        }
        total += period;
 
@@ -133,19 +146,19 @@ process_event(event_t *event, unsigned long offset, unsigned long head)
        trace_event(event);
 
        switch (event->header.type) {
-       case PERF_EVENT_MMAP ... PERF_EVENT_LOST:
+       case PERF_RECORD_MMAP ... PERF_RECORD_LOST:
                return 0;
 
-       case PERF_EVENT_COMM:
+       case PERF_RECORD_COMM:
                return process_comm_event(event, offset, head);
 
-       case PERF_EVENT_EXIT ... PERF_EVENT_READ:
+       case PERF_RECORD_EXIT ... PERF_RECORD_READ:
                return 0;
 
-       case PERF_EVENT_SAMPLE:
+       case PERF_RECORD_SAMPLE:
                return process_sample_event(event, offset, head);
 
-       case PERF_EVENT_MAX:
+       case PERF_RECORD_MAX:
        default:
                return -1;
        }
@@ -164,6 +177,7 @@ static int __cmd_trace(void)
        char *buf;
 
        trace_report();
+       register_idle_thread(&threads, &last_match);
 
        input = open(input_name, O_RDONLY);
        if (input < 0) {
@@ -182,6 +196,7 @@ static int __cmd_trace(void)
                exit(0);
        }
        header = perf_header__read(input);
+       head = header->data_offset;
        sample_type = perf_header__sample_type(header);
 
        if (!(sample_type & PERF_SAMPLE_RAW))
@@ -204,10 +219,6 @@ remap:
 more:
        event = (event_t *)(buf + head);
 
-       size = event->header.size;
-       if (!size)
-               size = 8;
-
        if (head + event->header.size >= page_size * mmap_window) {
                unsigned long shift = page_size * (head / page_size);
                int res;
@@ -222,7 +233,6 @@ more:
 
        size = event->header.size;
 
-
        if (!size || process_event(event, offset, head) < 0) {
 
                /*
@@ -257,6 +267,7 @@ static const struct option options[] = {
                    "dump raw trace in ASCII"),
        OPT_BOOLEAN('v', "verbose", &verbose,
                    "be more verbose (show symbol address, etc)"),
+       OPT_END()
 };
 
 int cmd_trace(int argc, const char **argv, const char *prefix __used)
@@ -274,7 +285,6 @@ int cmd_trace(int argc, const char **argv, const char *prefix __used)
                        usage_with_options(annotate_usage, options);
        }
 
-
        setup_pager();
 
        return __cmd_trace();