mirror of https://gitee.com/openkylin/linux.git
perf/POWER7: Make generic event translations available in sysfs
Make the generic perf events in POWER7 available via sysfs.
$ ls /sys/bus/event_source/devices/cpu/events
branch-instructions
branch-misses
cache-misses
cache-references
cpu-cycles
instructions
stalled-cycles-backend
stalled-cycles-frontend
$ cat /sys/bus/event_source/devices/cpu/events/cache-misses
event=0x400f0
This patch is based on commits that implement this functionality on x86.
Eg:
commit a47473939d
Author: Jiri Olsa <jolsa@redhat.com>
Date: Wed Oct 10 14:53:11 2012 +0200
perf/x86: Make hardware event translations available in sysfs
Changelog:[v2]
[Jiri Osla] Drop EVENT_ID() macro since it is only used once.
Signed-off-by: Sukadev Bhattiprolu <sukadev@linux.vnet.ibm.com>
Cc: Andi Kleen <ak@linux.intel.com>
Cc: Anton Blanchard <anton@au1.ibm.com>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Robert Richter <robert.richter@amd.com>
Cc: Stephane Eranian <eranian@google.com>
Cc: linuxppc-dev@ozlabs.org
Link: http://lkml.kernel.org/r/20130123062454.GD13720@us.ibm.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
This commit is contained in:
parent
2663960c15
commit
1c53a27072
|
@ -11,6 +11,7 @@
|
|||
|
||||
#include <linux/types.h>
|
||||
#include <asm/hw_irq.h>
|
||||
#include <linux/device.h>
|
||||
|
||||
#define MAX_HWEVENTS 8
|
||||
#define MAX_EVENT_ALTERNATIVES 8
|
||||
|
@ -35,6 +36,7 @@ struct power_pmu {
|
|||
void (*disable_pmc)(unsigned int pmc, unsigned long mmcr[]);
|
||||
int (*limited_pmc_event)(u64 event_id);
|
||||
u32 flags;
|
||||
const struct attribute_group **attr_groups;
|
||||
int n_generic;
|
||||
int *generic_events;
|
||||
int (*cache_events)[PERF_COUNT_HW_CACHE_MAX]
|
||||
|
@ -109,3 +111,24 @@ extern unsigned long perf_instruction_pointer(struct pt_regs *regs);
|
|||
* If an event_id is not subject to the constraint expressed by a particular
|
||||
* field, then it will have 0 in both the mask and value for that field.
|
||||
*/
|
||||
|
||||
extern ssize_t power_events_sysfs_show(struct device *dev,
|
||||
struct device_attribute *attr, char *page);
|
||||
|
||||
/*
|
||||
* EVENT_VAR() is same as PMU_EVENT_VAR with a suffix.
|
||||
*
|
||||
* Having a suffix allows us to have aliases in sysfs - eg: the generic
|
||||
* event 'cpu-cycles' can have two entries in sysfs: 'cpu-cycles' and
|
||||
* 'PM_CYC' where the latter is the name by which the event is known in
|
||||
* POWER CPU specification.
|
||||
*/
|
||||
#define EVENT_VAR(_id, _suffix) event_attr_##_id##_suffix
|
||||
#define EVENT_PTR(_id, _suffix) &EVENT_VAR(_id, _suffix)
|
||||
|
||||
#define EVENT_ATTR(_name, _id, _suffix) \
|
||||
PMU_EVENT_ATTR(_name, EVENT_VAR(_id, _suffix), PME_PM_##_id, \
|
||||
power_events_sysfs_show)
|
||||
|
||||
#define GENERIC_EVENT_ATTR(_name, _id) EVENT_ATTR(_name, _id, _g)
|
||||
#define GENERIC_EVENT_PTR(_id) EVENT_PTR(_id, _g)
|
||||
|
|
|
@ -1305,6 +1305,16 @@ static int power_pmu_event_idx(struct perf_event *event)
|
|||
return event->hw.idx;
|
||||
}
|
||||
|
||||
ssize_t power_events_sysfs_show(struct device *dev,
|
||||
struct device_attribute *attr, char *page)
|
||||
{
|
||||
struct perf_pmu_events_attr *pmu_attr;
|
||||
|
||||
pmu_attr = container_of(attr, struct perf_pmu_events_attr, attr);
|
||||
|
||||
return sprintf(page, "event=0x%02llx\n", pmu_attr->id);
|
||||
}
|
||||
|
||||
struct pmu power_pmu = {
|
||||
.pmu_enable = power_pmu_enable,
|
||||
.pmu_disable = power_pmu_disable,
|
||||
|
@ -1537,6 +1547,8 @@ int __cpuinit register_power_pmu(struct power_pmu *pmu)
|
|||
pr_info("%s performance monitor hardware support registered\n",
|
||||
pmu->name);
|
||||
|
||||
power_pmu.attr_groups = ppmu->attr_groups;
|
||||
|
||||
#ifdef MSR_HV
|
||||
/*
|
||||
* Use FCHV to ignore kernel events if MSR.HV is set.
|
||||
|
|
|
@ -374,6 +374,39 @@ static int power7_cache_events[C(MAX)][C(OP_MAX)][C(RESULT_MAX)] = {
|
|||
},
|
||||
};
|
||||
|
||||
|
||||
GENERIC_EVENT_ATTR(cpu-cycles, CYC);
|
||||
GENERIC_EVENT_ATTR(stalled-cycles-frontend, GCT_NOSLOT_CYC);
|
||||
GENERIC_EVENT_ATTR(stalled-cycles-backend, CMPLU_STALL);
|
||||
GENERIC_EVENT_ATTR(instructions, INST_CMPL);
|
||||
GENERIC_EVENT_ATTR(cache-references, LD_REF_L1);
|
||||
GENERIC_EVENT_ATTR(cache-misses, LD_MISS_L1);
|
||||
GENERIC_EVENT_ATTR(branch-instructions, BRU_FIN);
|
||||
GENERIC_EVENT_ATTR(branch-misses, BRU_MPRED);
|
||||
|
||||
static struct attribute *power7_events_attr[] = {
|
||||
GENERIC_EVENT_PTR(CYC),
|
||||
GENERIC_EVENT_PTR(GCT_NOSLOT_CYC),
|
||||
GENERIC_EVENT_PTR(CMPLU_STALL),
|
||||
GENERIC_EVENT_PTR(INST_CMPL),
|
||||
GENERIC_EVENT_PTR(LD_REF_L1),
|
||||
GENERIC_EVENT_PTR(LD_MISS_L1),
|
||||
GENERIC_EVENT_PTR(BRU_FIN),
|
||||
GENERIC_EVENT_PTR(BRU_MPRED),
|
||||
NULL
|
||||
};
|
||||
|
||||
|
||||
static struct attribute_group power7_pmu_events_group = {
|
||||
.name = "events",
|
||||
.attrs = power7_events_attr,
|
||||
};
|
||||
|
||||
static const struct attribute_group *power7_pmu_attr_groups[] = {
|
||||
&power7_pmu_events_group,
|
||||
NULL,
|
||||
};
|
||||
|
||||
static struct power_pmu power7_pmu = {
|
||||
.name = "POWER7",
|
||||
.n_counter = 6,
|
||||
|
@ -385,6 +418,7 @@ static struct power_pmu power7_pmu = {
|
|||
.get_alternatives = power7_get_alternatives,
|
||||
.disable_pmc = power7_disable_pmc,
|
||||
.flags = PPMU_ALT_SIPR,
|
||||
.attr_groups = power7_pmu_attr_groups,
|
||||
.n_generic = ARRAY_SIZE(power7_generic_events),
|
||||
.generic_events = power7_generic_events,
|
||||
.cache_events = &power7_cache_events,
|
||||
|
|
Loading…
Reference in New Issue