diff options
-rw-r--r-- | Documentation/ABI/stable/sysfs-devices-cpu-events | 0 | ||||
-rw-r--r-- | arch/powerpc/include/asm/perf_event_server.h | 23 | ||||
-rw-r--r-- | arch/powerpc/perf/core-book3s.c | 12 | ||||
-rw-r--r-- | arch/powerpc/perf/power7-pmu.c | 34 |
4 files changed, 69 insertions, 0 deletions
diff --git a/Documentation/ABI/stable/sysfs-devices-cpu-events b/Documentation/ABI/stable/sysfs-devices-cpu-events new file mode 100644 index 000000000000..e69de29bb2d1 --- /dev/null +++ b/Documentation/ABI/stable/sysfs-devices-cpu-events | |||
diff --git a/arch/powerpc/include/asm/perf_event_server.h b/arch/powerpc/include/asm/perf_event_server.h index 9710be3a2d17..b9b6c557bd0c 100644 --- a/arch/powerpc/include/asm/perf_event_server.h +++ b/arch/powerpc/include/asm/perf_event_server.h | |||
@@ -11,6 +11,7 @@ | |||
11 | 11 | ||
12 | #include <linux/types.h> | 12 | #include <linux/types.h> |
13 | #include <asm/hw_irq.h> | 13 | #include <asm/hw_irq.h> |
14 | #include <linux/device.h> | ||
14 | 15 | ||
15 | #define MAX_HWEVENTS 8 | 16 | #define MAX_HWEVENTS 8 |
16 | #define MAX_EVENT_ALTERNATIVES 8 | 17 | #define MAX_EVENT_ALTERNATIVES 8 |
@@ -35,6 +36,7 @@ struct power_pmu { | |||
35 | void (*disable_pmc)(unsigned int pmc, unsigned long mmcr[]); | 36 | void (*disable_pmc)(unsigned int pmc, unsigned long mmcr[]); |
36 | int (*limited_pmc_event)(u64 event_id); | 37 | int (*limited_pmc_event)(u64 event_id); |
37 | u32 flags; | 38 | u32 flags; |
39 | const struct attribute_group **attr_groups; | ||
38 | int n_generic; | 40 | int n_generic; |
39 | int *generic_events; | 41 | int *generic_events; |
40 | int (*cache_events)[PERF_COUNT_HW_CACHE_MAX] | 42 | int (*cache_events)[PERF_COUNT_HW_CACHE_MAX] |
@@ -109,3 +111,24 @@ extern unsigned long perf_instruction_pointer(struct pt_regs *regs); | |||
109 | * If an event_id is not subject to the constraint expressed by a particular | 111 | * If an event_id is not subject to the constraint expressed by a particular |
110 | * field, then it will have 0 in both the mask and value for that field. | 112 | * field, then it will have 0 in both the mask and value for that field. |
111 | */ | 113 | */ |
114 | |||
115 | extern ssize_t power_events_sysfs_show(struct device *dev, | ||
116 | struct device_attribute *attr, char *page); | ||
117 | |||
118 | /* | ||
119 | * EVENT_VAR() is same as PMU_EVENT_VAR with a suffix. | ||
120 | * | ||
121 | * Having a suffix allows us to have aliases in sysfs - eg: the generic | ||
122 | * event 'cpu-cycles' can have two entries in sysfs: 'cpu-cycles' and | ||
123 | * 'PM_CYC' where the latter is the name by which the event is known in | ||
124 | * POWER CPU specification. | ||
125 | */ | ||
126 | #define EVENT_VAR(_id, _suffix) event_attr_##_id##_suffix | ||
127 | #define EVENT_PTR(_id, _suffix) &EVENT_VAR(_id, _suffix) | ||
128 | |||
129 | #define EVENT_ATTR(_name, _id, _suffix) \ | ||
130 | PMU_EVENT_ATTR(_name, EVENT_VAR(_id, _suffix), PME_PM_##_id, \ | ||
131 | power_events_sysfs_show) | ||
132 | |||
133 | #define GENERIC_EVENT_ATTR(_name, _id) EVENT_ATTR(_name, _id, _g) | ||
134 | #define GENERIC_EVENT_PTR(_id) EVENT_PTR(_id, _g) | ||
diff --git a/arch/powerpc/perf/core-book3s.c b/arch/powerpc/perf/core-book3s.c index aa2465e21f1a..fa476d50791f 100644 --- a/arch/powerpc/perf/core-book3s.c +++ b/arch/powerpc/perf/core-book3s.c | |||
@@ -1305,6 +1305,16 @@ static int power_pmu_event_idx(struct perf_event *event) | |||
1305 | return event->hw.idx; | 1305 | return event->hw.idx; |
1306 | } | 1306 | } |
1307 | 1307 | ||
1308 | ssize_t power_events_sysfs_show(struct device *dev, | ||
1309 | struct device_attribute *attr, char *page) | ||
1310 | { | ||
1311 | struct perf_pmu_events_attr *pmu_attr; | ||
1312 | |||
1313 | pmu_attr = container_of(attr, struct perf_pmu_events_attr, attr); | ||
1314 | |||
1315 | return sprintf(page, "event=0x%02llx\n", pmu_attr->id); | ||
1316 | } | ||
1317 | |||
1308 | struct pmu power_pmu = { | 1318 | struct pmu power_pmu = { |
1309 | .pmu_enable = power_pmu_enable, | 1319 | .pmu_enable = power_pmu_enable, |
1310 | .pmu_disable = power_pmu_disable, | 1320 | .pmu_disable = power_pmu_disable, |
@@ -1537,6 +1547,8 @@ int __cpuinit register_power_pmu(struct power_pmu *pmu) | |||
1537 | pr_info("%s performance monitor hardware support registered\n", | 1547 | pr_info("%s performance monitor hardware support registered\n", |
1538 | pmu->name); | 1548 | pmu->name); |
1539 | 1549 | ||
1550 | power_pmu.attr_groups = ppmu->attr_groups; | ||
1551 | |||
1540 | #ifdef MSR_HV | 1552 | #ifdef MSR_HV |
1541 | /* | 1553 | /* |
1542 | * Use FCHV to ignore kernel events if MSR.HV is set. | 1554 | * Use FCHV to ignore kernel events if MSR.HV is set. |
diff --git a/arch/powerpc/perf/power7-pmu.c b/arch/powerpc/perf/power7-pmu.c index eebb36de429f..269bf2464a36 100644 --- a/arch/powerpc/perf/power7-pmu.c +++ b/arch/powerpc/perf/power7-pmu.c | |||
@@ -374,6 +374,39 @@ static int power7_cache_events[C(MAX)][C(OP_MAX)][C(RESULT_MAX)] = { | |||
374 | }, | 374 | }, |
375 | }; | 375 | }; |
376 | 376 | ||
377 | |||
378 | GENERIC_EVENT_ATTR(cpu-cycles, CYC); | ||
379 | GENERIC_EVENT_ATTR(stalled-cycles-frontend, GCT_NOSLOT_CYC); | ||
380 | GENERIC_EVENT_ATTR(stalled-cycles-backend, CMPLU_STALL); | ||
381 | GENERIC_EVENT_ATTR(instructions, INST_CMPL); | ||
382 | GENERIC_EVENT_ATTR(cache-references, LD_REF_L1); | ||
383 | GENERIC_EVENT_ATTR(cache-misses, LD_MISS_L1); | ||
384 | GENERIC_EVENT_ATTR(branch-instructions, BRU_FIN); | ||
385 | GENERIC_EVENT_ATTR(branch-misses, BRU_MPRED); | ||
386 | |||
387 | static struct attribute *power7_events_attr[] = { | ||
388 | GENERIC_EVENT_PTR(CYC), | ||
389 | GENERIC_EVENT_PTR(GCT_NOSLOT_CYC), | ||
390 | GENERIC_EVENT_PTR(CMPLU_STALL), | ||
391 | GENERIC_EVENT_PTR(INST_CMPL), | ||
392 | GENERIC_EVENT_PTR(LD_REF_L1), | ||
393 | GENERIC_EVENT_PTR(LD_MISS_L1), | ||
394 | GENERIC_EVENT_PTR(BRU_FIN), | ||
395 | GENERIC_EVENT_PTR(BRU_MPRED), | ||
396 | NULL | ||
397 | }; | ||
398 | |||
399 | |||
400 | static struct attribute_group power7_pmu_events_group = { | ||
401 | .name = "events", | ||
402 | .attrs = power7_events_attr, | ||
403 | }; | ||
404 | |||
405 | static const struct attribute_group *power7_pmu_attr_groups[] = { | ||
406 | &power7_pmu_events_group, | ||
407 | NULL, | ||
408 | }; | ||
409 | |||
377 | static struct power_pmu power7_pmu = { | 410 | static struct power_pmu power7_pmu = { |
378 | .name = "POWER7", | 411 | .name = "POWER7", |
379 | .n_counter = 6, | 412 | .n_counter = 6, |
@@ -385,6 +418,7 @@ static struct power_pmu power7_pmu = { | |||
385 | .get_alternatives = power7_get_alternatives, | 418 | .get_alternatives = power7_get_alternatives, |
386 | .disable_pmc = power7_disable_pmc, | 419 | .disable_pmc = power7_disable_pmc, |
387 | .flags = PPMU_ALT_SIPR, | 420 | .flags = PPMU_ALT_SIPR, |
421 | .attr_groups = power7_pmu_attr_groups, | ||
388 | .n_generic = ARRAY_SIZE(power7_generic_events), | 422 | .n_generic = ARRAY_SIZE(power7_generic_events), |
389 | .generic_events = power7_generic_events, | 423 | .generic_events = power7_generic_events, |
390 | .cache_events = &power7_cache_events, | 424 | .cache_events = &power7_cache_events, |