perf pmu: Support MetricExpr header in JSON event list
authorAndi Kleen <ak@linux.intel.com>
Mon, 20 Mar 2017 20:17:07 +0000 (13:17 -0700)
committerArnaldo Carvalho de Melo <acme@redhat.com>
Thu, 23 Mar 2017 14:42:29 +0000 (11:42 -0300)
Add support for parsing the MetricExpr header in the JSON event lists
and storing them in the alias structure.

Used in the next patch.

v2: Change DividedBy to MetricExpr
v3: Really catch all uses of DividedBy

Signed-off-by: Andi Kleen <ak@linux.intel.com>
Acked-by: Jiri Olsa <jolsa@kernel.org>
Link: http://lkml.kernel.org/r/20170320201711.14142-10-andi@firstfloor.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
tools/perf/pmu-events/jevents.c
tools/perf/pmu-events/jevents.h
tools/perf/pmu-events/pmu-events.h
tools/perf/util/pmu.c
tools/perf/util/pmu.h

index eed09346a72afab1ede36b7b3b507f3dc5d62a84..0735dc2a167a44b6e1954f0feeb9e4cc82aa190a 100644 (file)
@@ -291,7 +291,8 @@ static void print_events_table_prefix(FILE *fp, const char *tblname)
 
 static int print_events_table_entry(void *data, char *name, char *event,
                                    char *desc, char *long_desc,
-                                   char *pmu, char *unit, char *perpkg)
+                                   char *pmu, char *unit, char *perpkg,
+                                   char *metric_expr)
 {
        struct perf_entry_data *pd = data;
        FILE *outfp = pd->outfp;
@@ -315,6 +316,8 @@ static int print_events_table_entry(void *data, char *name, char *event,
                fprintf(outfp, "\t.unit = \"%s\",\n", unit);
        if (perpkg)
                fprintf(outfp, "\t.perpkg = \"%s\",\n", perpkg);
+       if (metric_expr)
+               fprintf(outfp, "\t.metric_expr = \"%s\",\n", metric_expr);
        fprintf(outfp, "},\n");
 
        return 0;
@@ -362,7 +365,8 @@ static char *real_event(const char *name, char *event)
 int json_events(const char *fn,
          int (*func)(void *data, char *name, char *event, char *desc,
                      char *long_desc,
-                     char *pmu, char *unit, char *perpkg),
+                     char *pmu, char *unit, char *perpkg,
+                     char *metric_expr),
          void *data)
 {
        int err = -EIO;
@@ -388,6 +392,7 @@ int json_events(const char *fn,
                char *filter = NULL;
                char *perpkg = NULL;
                char *unit = NULL;
+               char *metric_expr = NULL;
                unsigned long long eventcode = 0;
                struct msrmap *msr = NULL;
                jsmntok_t *msrval = NULL;
@@ -398,6 +403,7 @@ int json_events(const char *fn,
                for (j = 0; j < obj->size; j += 2) {
                        jsmntok_t *field, *val;
                        int nz;
+                       char *s;
 
                        field = tok + j;
                        EXPECT(field->type == JSMN_STRING, tok + j,
@@ -444,7 +450,6 @@ int json_events(const char *fn,
                                        NULL);
                        } else if (json_streq(map, field, "Unit")) {
                                const char *ppmu;
-                               char *s;
 
                                ppmu = field_to_perf(unit_to_pmu, map, val);
                                if (ppmu) {
@@ -464,6 +469,10 @@ int json_events(const char *fn,
                                addfield(map, &unit, "", "", val);
                        } else if (json_streq(map, field, "PerPkg")) {
                                addfield(map, &perpkg, "", "", val);
+                       } else if (json_streq(map, field, "MetricExpr")) {
+                               addfield(map, &metric_expr, "", "", val);
+                               for (s = metric_expr; *s; s++)
+                                       *s = tolower(*s);
                        }
                        /* ignore unknown fields */
                }
@@ -488,7 +497,7 @@ int json_events(const char *fn,
                fixname(name);
 
                err = func(data, name, real_event(name, event), desc, long_desc,
-                               pmu, unit, perpkg);
+                               pmu, unit, perpkg, metric_expr);
                free(event);
                free(desc);
                free(name);
@@ -498,6 +507,7 @@ int json_events(const char *fn,
                free(filter);
                free(perpkg);
                free(unit);
+               free(metric_expr);
                if (err)
                        break;
                tok += j;
index 71e13de31092f2de94827573f4e4dc537df8b726..57e111bf216864368c613ec28454e986f59a35e1 100644 (file)
@@ -5,7 +5,7 @@ int json_events(const char *fn,
                int (*func)(void *data, char *name, char *event, char *desc,
                                char *long_desc,
                                char *pmu,
-                               char *unit, char *perpkg),
+                               char *unit, char *perpkg, char *metric_expr),
                void *data);
 char *get_cpu_str(void);
 
index c669a3cdb9f0279c96caa80cf68aab2862e202a9..d046e3a4ce46f1e0c4fc8bb0db7353eebb35f029 100644 (file)
@@ -13,6 +13,7 @@ struct pmu_event {
        const char *pmu;
        const char *unit;
        const char *perpkg;
+       const char *metric_expr;
 };
 
 /*
index 12f84dd2ac5dfddc9f7e124fa25b5da4bb2be021..c0d487b3b925b2852252447c512c4d9d2c6cedb6 100644 (file)
@@ -231,7 +231,8 @@ static int perf_pmu__parse_snapshot(struct perf_pmu_alias *alias,
 static int __perf_pmu__new_alias(struct list_head *list, char *dir, char *name,
                                 char *desc, char *val,
                                 char *long_desc, char *topic,
-                                char *unit, char *perpkg)
+                                char *unit, char *perpkg,
+                                char *metric_expr)
 {
        struct perf_pmu_alias *alias;
        int ret;
@@ -265,6 +266,7 @@ static int __perf_pmu__new_alias(struct list_head *list, char *dir, char *name,
                perf_pmu__parse_snapshot(alias, dir, name);
        }
 
+       alias->metric_expr = metric_expr ? strdup(metric_expr) : NULL;
        alias->desc = desc ? strdup(desc) : NULL;
        alias->long_desc = long_desc ? strdup(long_desc) :
                                desc ? strdup(desc) : NULL;
@@ -294,7 +296,7 @@ static int perf_pmu__new_alias(struct list_head *list, char *dir, char *name, FI
        buf[ret] = 0;
 
        return __perf_pmu__new_alias(list, dir, name, NULL, buf, NULL, NULL, NULL,
-                                    NULL);
+                                    NULL, NULL);
 }
 
 static inline bool pmu_alias_info_file(char *name)
@@ -564,7 +566,8 @@ static void pmu_add_cpu_aliases(struct list_head *head, const char *name)
                __perf_pmu__new_alias(head, NULL, (char *)pe->name,
                                (char *)pe->desc, (char *)pe->event,
                                (char *)pe->long_desc, (char *)pe->topic,
-                               (char *)pe->unit, (char *)pe->perpkg);
+                               (char *)pe->unit, (char *)pe->perpkg,
+                               (char *)pe->metric_expr);
        }
 
 out:
index 00852ddc7741b068e212adf2eb3e5e2b0c56c872..3dccb15f29e9a5e3e240f13f8b7d10450653d690 100644 (file)
@@ -50,6 +50,7 @@ struct perf_pmu_alias {
        double scale;
        bool per_pkg;
        bool snapshot;
+       char *metric_expr;
 };
 
 struct perf_pmu *perf_pmu__find(const char *name);