summaryrefslogtreecommitdiffstats
path: root/tools/perf/util/pmu.c
diff options
context:
space:
mode:
authorAndi Kleen <ak@linux.intel.com>2017-01-28 03:03:37 +0100
committerArnaldo Carvalho de Melo <acme@redhat.com>2017-02-08 12:55:03 +0100
commitfedb2b518239cbc00abcf0d200e0be8436251c11 (patch)
tree8ab7fa4997f4b77d10f80bef73cdbdb550330998 /tools/perf/util/pmu.c
parentperf jevents: Parse eventcode as number (diff)
downloadlinux-fedb2b518239cbc00abcf0d200e0be8436251c11.tar.xz
linux-fedb2b518239cbc00abcf0d200e0be8436251c11.zip
perf jevents: Add support for parsing uncore json files
Handle the "Unit" field, which is needed to find the right PMU for an event. We call it "pmu" and convert it to the perf pmu name with an uncore prefix. Handle the "ExtSel" field, which just extends the event mask with an additional bit. Handle the "Filter" field which adds parameters to the main event to configure filtering. Handle the "Unit" field which declares the unit the values should be scaled too (similar to what the kernel exports) Set up the "perpkg" field for uncore events so that perf knows they are per package (similar to what the kernel exports) Then output the fields into the pmu-events data structures which are compiled into perf. Filter out zero fields, except for the event itself. v2: Fix compilation. Add uncore_ prefix at pre-processing time. Move eventcode change to separate patch. v3: Remove extra __maybe_unused v4: dont duplicate aliases for cpu pmu events Signed-off-by: Andi Kleen <ak@linux.intel.com> Acked-by: Jiri Olsa <jolsa@kernel.org> Link: http://lkml.kernel.org/r/20170128020345.19007-3-andi@firstfloor.org Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools/perf/util/pmu.c')
-rw-r--r--tools/perf/util/pmu.c30
1 files changed, 22 insertions, 8 deletions
diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c
index 78b16100567d..6dc3cc050105 100644
--- a/tools/perf/util/pmu.c
+++ b/tools/perf/util/pmu.c
@@ -229,11 +229,13 @@ 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 *desc, char *val,
+ char *long_desc, char *topic,
+ char *unit, char *perpkg)
{
struct perf_pmu_alias *alias;
int ret;
+ int num;
alias = malloc(sizeof(*alias));
if (!alias)
@@ -267,7 +269,12 @@ static int __perf_pmu__new_alias(struct list_head *list, char *dir, char *name,
alias->long_desc = long_desc ? strdup(long_desc) :
desc ? strdup(desc) : NULL;
alias->topic = topic ? strdup(topic) : NULL;
-
+ if (unit) {
+ if (convert_scale(unit, &unit, &alias->scale) < 0)
+ return -1;
+ snprintf(alias->unit, sizeof(alias->unit), "%s", unit);
+ }
+ alias->per_pkg = perpkg && sscanf(perpkg, "%d", &num) == 1 && num == 1;
list_add_tail(&alias->list, list);
return 0;
@@ -284,7 +291,8 @@ 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);
+ return __perf_pmu__new_alias(list, dir, name, NULL, buf, NULL, NULL, NULL,
+ NULL);
}
static inline bool pmu_alias_info_file(char *name)
@@ -504,7 +512,7 @@ char * __weak get_cpuid_str(void)
* to the current running CPU. Then, add all PMU events from that table
* as aliases.
*/
-static void pmu_add_cpu_aliases(struct list_head *head)
+static void pmu_add_cpu_aliases(struct list_head *head, const char *name)
{
int i;
struct pmu_events_map *map;
@@ -540,14 +548,21 @@ static void pmu_add_cpu_aliases(struct list_head *head)
*/
i = 0;
while (1) {
+ const char *pname;
+
pe = &map->table[i++];
if (!pe->name)
break;
+ pname = pe->pmu ? pe->pmu : "cpu";
+ if (strncmp(pname, name, strlen(pname)))
+ continue;
+
/* need type casts to override 'const' */
__perf_pmu__new_alias(head, NULL, (char *)pe->name,
(char *)pe->desc, (char *)pe->event,
- (char *)pe->long_desc, (char *)pe->topic);
+ (char *)pe->long_desc, (char *)pe->topic,
+ (char *)pe->unit, (char *)pe->perpkg);
}
out:
@@ -578,8 +593,7 @@ static struct perf_pmu *pmu_lookup(const char *name)
if (pmu_aliases(name, &aliases))
return NULL;
- if (!strcmp(name, "cpu"))
- pmu_add_cpu_aliases(&aliases);
+ pmu_add_cpu_aliases(&aliases, name);
if (pmu_type(name, &type))
return NULL;