perf_event: Fix raw event processing
[linux-3.10.git] / tools / perf / builtin-sched.c
index 26b782f..4655e16 100644 (file)
@@ -1570,13 +1570,17 @@ process_sched_migrate_task_event(struct raw_event_sample *raw,
 }
 
 static void
-process_raw_event(event_t *raw_event __used, void *more_data,
+process_raw_event(event_t *raw_event __used, u32 size, void *data,
                  int cpu, u64 timestamp, struct thread *thread)
 {
-       struct raw_event_sample *raw = more_data;
+       struct raw_event_sample *raw;
        struct event *event;
        int type;
 
+       raw = malloc_or_die(sizeof(*raw)+size);
+       raw->size = size;
+       memcpy(raw->data, data, size);
+
        type = trace_parse_common_type(raw->data);
        event = trace_find_event(type);
 
@@ -1598,40 +1602,26 @@ process_raw_event(event_t *raw_event __used, void *more_data,
 
 static int process_sample_event(event_t *event)
 {
+       struct sample_data data;
        struct thread *thread;
-       u64 ip = event->ip.ip;
-       u64 timestamp = -1;
-       u32 cpu = -1;
-       u64 period = 1;
-       void *more_data = event->ip.__more_data;
 
        if (!(sample_type & PERF_SAMPLE_RAW))
                return 0;
 
-       thread = threads__findnew(event->ip.pid);
-
-       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 */
-       }
+       memset(&data, 0, sizeof(data));
+       data.time = -1;
+       data.cpu = -1;
+       data.period = -1;
 
-       if (sample_type & PERF_SAMPLE_PERIOD) {
-               period = *(u64 *)more_data;
-               more_data += sizeof(u64);
-       }
+       event__parse_sample(event, sample_type, &data);
 
        dump_printf("(IP, %d): %d/%d: %p period: %Ld\n",
                event->header.misc,
-               event->ip.pid, event->ip.tid,
-               (void *)(long)ip,
-               (long long)period);
+               data.pid, data.tid,
+               (void *)(long)data.ip,
+               (long long)data.period);
 
+       thread = threads__findnew(data.pid);
        if (thread == NULL) {
                pr_debug("problem processing %d event, skipping it.\n",
                         event->header.type);
@@ -1640,10 +1630,11 @@ static int process_sample_event(event_t *event)
 
        dump_printf(" ... thread: %s:%d\n", thread->comm, thread->pid);
 
-       if (profile_cpu != -1 && profile_cpu != (int) cpu)
+       if (profile_cpu != -1 && profile_cpu != (int)data.cpu)
                return 0;
 
-       process_raw_event(event, more_data, cpu, timestamp, thread);
+       process_raw_event(event, data.raw_size, data.raw_data, data.cpu,
+                         data.time, thread);
 
        return 0;
 }
@@ -1902,13 +1893,18 @@ static int __cmd_record(int argc, const char **argv)
 
 int cmd_sched(int argc, const char **argv, const char *prefix __used)
 {
-       symbol__init(0);
-
        argc = parse_options(argc, argv, sched_options, sched_usage,
                             PARSE_OPT_STOP_AT_NON_OPTION);
        if (!argc)
                usage_with_options(sched_usage, sched_options);
 
+       /*
+        * Aliased to 'perf trace' for now:
+        */
+       if (!strcmp(argv[0], "trace"))
+               return cmd_trace(argc, argv, prefix);
+
+       symbol__init(0);
        if (!strncmp(argv[0], "rec", 3)) {
                return __cmd_record(argc, argv);
        } else if (!strncmp(argv[0], "lat", 3)) {
@@ -1932,11 +1928,6 @@ int cmd_sched(int argc, const char **argv, const char *prefix __used)
                                usage_with_options(replay_usage, replay_options);
                }
                __cmd_replay();
-       } else if (!strcmp(argv[0], "trace")) {
-               /*
-                * Aliased to 'perf trace' for now:
-                */
-               return cmd_trace(argc, argv, prefix);
        } else {
                usage_with_options(sched_usage, sched_options);
        }