diff options
| author | Stephane Eranian <eranian@google.com> | 2013-01-24 10:10:26 -0500 |
|---|---|---|
| committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2013-03-26 16:36:45 -0400 |
| commit | 3a54aaa0a3ddb2cf2ec1b94a94024e9a8a8af962 (patch) | |
| tree | b9667eba20bd202f6bd6a6afeaeb18ba58ba24c2 | |
| parent | 1a6461b12872e9622c231928e1620504d741cc79 (diff) | |
perf/x86: Improve sysfs event mapping with event string
This patch extends Jiri's changes to make generic
events mapping visible via sysfs. The patch extends
the mechanism to non-generic events by allowing
the mappings to be hardcoded in strings.
This mechanism will be used by the PEBS-LL patch
later on.
Signed-off-by: Stephane Eranian <eranian@google.com>
Cc: peterz@infradead.org
Cc: ak@linux.intel.com
Cc: acme@redhat.com
Cc: jolsa@redhat.com
Cc: namhyung.kim@lge.com
Link: http://lkml.kernel.org/r/1359040242-8269-3-git-send-email-eranian@google.com
Signed-off-by: Ingo Molnar <mingo@kernel.org>
[ fixed up conflict with 2663960 "perf: Make EVENT_ATTR global" ]
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
| -rw-r--r-- | arch/x86/kernel/cpu/perf_event.c | 20 | ||||
| -rw-r--r-- | arch/x86/kernel/cpu/perf_event.h | 17 | ||||
| -rw-r--r-- | include/linux/perf_event.h | 1 |
3 files changed, 30 insertions, 8 deletions
diff --git a/arch/x86/kernel/cpu/perf_event.c b/arch/x86/kernel/cpu/perf_event.c index c886dc8c63f8..6e8ab0427041 100644 --- a/arch/x86/kernel/cpu/perf_event.c +++ b/arch/x86/kernel/cpu/perf_event.c | |||
| @@ -1316,9 +1316,16 @@ static struct attribute_group x86_pmu_format_group = { | |||
| 1316 | */ | 1316 | */ |
| 1317 | static void __init filter_events(struct attribute **attrs) | 1317 | static void __init filter_events(struct attribute **attrs) |
| 1318 | { | 1318 | { |
| 1319 | struct device_attribute *d; | ||
| 1320 | struct perf_pmu_events_attr *pmu_attr; | ||
| 1319 | int i, j; | 1321 | int i, j; |
| 1320 | 1322 | ||
| 1321 | for (i = 0; attrs[i]; i++) { | 1323 | for (i = 0; attrs[i]; i++) { |
| 1324 | d = (struct device_attribute *)attrs[i]; | ||
| 1325 | pmu_attr = container_of(d, struct perf_pmu_events_attr, attr); | ||
| 1326 | /* str trumps id */ | ||
| 1327 | if (pmu_attr->event_str) | ||
| 1328 | continue; | ||
| 1322 | if (x86_pmu.event_map(i)) | 1329 | if (x86_pmu.event_map(i)) |
| 1323 | continue; | 1330 | continue; |
| 1324 | 1331 | ||
| @@ -1361,17 +1368,14 @@ static ssize_t events_sysfs_show(struct device *dev, struct device_attribute *at | |||
| 1361 | { | 1368 | { |
| 1362 | struct perf_pmu_events_attr *pmu_attr = \ | 1369 | struct perf_pmu_events_attr *pmu_attr = \ |
| 1363 | container_of(attr, struct perf_pmu_events_attr, attr); | 1370 | container_of(attr, struct perf_pmu_events_attr, attr); |
| 1364 | |||
| 1365 | u64 config = x86_pmu.event_map(pmu_attr->id); | 1371 | u64 config = x86_pmu.event_map(pmu_attr->id); |
| 1366 | return x86_pmu.events_sysfs_show(page, config); | ||
| 1367 | } | ||
| 1368 | 1372 | ||
| 1369 | #define EVENT_VAR(_id) event_attr_##_id | 1373 | /* string trumps id */ |
| 1370 | #define EVENT_PTR(_id) &event_attr_##_id.attr.attr | 1374 | if (pmu_attr->event_str) |
| 1375 | return sprintf(page, "%s", pmu_attr->event_str); | ||
| 1371 | 1376 | ||
| 1372 | #define EVENT_ATTR(_name, _id) \ | 1377 | return x86_pmu.events_sysfs_show(page, config); |
| 1373 | PMU_EVENT_ATTR(_name, EVENT_VAR(_id), PERF_COUNT_HW_##_id, \ | 1378 | } |
| 1374 | events_sysfs_show) | ||
| 1375 | 1379 | ||
| 1376 | EVENT_ATTR(cpu-cycles, CPU_CYCLES ); | 1380 | EVENT_ATTR(cpu-cycles, CPU_CYCLES ); |
| 1377 | EVENT_ATTR(instructions, INSTRUCTIONS ); | 1381 | EVENT_ATTR(instructions, INSTRUCTIONS ); |
diff --git a/arch/x86/kernel/cpu/perf_event.h b/arch/x86/kernel/cpu/perf_event.h index 95152c12a8d9..b1518eed5f99 100644 --- a/arch/x86/kernel/cpu/perf_event.h +++ b/arch/x86/kernel/cpu/perf_event.h | |||
| @@ -422,6 +422,23 @@ do { \ | |||
| 422 | #define ERF_NO_HT_SHARING 1 | 422 | #define ERF_NO_HT_SHARING 1 |
| 423 | #define ERF_HAS_RSP_1 2 | 423 | #define ERF_HAS_RSP_1 2 |
| 424 | 424 | ||
| 425 | #define EVENT_VAR(_id) event_attr_##_id | ||
| 426 | #define EVENT_PTR(_id) &event_attr_##_id.attr.attr | ||
| 427 | |||
| 428 | #define EVENT_ATTR(_name, _id) \ | ||
| 429 | static struct perf_pmu_events_attr EVENT_VAR(_id) = { \ | ||
| 430 | .attr = __ATTR(_name, 0444, events_sysfs_show, NULL), \ | ||
| 431 | .id = PERF_COUNT_HW_##_id, \ | ||
| 432 | .event_str = NULL, \ | ||
| 433 | }; | ||
| 434 | |||
| 435 | #define EVENT_ATTR_STR(_name, v, str) \ | ||
| 436 | static struct perf_pmu_events_attr event_attr_##v = { \ | ||
| 437 | .attr = __ATTR(_name, 0444, events_sysfs_show, NULL), \ | ||
| 438 | .id = 0, \ | ||
| 439 | .event_str = str, \ | ||
| 440 | }; | ||
| 441 | |||
| 425 | extern struct x86_pmu x86_pmu __read_mostly; | 442 | extern struct x86_pmu x86_pmu __read_mostly; |
| 426 | 443 | ||
| 427 | DECLARE_PER_CPU(struct cpu_hw_events, cpu_hw_events); | 444 | DECLARE_PER_CPU(struct cpu_hw_events, cpu_hw_events); |
diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h index 8737e1cee8b2..1c592114c437 100644 --- a/include/linux/perf_event.h +++ b/include/linux/perf_event.h | |||
| @@ -809,6 +809,7 @@ do { \ | |||
| 809 | struct perf_pmu_events_attr { | 809 | struct perf_pmu_events_attr { |
| 810 | struct device_attribute attr; | 810 | struct device_attribute attr; |
| 811 | u64 id; | 811 | u64 id; |
| 812 | const char *event_str; | ||
| 812 | }; | 813 | }; |
| 813 | 814 | ||
| 814 | #define PMU_EVENT_ATTR(_name, _var, _id, _show) \ | 815 | #define PMU_EVENT_ATTR(_name, _var, _id, _show) \ |
