FAILED: patch "[PATCH] perf pmu: Unbreak perf record for arm/arm64 with events with" failed to apply to 4.13-stable tree
Subsystems (2)
[email protected]
maintainerThe patch below does not apply to the 4.13-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
Quoted 1 line
From
66ec11919a0f96e936bb731fdbc2851316077d26Mon Sep 17 00:00:00 2001
From: Mark Rutland <[email protected]>
Date: Fri, 6 Oct 2017 19:38:22 +0100
Subject: [PATCH] perf pmu: Unbreak perf record for arm/arm64 with events with
explicit PMU
Currently, perf record is broken on arm/arm64 systems when the PMU is specified explicitly as part of the event, e.g.
$ ./perf record -e armv8_cortex_a53/cpu_cycles/u true
In such cases, perf record fails to open events unless perf_event_paranoid is set to -1, even if the PMU in question supports mode exclusion. Further, even when perf_event_paranoid is toggled, no samples are recorded.
This is an unintended side effect of commit:
e3ba76deef23064f ("perf tools: Force uncore events to system wide monitoring)
... which assumes that if a PMU has an associated cpu_map, it is an uncore PMU, and forces events for such PMUs to be system-wide.
This is not true for arm/arm64 systems, which can have heterogeneous CPUs. To account for this, multiple CPU PMUs are exposed, each with a "cpus" field under sysfs, which the perf tool parses into a cpu_map. ARM PMUs do not have a "cpumask" file, and only have a "cpus" file. For the gory details as to why, see commit:
7e3fcffe95544010 ("perf pmu: Support alternative sysfs cpumask")
Given all of this, we can instead identify uncore PMUs by explicitly checking for a "cpumask" file, and restore arm/arm64 PMU support back to a working state. This patch does so, adding a new perf_pmu::is_uncore field, and splitting the existing cpumask parsing so that it can be reused.
Tested-by Will Deacon <[email protected]>
tools/perf/util/parse-events.c +5 -4
@@ -309,10 +309,11 @@ static char *get_config_name(struct list_head *head_terms)static struct perf_evsel *__add_event (struct list_head *list,int *idx,struct perf_event_attr *attr, -char *name,struct cpu_map *cpus, +char *name,struct perf_pmu *pmu,struct list_head *config_terms,bool auto_merge_stats) {struct perf_evsel *evsel; +struct cpu_map *cpus = pmu ? pmu->cpus :NULL ;event_attr_init (attr);
@@ -323,7 +324,7 @@ __add_event(struct list_head *list, int *idx, (*idx)++; evsel->cpus =cpu_map__get (cpus); evsel->own_cpus =cpu_map__get (cpus); - evsel->system_wide = !!cpus; + evsel->system_wide = pmu ? pmu->is_uncore : false; evsel->auto_merge_stats = auto_merge_stats;if (name)
@@ -1233,7 +1234,7 @@ static int __parse_events_add_pmu(struct parse_events_state *parse_state,if (!head_config) { attr.type = pmu->type; - evsel =__add_event (list, &parse_state->idx, &attr,NULL , pmu->cpus,NULL , auto_merge_stats); + evsel =__add_event (list, &parse_state->idx, &attr,NULL , pmu,NULL , auto_merge_stats);return evsel ?0 : -ENOMEM ; }
@@ -1254,7 +1255,7 @@ static int __parse_events_add_pmu(struct parse_events_state *parse_state,return -EINVAL ; evsel =__add_event (list, &parse_state->idx, &attr, -get_config_name (head_config), pmu->cpus, +get_config_name (head_config), pmu, &config_terms, auto_merge_stats);if (evsel) { evsel->unit = info.unit;
tools/perf/util/pmu.c +41 -15
84 lines not on this page · raw message
tools/perf/util/pmu.h +1 -0
@@ -22,6 +22,7 @@ struct perf_pmu {char *name;__u32 type;bool selectable; +bool is_uncore;struct perf_event_attr *default_config;struct cpu_map *cpus;struct list_head format;/* HEAD struct perf_pmu_format -> list */