diff options
author | Stephane Eranian <eranian@google.com> | 2015-01-13 17:59:53 -0500 |
---|---|---|
committer | Ingo Molnar <mingo@kernel.org> | 2015-01-16 03:06:58 -0500 |
commit | 433678bdc6ed39f053c55da96b51de5bf0aeebb1 (patch) | |
tree | 4f8d1cb9a64d8d4f6b8836099c40d666553ba592 /arch | |
parent | f800c25b7a762d445ba1439a2428c8362157eba6 (diff) |
perf/rapl: Fix sysfs_show() initialization for RAPL PMU
This patch fixes a problem with the initialization of the
sysfs_show() routine for the RAPL PMU.
The current code was wrongly relying on the EVENT_ATTR_STR()
macro which uses the events_sysfs_show() function in the x86
PMU code. That function itself was relying on the x86_pmu data
structure. Yet RAPL and the core PMU (x86_pmu) have nothing to
do with each other. They should therefore not interact with
each other.
The x86_pmu structure is initialized at boot time based on
the host CPU model. When the host CPU is not supported, the
x86_pmu remains uninitialized and some of the callbacks it
contains are NULL.
The false dependency with x86_pmu could potentially cause crashes
in case the x86_pmu is not initialized while the RAPL PMU is. This
may, for instance, be the case in virtualized environments.
This patch fixes the problem by using a private sysfs_show()
routine for exporting the RAPL PMU events.
Signed-off-by: Stephane Eranian <eranian@google.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Link: http://lkml.kernel.org/r/20150113225953.GA21525@thinkpad
Cc: vincent.weaver@maine.edu
Cc: jolsa@redhat.com
Cc: Arnaldo Carvalho de Melo <acme@kernel.org>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/x86/kernel/cpu/perf_event_intel_rapl.c | 44 |
1 files changed, 32 insertions, 12 deletions
diff --git a/arch/x86/kernel/cpu/perf_event_intel_rapl.c b/arch/x86/kernel/cpu/perf_event_intel_rapl.c index 673f930c700f..6e434f8e5fc8 100644 --- a/arch/x86/kernel/cpu/perf_event_intel_rapl.c +++ b/arch/x86/kernel/cpu/perf_event_intel_rapl.c | |||
@@ -103,6 +103,13 @@ static struct kobj_attribute format_attr_##_var = \ | |||
103 | 103 | ||
104 | #define RAPL_CNTR_WIDTH 32 /* 32-bit rapl counters */ | 104 | #define RAPL_CNTR_WIDTH 32 /* 32-bit rapl counters */ |
105 | 105 | ||
106 | #define RAPL_EVENT_ATTR_STR(_name, v, str) \ | ||
107 | static struct perf_pmu_events_attr event_attr_##v = { \ | ||
108 | .attr = __ATTR(_name, 0444, rapl_sysfs_show, NULL), \ | ||
109 | .id = 0, \ | ||
110 | .event_str = str, \ | ||
111 | }; | ||
112 | |||
106 | struct rapl_pmu { | 113 | struct rapl_pmu { |
107 | spinlock_t lock; | 114 | spinlock_t lock; |
108 | int hw_unit; /* 1/2^hw_unit Joule */ | 115 | int hw_unit; /* 1/2^hw_unit Joule */ |
@@ -379,23 +386,36 @@ static struct attribute_group rapl_pmu_attr_group = { | |||
379 | .attrs = rapl_pmu_attrs, | 386 | .attrs = rapl_pmu_attrs, |
380 | }; | 387 | }; |
381 | 388 | ||
382 | EVENT_ATTR_STR(energy-cores, rapl_cores, "event=0x01"); | 389 | static ssize_t rapl_sysfs_show(struct device *dev, |
383 | EVENT_ATTR_STR(energy-pkg , rapl_pkg, "event=0x02"); | 390 | struct device_attribute *attr, |
384 | EVENT_ATTR_STR(energy-ram , rapl_ram, "event=0x03"); | 391 | char *page) |
385 | EVENT_ATTR_STR(energy-gpu , rapl_gpu, "event=0x04"); | 392 | { |
393 | struct perf_pmu_events_attr *pmu_attr = \ | ||
394 | container_of(attr, struct perf_pmu_events_attr, attr); | ||
395 | |||
396 | if (pmu_attr->event_str) | ||
397 | return sprintf(page, "%s", pmu_attr->event_str); | ||
398 | |||
399 | return 0; | ||
400 | } | ||
401 | |||
402 | RAPL_EVENT_ATTR_STR(energy-cores, rapl_cores, "event=0x01"); | ||
403 | RAPL_EVENT_ATTR_STR(energy-pkg , rapl_pkg, "event=0x02"); | ||
404 | RAPL_EVENT_ATTR_STR(energy-ram , rapl_ram, "event=0x03"); | ||
405 | RAPL_EVENT_ATTR_STR(energy-gpu , rapl_gpu, "event=0x04"); | ||
386 | 406 | ||
387 | EVENT_ATTR_STR(energy-cores.unit, rapl_cores_unit, "Joules"); | 407 | RAPL_EVENT_ATTR_STR(energy-cores.unit, rapl_cores_unit, "Joules"); |
388 | EVENT_ATTR_STR(energy-pkg.unit , rapl_pkg_unit, "Joules"); | 408 | RAPL_EVENT_ATTR_STR(energy-pkg.unit , rapl_pkg_unit, "Joules"); |
389 | EVENT_ATTR_STR(energy-ram.unit , rapl_ram_unit, "Joules"); | 409 | RAPL_EVENT_ATTR_STR(energy-ram.unit , rapl_ram_unit, "Joules"); |
390 | EVENT_ATTR_STR(energy-gpu.unit , rapl_gpu_unit, "Joules"); | 410 | RAPL_EVENT_ATTR_STR(energy-gpu.unit , rapl_gpu_unit, "Joules"); |
391 | 411 | ||
392 | /* | 412 | /* |
393 | * we compute in 0.23 nJ increments regardless of MSR | 413 | * we compute in 0.23 nJ increments regardless of MSR |
394 | */ | 414 | */ |
395 | EVENT_ATTR_STR(energy-cores.scale, rapl_cores_scale, "2.3283064365386962890625e-10"); | 415 | RAPL_EVENT_ATTR_STR(energy-cores.scale, rapl_cores_scale, "2.3283064365386962890625e-10"); |
396 | EVENT_ATTR_STR(energy-pkg.scale, rapl_pkg_scale, "2.3283064365386962890625e-10"); | 416 | RAPL_EVENT_ATTR_STR(energy-pkg.scale, rapl_pkg_scale, "2.3283064365386962890625e-10"); |
397 | EVENT_ATTR_STR(energy-ram.scale, rapl_ram_scale, "2.3283064365386962890625e-10"); | 417 | RAPL_EVENT_ATTR_STR(energy-ram.scale, rapl_ram_scale, "2.3283064365386962890625e-10"); |
398 | EVENT_ATTR_STR(energy-gpu.scale, rapl_gpu_scale, "2.3283064365386962890625e-10"); | 418 | RAPL_EVENT_ATTR_STR(energy-gpu.scale, rapl_gpu_scale, "2.3283064365386962890625e-10"); |
399 | 419 | ||
400 | static struct attribute *rapl_events_srv_attr[] = { | 420 | static struct attribute *rapl_events_srv_attr[] = { |
401 | EVENT_PTR(rapl_cores), | 421 | EVENT_PTR(rapl_cores), |