diff options
Diffstat (limited to 'arch/x86/kernel/cpu/perf_event.h')
| -rw-r--r-- | arch/x86/kernel/cpu/perf_event.h | 56 | 
1 files changed, 52 insertions, 4 deletions
diff --git a/arch/x86/kernel/cpu/perf_event.h b/arch/x86/kernel/cpu/perf_event.h index 7f5c75c2afd..ba9aadfa683 100644 --- a/arch/x86/kernel/cpu/perf_event.h +++ b/arch/x86/kernel/cpu/perf_event.h @@ -46,6 +46,7 @@ enum extra_reg_type {  	EXTRA_REG_RSP_0 = 0,	/* offcore_response_0 */  	EXTRA_REG_RSP_1 = 1,	/* offcore_response_1 */  	EXTRA_REG_LBR   = 2,	/* lbr_select */ +	EXTRA_REG_LDLAT = 3,	/* ld_lat_threshold */  	EXTRA_REG_MAX		/* number of entries needed */  }; @@ -59,7 +60,13 @@ struct event_constraint {  	u64	cmask;  	int	weight;  	int	overlap; +	int	flags;  }; +/* + * struct event_constraint flags + */ +#define PERF_X86_EVENT_PEBS_LDLAT	0x1 /* ld+ldlat data address sampling */ +#define PERF_X86_EVENT_PEBS_ST		0x2 /* st data address sampling */  struct amd_nb {  	int nb_id;  /* NorthBridge id */ @@ -170,16 +177,17 @@ struct cpu_hw_events {  	void				*kfree_on_online;  }; -#define __EVENT_CONSTRAINT(c, n, m, w, o) {\ +#define __EVENT_CONSTRAINT(c, n, m, w, o, f) {\  	{ .idxmsk64 = (n) },		\  	.code = (c),			\  	.cmask = (m),			\  	.weight = (w),			\  	.overlap = (o),			\ +	.flags = f,			\  }  #define EVENT_CONSTRAINT(c, n, m)	\ -	__EVENT_CONSTRAINT(c, n, m, HWEIGHT(n), 0) +	__EVENT_CONSTRAINT(c, n, m, HWEIGHT(n), 0, 0)  /*   * The overlap flag marks event constraints with overlapping counter @@ -203,7 +211,7 @@ struct cpu_hw_events {   * and its counter masks must be kept at a minimum.   */  #define EVENT_CONSTRAINT_OVERLAP(c, n, m)	\ -	__EVENT_CONSTRAINT(c, n, m, HWEIGHT(n), 1) +	__EVENT_CONSTRAINT(c, n, m, HWEIGHT(n), 1, 0)  /*   * Constraint on the Event code. @@ -231,6 +239,14 @@ struct cpu_hw_events {  #define INTEL_UEVENT_CONSTRAINT(c, n)	\  	EVENT_CONSTRAINT(c, n, INTEL_ARCH_EVENT_MASK) +#define INTEL_PLD_CONSTRAINT(c, n)	\ +	__EVENT_CONSTRAINT(c, n, INTEL_ARCH_EVENT_MASK, \ +			   HWEIGHT(n), 0, PERF_X86_EVENT_PEBS_LDLAT) + +#define INTEL_PST_CONSTRAINT(c, n)	\ +	__EVENT_CONSTRAINT(c, n, INTEL_ARCH_EVENT_MASK, \ +			  HWEIGHT(n), 0, PERF_X86_EVENT_PEBS_ST) +  #define EVENT_CONSTRAINT_END		\  	EVENT_CONSTRAINT(0, 0, 0) @@ -260,12 +276,22 @@ struct extra_reg {  	.msr = (ms),		\  	.config_mask = (m),	\  	.valid_mask = (vm),	\ -	.idx = EXTRA_REG_##i	\ +	.idx = EXTRA_REG_##i,	\  	}  #define INTEL_EVENT_EXTRA_REG(event, msr, vm, idx)	\  	EVENT_EXTRA_REG(event, msr, ARCH_PERFMON_EVENTSEL_EVENT, vm, idx) +#define INTEL_UEVENT_EXTRA_REG(event, msr, vm, idx) \ +	EVENT_EXTRA_REG(event, msr, ARCH_PERFMON_EVENTSEL_EVENT | \ +			ARCH_PERFMON_EVENTSEL_UMASK, vm, idx) + +#define INTEL_UEVENT_PEBS_LDLAT_EXTRA_REG(c) \ +	INTEL_UEVENT_EXTRA_REG(c, \ +			       MSR_PEBS_LD_LAT_THRESHOLD, \ +			       0xffff, \ +			       LDLAT) +  #define EVENT_EXTRA_END EVENT_EXTRA_REG(0, 0, 0, 0, RSP_0)  union perf_capabilities { @@ -355,8 +381,10 @@ struct x86_pmu {  	 */  	int		attr_rdpmc;  	struct attribute **format_attrs; +	struct attribute **event_attrs;  	ssize_t		(*events_sysfs_show)(char *page, u64 config); +	struct attribute **cpu_events;  	/*  	 * CPU Hotplug hooks @@ -421,6 +449,23 @@ do {									\  #define ERF_NO_HT_SHARING	1  #define ERF_HAS_RSP_1		2 +#define EVENT_VAR(_id)  event_attr_##_id +#define EVENT_PTR(_id) &event_attr_##_id.attr.attr + +#define EVENT_ATTR(_name, _id)						\ +static struct perf_pmu_events_attr EVENT_VAR(_id) = {			\ +	.attr		= __ATTR(_name, 0444, events_sysfs_show, NULL),	\ +	.id		= PERF_COUNT_HW_##_id,				\ +	.event_str	= NULL,						\ +}; + +#define EVENT_ATTR_STR(_name, v, str)					\ +static struct perf_pmu_events_attr event_attr_##v = {			\ +	.attr		= __ATTR(_name, 0444, events_sysfs_show, NULL),	\ +	.id		= 0,						\ +	.event_str	= str,						\ +}; +  extern struct x86_pmu x86_pmu __read_mostly;  DECLARE_PER_CPU(struct cpu_hw_events, cpu_hw_events); @@ -628,6 +673,9 @@ int p6_pmu_init(void);  int knc_pmu_init(void); +ssize_t events_sysfs_show(struct device *dev, struct device_attribute *attr, +			  char *page); +  #else /* CONFIG_CPU_SUP_INTEL */  static inline void reserve_ds_buffers(void)  |