[RFCv2 4/4] perf: util: support sysfs supported_cpumask file

From: Mark Rutland
Date: Fri Jul 15 2016 - 06:08:51 EST


For system PMUs, the perf tools have long expected a cpumask file under
sysfs, describing the single CPU which they support events being
opened/handled on. Prior patches in this series have reworked this
support to support multiple CPUs in a mask, as is required to handle
heterogeneous CPU PMUs.

Unfortunately, adding a cpumask file to CPU PMUs would break existing
userspace. Prior to this series, perf record will refuse to open events,
and perf stat may unexpectedly block at exit time. In the absence of a
cpumask, perf stat is functional.

To address this, this patch adds support for a new file,
supported_cpumask, which can be used to describe heterogeneous CPUs,
without the risk of breaking existing userspace binaries.

Signed-off-by: Mark Rutland <mark.rutland@xxxxxxx>
---
tools/perf/util/pmu.c | 15 ++++++++++++---
1 file changed, 12 insertions(+), 3 deletions(-)

diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c
index ddb0261..06c985c 100644
--- a/tools/perf/util/pmu.c
+++ b/tools/perf/util/pmu.c
@@ -445,14 +445,23 @@ static struct cpu_map *pmu_cpumask(const char *name)
FILE *file;
struct cpu_map *cpus;
const char *sysfs = sysfs__mountpoint();
+ const char *path_template[] = {
+ "%s/bus/event_source/devices/%s/cpumask",
+ "%s/bus/event_source/devices/%s/supported_cpumask",
+ NULL
+ };
+ unsigned int i;

if (!sysfs)
return NULL;

- snprintf(path, PATH_MAX,
- "%s/bus/event_source/devices/%s/cpumask", sysfs, name);
+ for (i = 0; i < ARRAY_SIZE(path_template); i++) {
+ snprintf(path, PATH_MAX, *path_template, sysfs, name);
+ if (stat(path, &st) == 0)
+ break;
+ }

- if (stat(path, &st) < 0)
+ if (!*path_template)
return NULL;

file = fopen(path, "r");
--
1.9.1