aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/util/parse-events.c
diff options
context:
space:
mode:
authorStephane Eranian <eranian@google.com>2013-11-12 11:58:49 -0500
committerIngo Molnar <mingo@kernel.org>2013-11-27 05:16:39 -0500
commit410136f5dd96b6013fe6d1011b523b1c247e1ccb (patch)
treee30c0e866a1879752b570ad3973af5c0ef0e4cdd /tools/perf/util/parse-events.c
parent71ad88efebbcde374bddf904b96f3a7fc82d45d4 (diff)
tools/perf/stat: Add event unit and scale support
This patch adds perf stat support for handling event units and scales as exported by the kernel. The kernel can export PMU events actual unit and scaling factor via sysfs: $ ls -1 /sys/devices/power/events/energy-* /sys/devices/power/events/energy-cores /sys/devices/power/events/energy-cores.scale /sys/devices/power/events/energy-cores.unit /sys/devices/power/events/energy-pkg /sys/devices/power/events/energy-pkg.scale /sys/devices/power/events/energy-pkg.unit $ cat /sys/devices/power/events/energy-cores.scale 2.3283064365386962890625e-10 $ cat cat /sys/devices/power/events/energy-cores.unit Joules This patch modifies the pmu event alias code to check for the presence of the .unit and .scale files to load the corresponding values. They are then used by perf stat transparently: # perf stat -a -e power/energy-pkg/,power/energy-cores/,cycles -I 1000 sleep 1000 # time counts unit events 1.000214717 3.07 Joules power/energy-pkg/ [100.00%] 1.000214717 0.53 Joules power/energy-cores/ 1.000214717 12965028 cycles [100.00%] 2.000749289 3.01 Joules power/energy-pkg/ 2.000749289 0.52 Joules power/energy-cores/ 2.000749289 15817043 cycles When the event does not have an explicit unit exported by the kernel, nothing is printed. In csv output mode, there will be an empty field. Special thanks to Jiri for providing the supporting code in the parser to trigger reading of the scale and unit files. Signed-off-by: Stephane Eranian <eranian@google.com> Reviewed-by: Jiri Olsa <jolsa@redhat.com> Reviewed-by: Andi Kleen <ak@linux.intel.com> Signed-off-by: Peter Zijlstra <peterz@infradead.org> Cc: zheng.z.yan@intel.com Cc: bp@alien8.de Cc: maria.n.dimakopoulou@gmail.com Cc: acme@redhat.com Link: http://lkml.kernel.org/r/1384275531-10892-3-git-send-email-eranian@google.com Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'tools/perf/util/parse-events.c')
-rw-r--r--tools/perf/util/parse-events.c28
1 files changed, 19 insertions, 9 deletions
diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c
index 6de6f89c2a61..969cb8f0d88d 100644
--- a/tools/perf/util/parse-events.c
+++ b/tools/perf/util/parse-events.c
@@ -269,9 +269,10 @@ const char *event_type(int type)
269 269
270 270
271 271
272static int __add_event(struct list_head *list, int *idx, 272static struct perf_evsel *
273 struct perf_event_attr *attr, 273__add_event(struct list_head *list, int *idx,
274 char *name, struct cpu_map *cpus) 274 struct perf_event_attr *attr,
275 char *name, struct cpu_map *cpus)
275{ 276{
276 struct perf_evsel *evsel; 277 struct perf_evsel *evsel;
277 278
@@ -279,19 +280,19 @@ static int __add_event(struct list_head *list, int *idx,
279 280
280 evsel = perf_evsel__new_idx(attr, (*idx)++); 281 evsel = perf_evsel__new_idx(attr, (*idx)++);
281 if (!evsel) 282 if (!evsel)
282 return -ENOMEM; 283 return NULL;
283 284
284 evsel->cpus = cpus; 285 evsel->cpus = cpus;
285 if (name) 286 if (name)
286 evsel->name = strdup(name); 287 evsel->name = strdup(name);
287 list_add_tail(&evsel->node, list); 288 list_add_tail(&evsel->node, list);
288 return 0; 289 return evsel;
289} 290}
290 291
291static int add_event(struct list_head *list, int *idx, 292static int add_event(struct list_head *list, int *idx,
292 struct perf_event_attr *attr, char *name) 293 struct perf_event_attr *attr, char *name)
293{ 294{
294 return __add_event(list, idx, attr, name, NULL); 295 return __add_event(list, idx, attr, name, NULL) ? 0 : -ENOMEM;
295} 296}
296 297
297static int parse_aliases(char *str, const char *names[][PERF_EVSEL__MAX_ALIASES], int size) 298static int parse_aliases(char *str, const char *names[][PERF_EVSEL__MAX_ALIASES], int size)
@@ -633,6 +634,9 @@ int parse_events_add_pmu(struct list_head *list, int *idx,
633{ 634{
634 struct perf_event_attr attr; 635 struct perf_event_attr attr;
635 struct perf_pmu *pmu; 636 struct perf_pmu *pmu;
637 struct perf_evsel *evsel;
638 char *unit;
639 double scale;
636 640
637 pmu = perf_pmu__find(name); 641 pmu = perf_pmu__find(name);
638 if (!pmu) 642 if (!pmu)
@@ -640,7 +644,7 @@ int parse_events_add_pmu(struct list_head *list, int *idx,
640 644
641 memset(&attr, 0, sizeof(attr)); 645 memset(&attr, 0, sizeof(attr));
642 646
643 if (perf_pmu__check_alias(pmu, head_config)) 647 if (perf_pmu__check_alias(pmu, head_config, &unit, &scale))
644 return -EINVAL; 648 return -EINVAL;
645 649
646 /* 650 /*
@@ -652,8 +656,14 @@ int parse_events_add_pmu(struct list_head *list, int *idx,
652 if (perf_pmu__config(pmu, &attr, head_config)) 656 if (perf_pmu__config(pmu, &attr, head_config))
653 return -EINVAL; 657 return -EINVAL;
654 658
655 return __add_event(list, idx, &attr, pmu_event_name(head_config), 659 evsel = __add_event(list, idx, &attr, pmu_event_name(head_config),
656 pmu->cpus); 660 pmu->cpus);
661 if (evsel) {
662 evsel->unit = unit;
663 evsel->scale = scale;
664 }
665
666 return evsel ? 0 : -ENOMEM;
657} 667}
658 668
659int parse_events__modifier_group(struct list_head *list, 669int parse_events__modifier_group(struct list_head *list,