aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndi Kleen <ak@linux.intel.com>2017-03-20 16:17:10 -0400
committerArnaldo Carvalho de Melo <acme@redhat.com>2017-03-23 10:42:31 -0400
commit962848142335e8b35d522be78f58f2011d976b17 (patch)
tree3d73b6f223cf8fd2246d2ee33870bac2166d34bc
parent7f372a636d92e21d6fa41aebd6986ef590aefbfc (diff)
perf pmu: Add support for MetricName JSON attribute
Add support for a new JSON event attribute to name MetricExpr for better output in perf stat. If the event has no MetricName it uses the normal event name instead to describe the metric. Before % perf stat -a -I 1000 -e '{unc_p_clockticks,unc_p_freq_max_os_cycles}' --metric-only time unc_p_freq_max_os_cycles 1.000149775 15.7 2.000344807 19.3 3.000502544 16.7 4.000640656 6.6 5.000779955 9.9 After % perf stat -a -I 1000 -e '{unc_p_clockticks,unc_p_freq_max_os_cycles}' --metric-only time freq_max_os_cycles % 1.000149775 15.7 2.000344807 19.3 3.000502544 16.7 4.000640656 6.6 5.000779955 9.9 Signed-off-by: Andi Kleen <ak@linux.intel.com> Acked-by: Jiri Olsa <jolsa@kernel.org> Link: http://lkml.kernel.org/r/20170320201711.14142-13-andi@firstfloor.org Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
-rw-r--r--tools/perf/pmu-events/jevents.c14
-rw-r--r--tools/perf/pmu-events/jevents.h3
-rw-r--r--tools/perf/pmu-events/pmu-events.h1
-rw-r--r--tools/perf/util/evsel.c1
-rw-r--r--tools/perf/util/evsel.h1
-rw-r--r--tools/perf/util/parse-events.c1
-rw-r--r--tools/perf/util/pmu.c15
-rw-r--r--tools/perf/util/pmu.h2
-rw-r--r--tools/perf/util/stat-shadow.c4
9 files changed, 34 insertions, 8 deletions
diff --git a/tools/perf/pmu-events/jevents.c b/tools/perf/pmu-events/jevents.c
index 0735dc2a167a..81f2ef3b15cf 100644
--- a/tools/perf/pmu-events/jevents.c
+++ b/tools/perf/pmu-events/jevents.c
@@ -292,7 +292,8 @@ static void print_events_table_prefix(FILE *fp, const char *tblname)
292static int print_events_table_entry(void *data, char *name, char *event, 292static int print_events_table_entry(void *data, char *name, char *event,
293 char *desc, char *long_desc, 293 char *desc, char *long_desc,
294 char *pmu, char *unit, char *perpkg, 294 char *pmu, char *unit, char *perpkg,
295 char *metric_expr) 295 char *metric_expr,
296 char *metric_name)
296{ 297{
297 struct perf_entry_data *pd = data; 298 struct perf_entry_data *pd = data;
298 FILE *outfp = pd->outfp; 299 FILE *outfp = pd->outfp;
@@ -318,6 +319,8 @@ static int print_events_table_entry(void *data, char *name, char *event,
318 fprintf(outfp, "\t.perpkg = \"%s\",\n", perpkg); 319 fprintf(outfp, "\t.perpkg = \"%s\",\n", perpkg);
319 if (metric_expr) 320 if (metric_expr)
320 fprintf(outfp, "\t.metric_expr = \"%s\",\n", metric_expr); 321 fprintf(outfp, "\t.metric_expr = \"%s\",\n", metric_expr);
322 if (metric_name)
323 fprintf(outfp, "\t.metric_name = \"%s\",\n", metric_name);
321 fprintf(outfp, "},\n"); 324 fprintf(outfp, "},\n");
322 325
323 return 0; 326 return 0;
@@ -366,7 +369,8 @@ int json_events(const char *fn,
366 int (*func)(void *data, char *name, char *event, char *desc, 369 int (*func)(void *data, char *name, char *event, char *desc,
367 char *long_desc, 370 char *long_desc,
368 char *pmu, char *unit, char *perpkg, 371 char *pmu, char *unit, char *perpkg,
369 char *metric_expr), 372 char *metric_expr,
373 char *metric_name),
370 void *data) 374 void *data)
371{ 375{
372 int err = -EIO; 376 int err = -EIO;
@@ -393,6 +397,7 @@ int json_events(const char *fn,
393 char *perpkg = NULL; 397 char *perpkg = NULL;
394 char *unit = NULL; 398 char *unit = NULL;
395 char *metric_expr = NULL; 399 char *metric_expr = NULL;
400 char *metric_name = NULL;
396 unsigned long long eventcode = 0; 401 unsigned long long eventcode = 0;
397 struct msrmap *msr = NULL; 402 struct msrmap *msr = NULL;
398 jsmntok_t *msrval = NULL; 403 jsmntok_t *msrval = NULL;
@@ -469,6 +474,8 @@ int json_events(const char *fn,
469 addfield(map, &unit, "", "", val); 474 addfield(map, &unit, "", "", val);
470 } else if (json_streq(map, field, "PerPkg")) { 475 } else if (json_streq(map, field, "PerPkg")) {
471 addfield(map, &perpkg, "", "", val); 476 addfield(map, &perpkg, "", "", val);
477 } else if (json_streq(map, field, "MetricName")) {
478 addfield(map, &metric_name, "", "", val);
472 } else if (json_streq(map, field, "MetricExpr")) { 479 } else if (json_streq(map, field, "MetricExpr")) {
473 addfield(map, &metric_expr, "", "", val); 480 addfield(map, &metric_expr, "", "", val);
474 for (s = metric_expr; *s; s++) 481 for (s = metric_expr; *s; s++)
@@ -497,7 +504,7 @@ int json_events(const char *fn,
497 fixname(name); 504 fixname(name);
498 505
499 err = func(data, name, real_event(name, event), desc, long_desc, 506 err = func(data, name, real_event(name, event), desc, long_desc,
500 pmu, unit, perpkg, metric_expr); 507 pmu, unit, perpkg, metric_expr, metric_name);
501 free(event); 508 free(event);
502 free(desc); 509 free(desc);
503 free(name); 510 free(name);
@@ -508,6 +515,7 @@ int json_events(const char *fn,
508 free(perpkg); 515 free(perpkg);
509 free(unit); 516 free(unit);
510 free(metric_expr); 517 free(metric_expr);
518 free(metric_name);
511 if (err) 519 if (err)
512 break; 520 break;
513 tok += j; 521 tok += j;
diff --git a/tools/perf/pmu-events/jevents.h b/tools/perf/pmu-events/jevents.h
index 57e111bf2168..611fac01913d 100644
--- a/tools/perf/pmu-events/jevents.h
+++ b/tools/perf/pmu-events/jevents.h
@@ -5,7 +5,8 @@ int json_events(const char *fn,
5 int (*func)(void *data, char *name, char *event, char *desc, 5 int (*func)(void *data, char *name, char *event, char *desc,
6 char *long_desc, 6 char *long_desc,
7 char *pmu, 7 char *pmu,
8 char *unit, char *perpkg, char *metric_expr), 8 char *unit, char *perpkg, char *metric_expr,
9 char *metric_name),
9 void *data); 10 void *data);
10char *get_cpu_str(void); 11char *get_cpu_str(void);
11 12
diff --git a/tools/perf/pmu-events/pmu-events.h b/tools/perf/pmu-events/pmu-events.h
index d046e3a4ce46..569eab3688dd 100644
--- a/tools/perf/pmu-events/pmu-events.h
+++ b/tools/perf/pmu-events/pmu-events.h
@@ -14,6 +14,7 @@ struct pmu_event {
14 const char *unit; 14 const char *unit;
15 const char *perpkg; 15 const char *perpkg;
16 const char *metric_expr; 16 const char *metric_expr;
17 const char *metric_name;
17}; 18};
18 19
19/* 20/*
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
index ef2a31f6dd06..9dc7e2d6e48a 100644
--- a/tools/perf/util/evsel.c
+++ b/tools/perf/util/evsel.c
@@ -237,6 +237,7 @@ void perf_evsel__init(struct perf_evsel *evsel,
237 perf_evsel__calc_id_pos(evsel); 237 perf_evsel__calc_id_pos(evsel);
238 evsel->cmdline_group_boundary = false; 238 evsel->cmdline_group_boundary = false;
239 evsel->metric_expr = NULL; 239 evsel->metric_expr = NULL;
240 evsel->metric_name = NULL;
240 evsel->metric_events = NULL; 241 evsel->metric_events = NULL;
241 evsel->collect_stat = false; 242 evsel->collect_stat = false;
242} 243}
diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h
index 8f1f61826fdf..d101695c482c 100644
--- a/tools/perf/util/evsel.h
+++ b/tools/perf/util/evsel.h
@@ -133,6 +133,7 @@ struct perf_evsel {
133 int bpf_fd; 133 int bpf_fd;
134 bool merged_stat; 134 bool merged_stat;
135 const char * metric_expr; 135 const char * metric_expr;
136 const char * metric_name;
136 struct perf_evsel **metric_events; 137 struct perf_evsel **metric_events;
137 bool collect_stat; 138 bool collect_stat;
138}; 139};
diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c
index 91b8e83e307d..119eb0b65876 100644
--- a/tools/perf/util/parse-events.c
+++ b/tools/perf/util/parse-events.c
@@ -1256,6 +1256,7 @@ int parse_events_add_pmu(struct parse_events_evlist *data,
1256 evsel->per_pkg = info.per_pkg; 1256 evsel->per_pkg = info.per_pkg;
1257 evsel->snapshot = info.snapshot; 1257 evsel->snapshot = info.snapshot;
1258 evsel->metric_expr = info.metric_expr; 1258 evsel->metric_expr = info.metric_expr;
1259 evsel->metric_name = info.metric_name;
1259 } 1260 }
1260 1261
1261 return evsel ? 0 : -ENOMEM; 1262 return evsel ? 0 : -ENOMEM;
diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c
index f819ad162b7c..bcf752fa345b 100644
--- a/tools/perf/util/pmu.c
+++ b/tools/perf/util/pmu.c
@@ -232,7 +232,8 @@ static int __perf_pmu__new_alias(struct list_head *list, char *dir, char *name,
232 char *desc, char *val, 232 char *desc, char *val,
233 char *long_desc, char *topic, 233 char *long_desc, char *topic,
234 char *unit, char *perpkg, 234 char *unit, char *perpkg,
235 char *metric_expr) 235 char *metric_expr,
236 char *metric_name)
236{ 237{
237 struct perf_pmu_alias *alias; 238 struct perf_pmu_alias *alias;
238 int ret; 239 int ret;
@@ -267,6 +268,7 @@ static int __perf_pmu__new_alias(struct list_head *list, char *dir, char *name,
267 } 268 }
268 269
269 alias->metric_expr = metric_expr ? strdup(metric_expr) : NULL; 270 alias->metric_expr = metric_expr ? strdup(metric_expr) : NULL;
271 alias->metric_name = metric_name ? strdup(metric_name): NULL;
270 alias->desc = desc ? strdup(desc) : NULL; 272 alias->desc = desc ? strdup(desc) : NULL;
271 alias->long_desc = long_desc ? strdup(long_desc) : 273 alias->long_desc = long_desc ? strdup(long_desc) :
272 desc ? strdup(desc) : NULL; 274 desc ? strdup(desc) : NULL;
@@ -296,7 +298,7 @@ static int perf_pmu__new_alias(struct list_head *list, char *dir, char *name, FI
296 buf[ret] = 0; 298 buf[ret] = 0;
297 299
298 return __perf_pmu__new_alias(list, dir, name, NULL, buf, NULL, NULL, NULL, 300 return __perf_pmu__new_alias(list, dir, name, NULL, buf, NULL, NULL, NULL,
299 NULL, NULL); 301 NULL, NULL, NULL);
300} 302}
301 303
302static inline bool pmu_alias_info_file(char *name) 304static inline bool pmu_alias_info_file(char *name)
@@ -567,7 +569,8 @@ static void pmu_add_cpu_aliases(struct list_head *head, const char *name)
567 (char *)pe->desc, (char *)pe->event, 569 (char *)pe->desc, (char *)pe->event,
568 (char *)pe->long_desc, (char *)pe->topic, 570 (char *)pe->long_desc, (char *)pe->topic,
569 (char *)pe->unit, (char *)pe->perpkg, 571 (char *)pe->unit, (char *)pe->perpkg,
570 (char *)pe->metric_expr); 572 (char *)pe->metric_expr,
573 (char *)pe->metric_name);
571 } 574 }
572 575
573out: 576out:
@@ -995,6 +998,7 @@ int perf_pmu__check_alias(struct perf_pmu *pmu, struct list_head *head_terms,
995 info->scale = 0.0; 998 info->scale = 0.0;
996 info->snapshot = false; 999 info->snapshot = false;
997 info->metric_expr = NULL; 1000 info->metric_expr = NULL;
1001 info->metric_name = NULL;
998 1002
999 list_for_each_entry_safe(term, h, head_terms, list) { 1003 list_for_each_entry_safe(term, h, head_terms, list) {
1000 alias = pmu_find_alias(pmu, term); 1004 alias = pmu_find_alias(pmu, term);
@@ -1011,6 +1015,7 @@ int perf_pmu__check_alias(struct perf_pmu *pmu, struct list_head *head_terms,
1011 if (alias->per_pkg) 1015 if (alias->per_pkg)
1012 info->per_pkg = true; 1016 info->per_pkg = true;
1013 info->metric_expr = alias->metric_expr; 1017 info->metric_expr = alias->metric_expr;
1018 info->metric_name = alias->metric_name;
1014 1019
1015 list_del(&term->list); 1020 list_del(&term->list);
1016 free(term); 1021 free(term);
@@ -1106,6 +1111,7 @@ struct sevent {
1106 char *str; 1111 char *str;
1107 char *pmu; 1112 char *pmu;
1108 char *metric_expr; 1113 char *metric_expr;
1114 char *metric_name;
1109}; 1115};
1110 1116
1111static int cmp_sevent(const void *a, const void *b) 1117static int cmp_sevent(const void *a, const void *b)
@@ -1205,6 +1211,7 @@ void print_pmu_events(const char *event_glob, bool name_only, bool quiet_flag,
1205 aliases[j].str = alias->str; 1211 aliases[j].str = alias->str;
1206 aliases[j].pmu = pmu->name; 1212 aliases[j].pmu = pmu->name;
1207 aliases[j].metric_expr = alias->metric_expr; 1213 aliases[j].metric_expr = alias->metric_expr;
1214 aliases[j].metric_name = alias->metric_name;
1208 j++; 1215 j++;
1209 } 1216 }
1210 if (pmu->selectable && 1217 if (pmu->selectable &&
@@ -1241,6 +1248,8 @@ void print_pmu_events(const char *event_glob, bool name_only, bool quiet_flag,
1241 printf("]\n"); 1248 printf("]\n");
1242 if (verbose > 0) { 1249 if (verbose > 0) {
1243 printf("%*s%s/%s/ ", 8, "", aliases[j].pmu, aliases[j].str); 1250 printf("%*s%s/%s/ ", 8, "", aliases[j].pmu, aliases[j].str);
1251 if (aliases[j].metric_name)
1252 printf(" MetricName: %s", aliases[j].metric_name);
1244 if (aliases[j].metric_expr) 1253 if (aliases[j].metric_expr)
1245 printf(" MetricExpr: %s", aliases[j].metric_expr); 1254 printf(" MetricExpr: %s", aliases[j].metric_expr);
1246 putchar('\n'); 1255 putchar('\n');
diff --git a/tools/perf/util/pmu.h b/tools/perf/util/pmu.h
index 27f078ccc594..3d4b703f5d89 100644
--- a/tools/perf/util/pmu.h
+++ b/tools/perf/util/pmu.h
@@ -32,6 +32,7 @@ struct perf_pmu {
32struct perf_pmu_info { 32struct perf_pmu_info {
33 const char *unit; 33 const char *unit;
34 const char *metric_expr; 34 const char *metric_expr;
35 const char *metric_name;
35 double scale; 36 double scale;
36 bool per_pkg; 37 bool per_pkg;
37 bool snapshot; 38 bool snapshot;
@@ -52,6 +53,7 @@ struct perf_pmu_alias {
52 bool per_pkg; 53 bool per_pkg;
53 bool snapshot; 54 bool snapshot;
54 char *metric_expr; 55 char *metric_expr;
56 char *metric_name;
55}; 57};
56 58
57struct perf_pmu *perf_pmu__find(const char *name); 59struct perf_pmu *perf_pmu__find(const char *name);
diff --git a/tools/perf/util/stat-shadow.c b/tools/perf/util/stat-shadow.c
index c323cce97d98..ac10cc675d39 100644
--- a/tools/perf/util/stat-shadow.c
+++ b/tools/perf/util/stat-shadow.c
@@ -803,7 +803,9 @@ void perf_stat__print_shadow_stats(struct perf_evsel *evsel,
803 803
804 if (expr__parse(&ratio, &pctx, &p) == 0) 804 if (expr__parse(&ratio, &pctx, &p) == 0)
805 print_metric(ctxp, NULL, "%8.1f", 805 print_metric(ctxp, NULL, "%8.1f",
806 out->force_header ? evsel->name : "", 806 evsel->metric_name ?
807 evsel->metric_name :
808 out->force_header ? evsel->name : "",
807 ratio); 809 ratio);
808 else 810 else
809 print_metric(ctxp, NULL, NULL, "", 0); 811 print_metric(ctxp, NULL, NULL, "", 0);