aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Senozhatsky <sergey.senozhatsky@gmail.com>2013-10-08 17:42:55 +0300
committerSanjay Singh Rawat <sanjay.rawat@linaro.org>2013-10-17 14:15:02 +0530
commitab1706a4a9299f08cde121b161b4ff69b4c9c2e9 (patch)
tree57cc931116d1ceac6d652cdf201a16cca650edba
parenta322b28a9580b245c29c128a425c320d34c78821 (diff)
perf_bundle: introduce fixup_sample_trace_cpu()linaro-powertop-2013.10
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 38e1e91..e20a16c 100644
--- a/src/perf/perf_bundle.cpp
+++ b/src/perf/perf_bundle.cpp
@@ -284,6 +284,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;
@@ -308,6 +333,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);
}
}