aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Senozhatsky <sergey.senozhatsky@gmail.com>2013-10-08 17:42:55 +0300
committerSergey Senozhatsky <sergey.senozhatsky@gmail.com>2013-10-08 17:42:55 +0300
commitaf8431eb0062f9f785ec593f2e6747c75089962d (patch)
treef58d1e1b7b9217009e96f4548e862435c3cd68f1
parent3d0d01c29d2d07493595b87ae20354d335864f19 (diff)
perf_bundle: introduce fixup_sample_trace_cpu()
struct perf_sample's trace cpu is a raw_smp_processor_id() (as requsted by PERF_SAMPLE_CPU) by the time of perf_event_output() call, which may differ from original struct perf_event's cpu. thus we need to fix sample->trace.cpu via fixup_sample_trace_cpu() call. debugging output has demonstrated that some events (namely cpu_frequency) were routed incorrectly (sample->trace.cpu != pevent_get_field_val("cpu_id")): fix [cpu_frequency] cpu_nr from 1 to 0 fix [cpu_frequency] cpu_nr from 1 to 0 fix [cpu_frequency] cpu_nr from 1 to 2 fix [cpu_frequency] cpu_nr from 1 to 2 fix [cpu_frequency] cpu_nr from 1 to 3 fix [cpu_frequency] cpu_nr from 1 to 3 fix [cpu_frequency] cpu_nr from 1 to 0 fix [cpu_frequency] cpu_nr from 1 to 0 fix [cpu_frequency] cpu_nr from 1 to 2 fix [cpu_frequency] cpu_nr from 1 to 2 fix [cpu_frequency] cpu_nr from 1 to 0 fix [cpu_frequency] cpu_nr from 1 to 0 fix [cpu_frequency] cpu_nr from 1 to 0 Thanks for reporting and tracking this down to (not in any particular order): Shaojie Sun, Jon Medhurst, Sanjay Rawat, SunShaoJie. Cc: Shaojie Sun <shaojie.sun@linaro.org> Cc: Jon Medhurst <jon.medhurst@linaro.org> Cc: Sanjay Rawat <sanjay.rawat@linaro.org> Cc: SunShaoJie <sunshaojie@huawei.com> Signed-off-by: Sergey Senozhatsky <sergey.senozhatsky@gmail.com>
-rw-r--r--src/perf/perf_bundle.cpp26
1 files changed, 26 insertions, 0 deletions
diff --git a/src/perf/perf_bundle.cpp b/src/perf/perf_bundle.cpp
index 8d480e8..b0e982b 100644
--- a/src/perf/perf_bundle.cpp
+++ b/src/perf/perf_bundle.cpp
@@ -285,6 +285,31 @@ static bool event_sort_function (void *i, void *j)
return (timestamp(I)<timestamp(J));
}
+/*
+ * sample's PERF_SAMPLE_CPU cpu nr is a raw_smp_processor_id() by the
+ * time of perf_event_output(), which may differ from struct perf_event
+ * cpu, thus we need to fix sample->trace.cpu.
+ */
+static void fixup_sample_trace_cpu(struct perf_sample *sample)
+{
+ struct event_format *event;
+ struct pevent_record rec;
+ unsigned long long cpu_nr;
+ int type;
+ int ret;
+
+ rec.data = &sample->data;
+ type = pevent_data_type(perf_event::pevent, &rec);
+ event = pevent_find_event(perf_event::pevent, type);
+ if (!event)
+ return;
+ /** don't touch trace if event does not contain cpu_id field*/
+ ret = pevent_get_field_val(NULL, event, "cpu_id", &rec, &cpu_nr, 0);
+ if (ret < 0)
+ return;
+ sample->trace.cpu = cpu_nr;
+}
+
void perf_bundle::process(void)
{
unsigned int i;
@@ -309,6 +334,7 @@ void perf_bundle::process(void)
if (sample->header.type != PERF_RECORD_SAMPLE)
continue;
+ fixup_sample_trace_cpu(sample);
handle_trace_point(&sample->data, sample->trace.cpu, sample->trace.time);
}
}