linux-arm-kernel.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
* [PATCHv2] arm: perf: Add event descriptions
@ 2015-10-07 18:28 Drew Richardson
  2015-10-09 10:13 ` Will Deacon
  0 siblings, 1 reply; 23+ messages in thread
From: Drew Richardson @ 2015-10-07 18:28 UTC (permalink / raw)
  To: linux-arm-kernel

Add additional information about the ARM architected hardware events
to make counters self describing. This makes the hardware PMUs easier
to use as perf list contains possible events instead of users having
to refer to documentation like the ARM TRMs.

Signed-off-by: Drew Richardson <drew.richardson@arm.com>
---
 arch/arm/kernel/perf_event_v7.c | 96 +++++++++++++++++++++++++++++++++++++++++
 drivers/perf/arm_pmu.c          |  1 +
 2 files changed, 97 insertions(+)

diff --git a/arch/arm/kernel/perf_event_v7.c b/arch/arm/kernel/perf_event_v7.c
index 126dc679b230..6623bd0d8a1d 100644
--- a/arch/arm/kernel/perf_event_v7.c
+++ b/arch/arm/kernel/perf_event_v7.c
@@ -547,6 +547,95 @@ static const unsigned scorpion_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
 	[C(BPU)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
 };
 
+static ssize_t armv7_event_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);
+}
+
+#define ARMV7_EVENT_ATTR(name, config) \
+	PMU_EVENT_ATTR(name, armv7_event_attr_##name, config, \
+		       armv7_event_sysfs_show);
+
+ARMV7_EVENT_ATTR(sw_incr, ARMV7_PERFCTR_PMNC_SW_INCR);
+ARMV7_EVENT_ATTR(l1i_cache_refill, ARMV7_PERFCTR_L1_ICACHE_REFILL);
+ARMV7_EVENT_ATTR(l1i_tlb_refill, ARMV7_PERFCTR_ITLB_REFILL);
+ARMV7_EVENT_ATTR(l1d_cache_refill, ARMV7_PERFCTR_L1_DCACHE_REFILL);
+ARMV7_EVENT_ATTR(l1d_cache, ARMV7_PERFCTR_L1_DCACHE_ACCESS);
+ARMV7_EVENT_ATTR(l1d_tlb_refill, ARMV7_PERFCTR_DTLB_REFILL);
+ARMV7_EVENT_ATTR(ld_retired, ARMV7_PERFCTR_MEM_READ);
+ARMV7_EVENT_ATTR(st_retired, ARMV7_PERFCTR_MEM_WRITE);
+ARMV7_EVENT_ATTR(inst_retired, ARMV7_PERFCTR_INSTR_EXECUTED);
+ARMV7_EVENT_ATTR(exc_taken, ARMV7_PERFCTR_EXC_TAKEN);
+ARMV7_EVENT_ATTR(exc_return, ARMV7_PERFCTR_EXC_EXECUTED);
+ARMV7_EVENT_ATTR(cid_write_retired, ARMV7_PERFCTR_CID_WRITE);
+ARMV7_EVENT_ATTR(pc_write_retired, ARMV7_PERFCTR_PC_WRITE);
+ARMV7_EVENT_ATTR(br_immed_retired, ARMV7_PERFCTR_PC_IMM_BRANCH);
+ARMV7_EVENT_ATTR(br_return_retired, ARMV7_PERFCTR_PC_PROC_RETURN);
+ARMV7_EVENT_ATTR(unaligned_ldst_retired, ARMV7_PERFCTR_MEM_UNALIGNED_ACCESS);
+ARMV7_EVENT_ATTR(br_mis_pred, ARMV7_PERFCTR_PC_BRANCH_MIS_PRED);
+ARMV7_EVENT_ATTR(cpu_cycles, ARMV7_PERFCTR_CLOCK_CYCLES);
+ARMV7_EVENT_ATTR(br_pred, ARMV7_PERFCTR_PC_BRANCH_PRED);
+ARMV7_EVENT_ATTR(mem_access, ARMV7_PERFCTR_MEM_ACCESS);
+ARMV7_EVENT_ATTR(l1i_cache, ARMV7_PERFCTR_L1_ICACHE_ACCESS);
+ARMV7_EVENT_ATTR(l1d_cache_wb, ARMV7_PERFCTR_L1_DCACHE_WB);
+ARMV7_EVENT_ATTR(l2d_cache, ARMV7_PERFCTR_L2_CACHE_ACCESS);
+ARMV7_EVENT_ATTR(l2d_cache_refill, ARMV7_PERFCTR_L2_CACHE_REFILL);
+ARMV7_EVENT_ATTR(l2d_cache_wb, ARMV7_PERFCTR_L2_CACHE_WB);
+ARMV7_EVENT_ATTR(bus_access, ARMV7_PERFCTR_BUS_ACCESS);
+ARMV7_EVENT_ATTR(memory_error, ARMV7_PERFCTR_MEM_ERROR);
+ARMV7_EVENT_ATTR(inst_spec, ARMV7_PERFCTR_INSTR_SPEC);
+ARMV7_EVENT_ATTR(ttbr_write_retired, ARMV7_PERFCTR_TTBR_WRITE);
+ARMV7_EVENT_ATTR(bus_cycles, ARMV7_PERFCTR_BUS_CYCLES);
+
+static struct attribute *armv7_pmuv2_event_attrs[] = {
+	&armv7_event_attr_sw_incr.attr.attr,
+	&armv7_event_attr_l1i_cache_refill.attr.attr,
+	&armv7_event_attr_l1i_tlb_refill.attr.attr,
+	&armv7_event_attr_l1d_cache_refill.attr.attr,
+	&armv7_event_attr_l1d_cache.attr.attr,
+	&armv7_event_attr_l1d_tlb_refill.attr.attr,
+	&armv7_event_attr_ld_retired.attr.attr,
+	&armv7_event_attr_st_retired.attr.attr,
+	&armv7_event_attr_inst_retired.attr.attr,
+	&armv7_event_attr_exc_taken.attr.attr,
+	&armv7_event_attr_exc_return.attr.attr,
+	&armv7_event_attr_cid_write_retired.attr.attr,
+	&armv7_event_attr_pc_write_retired.attr.attr,
+	&armv7_event_attr_br_immed_retired.attr.attr,
+	&armv7_event_attr_br_return_retired.attr.attr,
+	&armv7_event_attr_unaligned_ldst_retired.attr.attr,
+	&armv7_event_attr_br_mis_pred.attr.attr,
+	&armv7_event_attr_cpu_cycles.attr.attr,
+	&armv7_event_attr_br_pred.attr.attr,
+	&armv7_event_attr_mem_access.attr.attr,
+	&armv7_event_attr_l1i_cache.attr.attr,
+	&armv7_event_attr_l1d_cache_wb.attr.attr,
+	&armv7_event_attr_l2d_cache.attr.attr,
+	&armv7_event_attr_l2d_cache_refill.attr.attr,
+	&armv7_event_attr_l2d_cache_wb.attr.attr,
+	&armv7_event_attr_bus_access.attr.attr,
+	&armv7_event_attr_memory_error.attr.attr,
+	&armv7_event_attr_inst_spec.attr.attr,
+	&armv7_event_attr_ttbr_write_retired.attr.attr,
+	&armv7_event_attr_bus_cycles.attr.attr,
+	NULL
+};
+
+static struct attribute_group armv7_pmuv2_events_attr_group = {
+	.name = "events",
+	.attrs = armv7_pmuv2_event_attrs,
+};
+
+static const struct attribute_group *armv7_pmuv2_attr_groups[] = {
+	&armv7_pmuv2_events_attr_group,
+	NULL
+};
+
 /*
  * Perf Events' indices
  */
@@ -1085,6 +1174,7 @@ static int armv7_a8_pmu_init(struct arm_pmu *cpu_pmu)
 	armv7pmu_init(cpu_pmu);
 	cpu_pmu->name		= "armv7_cortex_a8";
 	cpu_pmu->map_event	= armv7_a8_map_event;
+	cpu_pmu->pmu.attr_groups = armv7_pmuv2_attr_groups;
 	return armv7_probe_num_events(cpu_pmu);
 }
 
@@ -1093,6 +1183,7 @@ static int armv7_a9_pmu_init(struct arm_pmu *cpu_pmu)
 	armv7pmu_init(cpu_pmu);
 	cpu_pmu->name		= "armv7_cortex_a9";
 	cpu_pmu->map_event	= armv7_a9_map_event;
+	cpu_pmu->pmu.attr_groups = armv7_pmuv2_attr_groups;
 	return armv7_probe_num_events(cpu_pmu);
 }
 
@@ -1101,6 +1192,7 @@ static int armv7_a5_pmu_init(struct arm_pmu *cpu_pmu)
 	armv7pmu_init(cpu_pmu);
 	cpu_pmu->name		= "armv7_cortex_a5";
 	cpu_pmu->map_event	= armv7_a5_map_event;
+	cpu_pmu->pmu.attr_groups = armv7_pmuv2_attr_groups;
 	return armv7_probe_num_events(cpu_pmu);
 }
 
@@ -1110,6 +1202,7 @@ static int armv7_a15_pmu_init(struct arm_pmu *cpu_pmu)
 	cpu_pmu->name		= "armv7_cortex_a15";
 	cpu_pmu->map_event	= armv7_a15_map_event;
 	cpu_pmu->set_event_filter = armv7pmu_set_event_filter;
+	cpu_pmu->pmu.attr_groups = armv7_pmuv2_attr_groups;
 	return armv7_probe_num_events(cpu_pmu);
 }
 
@@ -1119,6 +1212,7 @@ static int armv7_a7_pmu_init(struct arm_pmu *cpu_pmu)
 	cpu_pmu->name		= "armv7_cortex_a7";
 	cpu_pmu->map_event	= armv7_a7_map_event;
 	cpu_pmu->set_event_filter = armv7pmu_set_event_filter;
+	cpu_pmu->pmu.attr_groups = armv7_pmuv2_attr_groups;
 	return armv7_probe_num_events(cpu_pmu);
 }
 
@@ -1128,6 +1222,7 @@ static int armv7_a12_pmu_init(struct arm_pmu *cpu_pmu)
 	cpu_pmu->name		= "armv7_cortex_a12";
 	cpu_pmu->map_event	= armv7_a12_map_event;
 	cpu_pmu->set_event_filter = armv7pmu_set_event_filter;
+	cpu_pmu->pmu.attr_groups = armv7_pmuv2_attr_groups;
 	return armv7_probe_num_events(cpu_pmu);
 }
 
@@ -1135,6 +1230,7 @@ static int armv7_a17_pmu_init(struct arm_pmu *cpu_pmu)
 {
 	int ret = armv7_a12_pmu_init(cpu_pmu);
 	cpu_pmu->name = "armv7_cortex_a17";
+	cpu_pmu->pmu.attr_groups = armv7_pmuv2_attr_groups;
 	return ret;
 }
 
diff --git a/drivers/perf/arm_pmu.c b/drivers/perf/arm_pmu.c
index 2365a32a595e..e933d2dd71c0 100644
--- a/drivers/perf/arm_pmu.c
+++ b/drivers/perf/arm_pmu.c
@@ -548,6 +548,7 @@ static void armpmu_init(struct arm_pmu *armpmu)
 		.stop		= armpmu_stop,
 		.read		= armpmu_read,
 		.filter_match	= armpmu_filter_match,
+		.attr_groups	= armpmu->pmu.attr_groups,
 	};
 }
 
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCHv2] arm: perf: Add event descriptions
  2015-10-07 18:28 [PATCHv2] arm: perf: Add event descriptions Drew Richardson
@ 2015-10-09 10:13 ` Will Deacon
  2015-10-09 16:53   ` Drew Richardson
  2015-10-22 14:05   ` [PATCHv2] " Drew Richardson
  0 siblings, 2 replies; 23+ messages in thread
From: Will Deacon @ 2015-10-09 10:13 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Oct 07, 2015 at 11:28:18AM -0700, Drew Richardson wrote:
> Add additional information about the ARM architected hardware events
> to make counters self describing. This makes the hardware PMUs easier
> to use as perf list contains possible events instead of users having
> to refer to documentation like the ARM TRMs.
> 
> Signed-off-by: Drew Richardson <drew.richardson@arm.com>
> ---
>  arch/arm/kernel/perf_event_v7.c | 96 +++++++++++++++++++++++++++++++++++++++++
>  drivers/perf/arm_pmu.c          |  1 +
>  2 files changed, 97 insertions(+)
> 
> diff --git a/arch/arm/kernel/perf_event_v7.c b/arch/arm/kernel/perf_event_v7.c
> index 126dc679b230..6623bd0d8a1d 100644
> --- a/arch/arm/kernel/perf_event_v7.c
> +++ b/arch/arm/kernel/perf_event_v7.c
> @@ -547,6 +547,95 @@ static const unsigned scorpion_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
>  	[C(BPU)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
>  };
>  
> +static ssize_t armv7_event_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);
> +}

Can we not do this with a couple of macros, stringification of the event
code and PMU_EVENT_ATTR_STRING, therefore avoiding this function entirely?

> +#define ARMV7_EVENT_ATTR(name, config) \
> +	PMU_EVENT_ATTR(name, armv7_event_attr_##name, config, \
> +		       armv7_event_sysfs_show);
> +
> +ARMV7_EVENT_ATTR(sw_incr, ARMV7_PERFCTR_PMNC_SW_INCR);
> +ARMV7_EVENT_ATTR(l1i_cache_refill, ARMV7_PERFCTR_L1_ICACHE_REFILL);
> +ARMV7_EVENT_ATTR(l1i_tlb_refill, ARMV7_PERFCTR_ITLB_REFILL);
> +ARMV7_EVENT_ATTR(l1d_cache_refill, ARMV7_PERFCTR_L1_DCACHE_REFILL);
> +ARMV7_EVENT_ATTR(l1d_cache, ARMV7_PERFCTR_L1_DCACHE_ACCESS);
> +ARMV7_EVENT_ATTR(l1d_tlb_refill, ARMV7_PERFCTR_DTLB_REFILL);
> +ARMV7_EVENT_ATTR(ld_retired, ARMV7_PERFCTR_MEM_READ);
> +ARMV7_EVENT_ATTR(st_retired, ARMV7_PERFCTR_MEM_WRITE);
> +ARMV7_EVENT_ATTR(inst_retired, ARMV7_PERFCTR_INSTR_EXECUTED);
> +ARMV7_EVENT_ATTR(exc_taken, ARMV7_PERFCTR_EXC_TAKEN);
> +ARMV7_EVENT_ATTR(exc_return, ARMV7_PERFCTR_EXC_EXECUTED);
> +ARMV7_EVENT_ATTR(cid_write_retired, ARMV7_PERFCTR_CID_WRITE);
> +ARMV7_EVENT_ATTR(pc_write_retired, ARMV7_PERFCTR_PC_WRITE);
> +ARMV7_EVENT_ATTR(br_immed_retired, ARMV7_PERFCTR_PC_IMM_BRANCH);
> +ARMV7_EVENT_ATTR(br_return_retired, ARMV7_PERFCTR_PC_PROC_RETURN);
> +ARMV7_EVENT_ATTR(unaligned_ldst_retired, ARMV7_PERFCTR_MEM_UNALIGNED_ACCESS);
> +ARMV7_EVENT_ATTR(br_mis_pred, ARMV7_PERFCTR_PC_BRANCH_MIS_PRED);
> +ARMV7_EVENT_ATTR(cpu_cycles, ARMV7_PERFCTR_CLOCK_CYCLES);
> +ARMV7_EVENT_ATTR(br_pred, ARMV7_PERFCTR_PC_BRANCH_PRED);
> +ARMV7_EVENT_ATTR(mem_access, ARMV7_PERFCTR_MEM_ACCESS);
> +ARMV7_EVENT_ATTR(l1i_cache, ARMV7_PERFCTR_L1_ICACHE_ACCESS);
> +ARMV7_EVENT_ATTR(l1d_cache_wb, ARMV7_PERFCTR_L1_DCACHE_WB);
> +ARMV7_EVENT_ATTR(l2d_cache, ARMV7_PERFCTR_L2_CACHE_ACCESS);
> +ARMV7_EVENT_ATTR(l2d_cache_refill, ARMV7_PERFCTR_L2_CACHE_REFILL);
> +ARMV7_EVENT_ATTR(l2d_cache_wb, ARMV7_PERFCTR_L2_CACHE_WB);
> +ARMV7_EVENT_ATTR(bus_access, ARMV7_PERFCTR_BUS_ACCESS);
> +ARMV7_EVENT_ATTR(memory_error, ARMV7_PERFCTR_MEM_ERROR);
> +ARMV7_EVENT_ATTR(inst_spec, ARMV7_PERFCTR_INSTR_SPEC);
> +ARMV7_EVENT_ATTR(ttbr_write_retired, ARMV7_PERFCTR_TTBR_WRITE);
> +ARMV7_EVENT_ATTR(bus_cycles, ARMV7_PERFCTR_BUS_CYCLES);
> +
> +static struct attribute *armv7_pmuv2_event_attrs[] = {
> +	&armv7_event_attr_sw_incr.attr.attr,
> +	&armv7_event_attr_l1i_cache_refill.attr.attr,
> +	&armv7_event_attr_l1i_tlb_refill.attr.attr,
> +	&armv7_event_attr_l1d_cache_refill.attr.attr,
> +	&armv7_event_attr_l1d_cache.attr.attr,
> +	&armv7_event_attr_l1d_tlb_refill.attr.attr,
> +	&armv7_event_attr_ld_retired.attr.attr,
> +	&armv7_event_attr_st_retired.attr.attr,
> +	&armv7_event_attr_inst_retired.attr.attr,
> +	&armv7_event_attr_exc_taken.attr.attr,
> +	&armv7_event_attr_exc_return.attr.attr,
> +	&armv7_event_attr_cid_write_retired.attr.attr,
> +	&armv7_event_attr_pc_write_retired.attr.attr,
> +	&armv7_event_attr_br_immed_retired.attr.attr,
> +	&armv7_event_attr_br_return_retired.attr.attr,
> +	&armv7_event_attr_unaligned_ldst_retired.attr.attr,
> +	&armv7_event_attr_br_mis_pred.attr.attr,
> +	&armv7_event_attr_cpu_cycles.attr.attr,
> +	&armv7_event_attr_br_pred.attr.attr,
> +	&armv7_event_attr_mem_access.attr.attr,
> +	&armv7_event_attr_l1i_cache.attr.attr,
> +	&armv7_event_attr_l1d_cache_wb.attr.attr,
> +	&armv7_event_attr_l2d_cache.attr.attr,
> +	&armv7_event_attr_l2d_cache_refill.attr.attr,
> +	&armv7_event_attr_l2d_cache_wb.attr.attr,
> +	&armv7_event_attr_bus_access.attr.attr,
> +	&armv7_event_attr_memory_error.attr.attr,
> +	&armv7_event_attr_inst_spec.attr.attr,
> +	&armv7_event_attr_ttbr_write_retired.attr.attr,
> +	&armv7_event_attr_bus_cycles.attr.attr,
> +	NULL
> +};
> +
> +static struct attribute_group armv7_pmuv2_events_attr_group = {
> +	.name = "events",
> +	.attrs = armv7_pmuv2_event_attrs,
> +};
> +
> +static const struct attribute_group *armv7_pmuv2_attr_groups[] = {
> +	&armv7_pmuv2_events_attr_group,
> +	NULL
> +};
> +
>  /*
>   * Perf Events' indices
>   */
> @@ -1085,6 +1174,7 @@ static int armv7_a8_pmu_init(struct arm_pmu *cpu_pmu)
>  	armv7pmu_init(cpu_pmu);
>  	cpu_pmu->name		= "armv7_cortex_a8";
>  	cpu_pmu->map_event	= armv7_a8_map_event;
> +	cpu_pmu->pmu.attr_groups = armv7_pmuv2_attr_groups;
>  	return armv7_probe_num_events(cpu_pmu);
>  }
>  
> @@ -1093,6 +1183,7 @@ static int armv7_a9_pmu_init(struct arm_pmu *cpu_pmu)
>  	armv7pmu_init(cpu_pmu);
>  	cpu_pmu->name		= "armv7_cortex_a9";
>  	cpu_pmu->map_event	= armv7_a9_map_event;
> +	cpu_pmu->pmu.attr_groups = armv7_pmuv2_attr_groups;

I didn't think these guys supported PMUv2, or is that backwards compatible
with the older event definitions?

Also, would you be able to do something similar for AArch64 too, please?
(take a look at our for-next/core branch for the latest perf changes).

Thanks,

Will

^ permalink raw reply	[flat|nested] 23+ messages in thread

* [PATCHv2] arm: perf: Add event descriptions
  2015-10-09 10:13 ` Will Deacon
@ 2015-10-09 16:53   ` Drew Richardson
  2015-10-12 14:30     ` Will Deacon
  2015-10-22 14:05   ` [PATCHv2] " Drew Richardson
  1 sibling, 1 reply; 23+ messages in thread
From: Drew Richardson @ 2015-10-09 16:53 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, Oct 09, 2015 at 11:13:38AM +0100, Will Deacon wrote:
> On Wed, Oct 07, 2015 at 11:28:18AM -0700, Drew Richardson wrote:
> > Add additional information about the ARM architected hardware events
> > to make counters self describing. This makes the hardware PMUs easier
> > to use as perf list contains possible events instead of users having
> > to refer to documentation like the ARM TRMs.
> > 
> > Signed-off-by: Drew Richardson <drew.richardson@arm.com>
> > ---
> >  arch/arm/kernel/perf_event_v7.c | 96 +++++++++++++++++++++++++++++++++++++++++
> >  drivers/perf/arm_pmu.c          |  1 +
> >  2 files changed, 97 insertions(+)
> > 
> > diff --git a/arch/arm/kernel/perf_event_v7.c b/arch/arm/kernel/perf_event_v7.c
> > index 126dc679b230..6623bd0d8a1d 100644
> > --- a/arch/arm/kernel/perf_event_v7.c
> > +++ b/arch/arm/kernel/perf_event_v7.c
> > @@ -547,6 +547,95 @@ static const unsigned scorpion_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
> >  	[C(BPU)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
> >  };
> >  
> > +static ssize_t armv7_event_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);
> > +}
> 
> Can we not do this with a couple of macros, stringification of the event
> code and PMU_EVENT_ATTR_STRING, therefore avoiding this function entirely?

I assumed that doing it this way would be smaller, but using
PMU_EVENT_ATTR_STRING is a few hundred bytes smaller, see
below. (Please let me know if you'd prefer I send it out in a separate
email or even a new thread)

> > +#define ARMV7_EVENT_ATTR(name, config) \
> > +	PMU_EVENT_ATTR(name, armv7_event_attr_##name, config, \
> > +		       armv7_event_sysfs_show);
> > +
> > +ARMV7_EVENT_ATTR(sw_incr, ARMV7_PERFCTR_PMNC_SW_INCR);
> > +ARMV7_EVENT_ATTR(l1i_cache_refill, ARMV7_PERFCTR_L1_ICACHE_REFILL);
> > +ARMV7_EVENT_ATTR(l1i_tlb_refill, ARMV7_PERFCTR_ITLB_REFILL);
> > +ARMV7_EVENT_ATTR(l1d_cache_refill, ARMV7_PERFCTR_L1_DCACHE_REFILL);
> > +ARMV7_EVENT_ATTR(l1d_cache, ARMV7_PERFCTR_L1_DCACHE_ACCESS);
> > +ARMV7_EVENT_ATTR(l1d_tlb_refill, ARMV7_PERFCTR_DTLB_REFILL);
> > +ARMV7_EVENT_ATTR(ld_retired, ARMV7_PERFCTR_MEM_READ);
> > +ARMV7_EVENT_ATTR(st_retired, ARMV7_PERFCTR_MEM_WRITE);
> > +ARMV7_EVENT_ATTR(inst_retired, ARMV7_PERFCTR_INSTR_EXECUTED);
> > +ARMV7_EVENT_ATTR(exc_taken, ARMV7_PERFCTR_EXC_TAKEN);
> > +ARMV7_EVENT_ATTR(exc_return, ARMV7_PERFCTR_EXC_EXECUTED);
> > +ARMV7_EVENT_ATTR(cid_write_retired, ARMV7_PERFCTR_CID_WRITE);
> > +ARMV7_EVENT_ATTR(pc_write_retired, ARMV7_PERFCTR_PC_WRITE);
> > +ARMV7_EVENT_ATTR(br_immed_retired, ARMV7_PERFCTR_PC_IMM_BRANCH);
> > +ARMV7_EVENT_ATTR(br_return_retired, ARMV7_PERFCTR_PC_PROC_RETURN);
> > +ARMV7_EVENT_ATTR(unaligned_ldst_retired, ARMV7_PERFCTR_MEM_UNALIGNED_ACCESS);
> > +ARMV7_EVENT_ATTR(br_mis_pred, ARMV7_PERFCTR_PC_BRANCH_MIS_PRED);
> > +ARMV7_EVENT_ATTR(cpu_cycles, ARMV7_PERFCTR_CLOCK_CYCLES);
> > +ARMV7_EVENT_ATTR(br_pred, ARMV7_PERFCTR_PC_BRANCH_PRED);
> > +ARMV7_EVENT_ATTR(mem_access, ARMV7_PERFCTR_MEM_ACCESS);
> > +ARMV7_EVENT_ATTR(l1i_cache, ARMV7_PERFCTR_L1_ICACHE_ACCESS);
> > +ARMV7_EVENT_ATTR(l1d_cache_wb, ARMV7_PERFCTR_L1_DCACHE_WB);
> > +ARMV7_EVENT_ATTR(l2d_cache, ARMV7_PERFCTR_L2_CACHE_ACCESS);
> > +ARMV7_EVENT_ATTR(l2d_cache_refill, ARMV7_PERFCTR_L2_CACHE_REFILL);
> > +ARMV7_EVENT_ATTR(l2d_cache_wb, ARMV7_PERFCTR_L2_CACHE_WB);
> > +ARMV7_EVENT_ATTR(bus_access, ARMV7_PERFCTR_BUS_ACCESS);
> > +ARMV7_EVENT_ATTR(memory_error, ARMV7_PERFCTR_MEM_ERROR);
> > +ARMV7_EVENT_ATTR(inst_spec, ARMV7_PERFCTR_INSTR_SPEC);
> > +ARMV7_EVENT_ATTR(ttbr_write_retired, ARMV7_PERFCTR_TTBR_WRITE);
> > +ARMV7_EVENT_ATTR(bus_cycles, ARMV7_PERFCTR_BUS_CYCLES);
> > +
> > +static struct attribute *armv7_pmuv2_event_attrs[] = {
> > +	&armv7_event_attr_sw_incr.attr.attr,
> > +	&armv7_event_attr_l1i_cache_refill.attr.attr,
> > +	&armv7_event_attr_l1i_tlb_refill.attr.attr,
> > +	&armv7_event_attr_l1d_cache_refill.attr.attr,
> > +	&armv7_event_attr_l1d_cache.attr.attr,
> > +	&armv7_event_attr_l1d_tlb_refill.attr.attr,
> > +	&armv7_event_attr_ld_retired.attr.attr,
> > +	&armv7_event_attr_st_retired.attr.attr,
> > +	&armv7_event_attr_inst_retired.attr.attr,
> > +	&armv7_event_attr_exc_taken.attr.attr,
> > +	&armv7_event_attr_exc_return.attr.attr,
> > +	&armv7_event_attr_cid_write_retired.attr.attr,
> > +	&armv7_event_attr_pc_write_retired.attr.attr,
> > +	&armv7_event_attr_br_immed_retired.attr.attr,
> > +	&armv7_event_attr_br_return_retired.attr.attr,
> > +	&armv7_event_attr_unaligned_ldst_retired.attr.attr,
> > +	&armv7_event_attr_br_mis_pred.attr.attr,
> > +	&armv7_event_attr_cpu_cycles.attr.attr,
> > +	&armv7_event_attr_br_pred.attr.attr,
> > +	&armv7_event_attr_mem_access.attr.attr,
> > +	&armv7_event_attr_l1i_cache.attr.attr,
> > +	&armv7_event_attr_l1d_cache_wb.attr.attr,
> > +	&armv7_event_attr_l2d_cache.attr.attr,
> > +	&armv7_event_attr_l2d_cache_refill.attr.attr,
> > +	&armv7_event_attr_l2d_cache_wb.attr.attr,
> > +	&armv7_event_attr_bus_access.attr.attr,
> > +	&armv7_event_attr_memory_error.attr.attr,
> > +	&armv7_event_attr_inst_spec.attr.attr,
> > +	&armv7_event_attr_ttbr_write_retired.attr.attr,
> > +	&armv7_event_attr_bus_cycles.attr.attr,
> > +	NULL
> > +};
> > +
> > +static struct attribute_group armv7_pmuv2_events_attr_group = {
> > +	.name = "events",
> > +	.attrs = armv7_pmuv2_event_attrs,
> > +};
> > +
> > +static const struct attribute_group *armv7_pmuv2_attr_groups[] = {
> > +	&armv7_pmuv2_events_attr_group,
> > +	NULL
> > +};
> > +
> >  /*
> >   * Perf Events' indices
> >   */
> > @@ -1085,6 +1174,7 @@ static int armv7_a8_pmu_init(struct arm_pmu *cpu_pmu)
> >  	armv7pmu_init(cpu_pmu);
> >  	cpu_pmu->name		= "armv7_cortex_a8";
> >  	cpu_pmu->map_event	= armv7_a8_map_event;
> > +	cpu_pmu->pmu.attr_groups = armv7_pmuv2_attr_groups;
> >  	return armv7_probe_num_events(cpu_pmu);
> >  }
> >  
> > @@ -1093,6 +1183,7 @@ static int armv7_a9_pmu_init(struct arm_pmu *cpu_pmu)
> >  	armv7pmu_init(cpu_pmu);
> >  	cpu_pmu->name		= "armv7_cortex_a9";
> >  	cpu_pmu->map_event	= armv7_a9_map_event;
> > +	cpu_pmu->pmu.attr_groups = armv7_pmuv2_attr_groups;
> 
> I didn't think these guys supported PMUv2, or is that backwards compatible
> with the older event definitions?

You're correct. I've added a PMUv1 for the A8, A9 and A5 (the A5 seems
to have some PMUv2 events but not all of them and is not documented as
having PMUv2 support).

> Also, would you be able to do something similar for AArch64 too, please?
> (take a look at our for-next/core branch for the latest perf changes).

I'll do that and send something out soon.

---

Add additional information about the ARM architected hardware events
to make counters self describing. This makes the hardware PMUs easier
to use as perf list contains possible events instead of users having
to refer to documentation like the ARM TRMs.

Signed-off-by: Drew Richardson <drew.richardson@arm.com>
---
 arch/arm/kernel/perf_event_v7.c | 119 ++++++++++++++++++++++++++++++++++++++++
 drivers/perf/arm_pmu.c          |   1 +
 2 files changed, 120 insertions(+)

diff --git a/arch/arm/kernel/perf_event_v7.c b/arch/arm/kernel/perf_event_v7.c
index 126dc679b230..3e94e6c22e16 100644
--- a/arch/arm/kernel/perf_event_v7.c
+++ b/arch/arm/kernel/perf_event_v7.c
@@ -547,6 +547,118 @@ static const unsigned scorpion_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
 	[C(BPU)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
 };
 
+#define ARMV7_EVENT_ATTR(name, config) \
+	PMU_EVENT_ATTR_STRING(name, armv7_event_attr_##name, "event=" #config)
+
+ARMV7_EVENT_ATTR(sw_incr, 0x00);
+ARMV7_EVENT_ATTR(l1i_cache_refill, 0x01);
+ARMV7_EVENT_ATTR(l1i_tlb_refill, 0x02);
+ARMV7_EVENT_ATTR(l1d_cache_refill, 0x03);
+ARMV7_EVENT_ATTR(l1d_cache, 0x04);
+ARMV7_EVENT_ATTR(l1d_tlb_refill, 0x05);
+ARMV7_EVENT_ATTR(ld_retired, 0x06);
+ARMV7_EVENT_ATTR(st_retired, 0x07);
+ARMV7_EVENT_ATTR(inst_retired, 0x08);
+ARMV7_EVENT_ATTR(exc_taken, 0x09);
+ARMV7_EVENT_ATTR(exc_return, 0x0a);
+ARMV7_EVENT_ATTR(cid_write_retired, 0x0b);
+ARMV7_EVENT_ATTR(pc_write_retired, 0x0c);
+ARMV7_EVENT_ATTR(br_immed_retired, 0x0d);
+ARMV7_EVENT_ATTR(br_return_retired, 0x0e);
+ARMV7_EVENT_ATTR(unaligned_ldst_retired, 0x0f);
+ARMV7_EVENT_ATTR(br_mis_pred, 0x10);
+ARMV7_EVENT_ATTR(cpu_cycles, 0x11);
+ARMV7_EVENT_ATTR(br_pred, 0x12);
+
+static struct attribute *armv7_pmuv1_event_attrs[] = {
+	&armv7_event_attr_sw_incr.attr.attr,
+	&armv7_event_attr_l1i_cache_refill.attr.attr,
+	&armv7_event_attr_l1i_tlb_refill.attr.attr,
+	&armv7_event_attr_l1d_cache_refill.attr.attr,
+	&armv7_event_attr_l1d_cache.attr.attr,
+	&armv7_event_attr_l1d_tlb_refill.attr.attr,
+	&armv7_event_attr_ld_retired.attr.attr,
+	&armv7_event_attr_st_retired.attr.attr,
+	&armv7_event_attr_inst_retired.attr.attr,
+	&armv7_event_attr_exc_taken.attr.attr,
+	&armv7_event_attr_exc_return.attr.attr,
+	&armv7_event_attr_cid_write_retired.attr.attr,
+	&armv7_event_attr_pc_write_retired.attr.attr,
+	&armv7_event_attr_br_immed_retired.attr.attr,
+	&armv7_event_attr_br_return_retired.attr.attr,
+	&armv7_event_attr_unaligned_ldst_retired.attr.attr,
+	&armv7_event_attr_br_mis_pred.attr.attr,
+	&armv7_event_attr_cpu_cycles.attr.attr,
+	&armv7_event_attr_br_pred.attr.attr,
+	NULL
+};
+
+static struct attribute_group armv7_pmuv1_events_attr_group = {
+	.name = "events",
+	.attrs = armv7_pmuv1_event_attrs,
+};
+
+static const struct attribute_group *armv7_pmuv1_attr_groups[] = {
+	&armv7_pmuv1_events_attr_group,
+	NULL
+};
+
+ARMV7_EVENT_ATTR(mem_access, 0x13);
+ARMV7_EVENT_ATTR(l1i_cache, 0x14);
+ARMV7_EVENT_ATTR(l1d_cache_wb, 0x15);
+ARMV7_EVENT_ATTR(l2d_cache, 0x16);
+ARMV7_EVENT_ATTR(l2d_cache_refill, 0x17);
+ARMV7_EVENT_ATTR(l2d_cache_wb, 0x18);
+ARMV7_EVENT_ATTR(bus_access, 0x19);
+ARMV7_EVENT_ATTR(memory_error, 0x1a);
+ARMV7_EVENT_ATTR(inst_spec, 0x1b);
+ARMV7_EVENT_ATTR(ttbr_write_retired, 0x1c);
+ARMV7_EVENT_ATTR(bus_cycles, 0x1d);
+
+static struct attribute *armv7_pmuv2_event_attrs[] = {
+	&armv7_event_attr_sw_incr.attr.attr,
+	&armv7_event_attr_l1i_cache_refill.attr.attr,
+	&armv7_event_attr_l1i_tlb_refill.attr.attr,
+	&armv7_event_attr_l1d_cache_refill.attr.attr,
+	&armv7_event_attr_l1d_cache.attr.attr,
+	&armv7_event_attr_l1d_tlb_refill.attr.attr,
+	&armv7_event_attr_ld_retired.attr.attr,
+	&armv7_event_attr_st_retired.attr.attr,
+	&armv7_event_attr_inst_retired.attr.attr,
+	&armv7_event_attr_exc_taken.attr.attr,
+	&armv7_event_attr_exc_return.attr.attr,
+	&armv7_event_attr_cid_write_retired.attr.attr,
+	&armv7_event_attr_pc_write_retired.attr.attr,
+	&armv7_event_attr_br_immed_retired.attr.attr,
+	&armv7_event_attr_br_return_retired.attr.attr,
+	&armv7_event_attr_unaligned_ldst_retired.attr.attr,
+	&armv7_event_attr_br_mis_pred.attr.attr,
+	&armv7_event_attr_cpu_cycles.attr.attr,
+	&armv7_event_attr_br_pred.attr.attr,
+	&armv7_event_attr_mem_access.attr.attr,
+	&armv7_event_attr_l1i_cache.attr.attr,
+	&armv7_event_attr_l1d_cache_wb.attr.attr,
+	&armv7_event_attr_l2d_cache.attr.attr,
+	&armv7_event_attr_l2d_cache_refill.attr.attr,
+	&armv7_event_attr_l2d_cache_wb.attr.attr,
+	&armv7_event_attr_bus_access.attr.attr,
+	&armv7_event_attr_memory_error.attr.attr,
+	&armv7_event_attr_inst_spec.attr.attr,
+	&armv7_event_attr_ttbr_write_retired.attr.attr,
+	&armv7_event_attr_bus_cycles.attr.attr,
+	NULL
+};
+
+static struct attribute_group armv7_pmuv2_events_attr_group = {
+	.name = "events",
+	.attrs = armv7_pmuv2_event_attrs,
+};
+
+static const struct attribute_group *armv7_pmuv2_attr_groups[] = {
+	&armv7_pmuv2_events_attr_group,
+	NULL
+};
+
 /*
  * Perf Events' indices
  */
@@ -1085,6 +1197,7 @@ static int armv7_a8_pmu_init(struct arm_pmu *cpu_pmu)
 	armv7pmu_init(cpu_pmu);
 	cpu_pmu->name		= "armv7_cortex_a8";
 	cpu_pmu->map_event	= armv7_a8_map_event;
+	cpu_pmu->pmu.attr_groups = armv7_pmuv1_attr_groups;
 	return armv7_probe_num_events(cpu_pmu);
 }
 
@@ -1093,6 +1206,7 @@ static int armv7_a9_pmu_init(struct arm_pmu *cpu_pmu)
 	armv7pmu_init(cpu_pmu);
 	cpu_pmu->name		= "armv7_cortex_a9";
 	cpu_pmu->map_event	= armv7_a9_map_event;
+	cpu_pmu->pmu.attr_groups = armv7_pmuv1_attr_groups;
 	return armv7_probe_num_events(cpu_pmu);
 }
 
@@ -1101,6 +1215,7 @@ static int armv7_a5_pmu_init(struct arm_pmu *cpu_pmu)
 	armv7pmu_init(cpu_pmu);
 	cpu_pmu->name		= "armv7_cortex_a5";
 	cpu_pmu->map_event	= armv7_a5_map_event;
+	cpu_pmu->pmu.attr_groups = armv7_pmuv1_attr_groups;
 	return armv7_probe_num_events(cpu_pmu);
 }
 
@@ -1110,6 +1225,7 @@ static int armv7_a15_pmu_init(struct arm_pmu *cpu_pmu)
 	cpu_pmu->name		= "armv7_cortex_a15";
 	cpu_pmu->map_event	= armv7_a15_map_event;
 	cpu_pmu->set_event_filter = armv7pmu_set_event_filter;
+	cpu_pmu->pmu.attr_groups = armv7_pmuv2_attr_groups;
 	return armv7_probe_num_events(cpu_pmu);
 }
 
@@ -1119,6 +1235,7 @@ static int armv7_a7_pmu_init(struct arm_pmu *cpu_pmu)
 	cpu_pmu->name		= "armv7_cortex_a7";
 	cpu_pmu->map_event	= armv7_a7_map_event;
 	cpu_pmu->set_event_filter = armv7pmu_set_event_filter;
+	cpu_pmu->pmu.attr_groups = armv7_pmuv2_attr_groups;
 	return armv7_probe_num_events(cpu_pmu);
 }
 
@@ -1128,6 +1245,7 @@ static int armv7_a12_pmu_init(struct arm_pmu *cpu_pmu)
 	cpu_pmu->name		= "armv7_cortex_a12";
 	cpu_pmu->map_event	= armv7_a12_map_event;
 	cpu_pmu->set_event_filter = armv7pmu_set_event_filter;
+	cpu_pmu->pmu.attr_groups = armv7_pmuv2_attr_groups;
 	return armv7_probe_num_events(cpu_pmu);
 }
 
@@ -1135,6 +1253,7 @@ static int armv7_a17_pmu_init(struct arm_pmu *cpu_pmu)
 {
 	int ret = armv7_a12_pmu_init(cpu_pmu);
 	cpu_pmu->name = "armv7_cortex_a17";
+	cpu_pmu->pmu.attr_groups = armv7_pmuv2_attr_groups;
 	return ret;
 }
 
diff --git a/drivers/perf/arm_pmu.c b/drivers/perf/arm_pmu.c
index 2365a32a595e..e933d2dd71c0 100644
--- a/drivers/perf/arm_pmu.c
+++ b/drivers/perf/arm_pmu.c
@@ -548,6 +548,7 @@ static void armpmu_init(struct arm_pmu *armpmu)
 		.stop		= armpmu_stop,
 		.read		= armpmu_read,
 		.filter_match	= armpmu_filter_match,
+		.attr_groups	= armpmu->pmu.attr_groups,
 	};
 }
 
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCHv2] arm: perf: Add event descriptions
  2015-10-09 16:53   ` Drew Richardson
@ 2015-10-12 14:30     ` Will Deacon
  2015-10-12 18:10       ` Drew Richardson
  0 siblings, 1 reply; 23+ messages in thread
From: Will Deacon @ 2015-10-12 14:30 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, Oct 09, 2015 at 09:53:32AM -0700, Drew Richardson wrote:
> On Fri, Oct 09, 2015 at 11:13:38AM +0100, Will Deacon wrote:
> > On Wed, Oct 07, 2015 at 11:28:18AM -0700, Drew Richardson wrote:
> > > diff --git a/arch/arm/kernel/perf_event_v7.c b/arch/arm/kernel/perf_event_v7.c
> > > index 126dc679b230..6623bd0d8a1d 100644
> > > --- a/arch/arm/kernel/perf_event_v7.c
> > > +++ b/arch/arm/kernel/perf_event_v7.c
> > > @@ -547,6 +547,95 @@ static const unsigned scorpion_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
> > >  	[C(BPU)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
> > >  };
> > >  
> > > +static ssize_t armv7_event_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);
> > > +}
> > 
> > Can we not do this with a couple of macros, stringification of the event
> > code and PMU_EVENT_ATTR_STRING, therefore avoiding this function entirely?
> 
> I assumed that doing it this way would be smaller, but using
> PMU_EVENT_ATTR_STRING is a few hundred bytes smaller, see
> below. (Please let me know if you'd prefer I send it out in a separate
> email or even a new thread)

I think this looks much better, thanks. The only thing left to do is
re-use some of the existing event descriptions from the enum
armv7_perf_types that we have at the top of the file, rather than
duplicate the event -> ID mapping. Feel free to extend the enumeration
if you need to (it's intended to cover all of the architected events).

Thanks,

Will

^ permalink raw reply	[flat|nested] 23+ messages in thread

* [PATCHv2] arm: perf: Add event descriptions
  2015-10-12 14:30     ` Will Deacon
@ 2015-10-12 18:10       ` Drew Richardson
  2015-10-13 14:15         ` Will Deacon
                           ` (3 more replies)
  0 siblings, 4 replies; 23+ messages in thread
From: Drew Richardson @ 2015-10-12 18:10 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Oct 12, 2015 at 03:30:25PM +0100, Will Deacon wrote:
> I think this looks much better, thanks. The only thing left to do is
> re-use some of the existing event descriptions from the enum
> armv7_perf_types that we have at the top of the file, rather than
> duplicate the event -> ID mapping. Feel free to extend the enumeration
> if you need to (it's intended to cover all of the architected events).

OK, here you go. I agree that duplicating the event -> ID mapping is
undesirable, but some rather ugly preprocessor stuff is required to
convert the enum into it's hex value (is there a better way to do
this?). I think it may be less ugly if we build the string at runtime
instead of at compile time (ie, going back to using PMU_EVENT_ATTR
instead of PMU_EVENT_ATTR_STRING).

Drew

---

Add additional information about the ARM architected hardware events
to make counters self describing. This makes the hardware PMUs easier
to use as perf list contains possible events instead of users having
to refer to documentation like the ARM TRMs.

Signed-off-by: Drew Richardson <drew.richardson@arm.com>
---
 arch/arm/kernel/perf_event_v7.c | 241 +++++++++++++++++++++++++++++++++++-----
 drivers/perf/arm_pmu.c          |   1 +
 2 files changed, 212 insertions(+), 30 deletions(-)

diff --git a/arch/arm/kernel/perf_event_v7.c b/arch/arm/kernel/perf_event_v7.c
index 126dc679b230..a9a7c3e92741 100644
--- a/arch/arm/kernel/perf_event_v7.c
+++ b/arch/arm/kernel/perf_event_v7.c
@@ -36,18 +36,42 @@
  * they are not available.
  */
 enum armv7_perf_types {
-	ARMV7_PERFCTR_PMNC_SW_INCR			= 0x00,
-	ARMV7_PERFCTR_L1_ICACHE_REFILL			= 0x01,
-	ARMV7_PERFCTR_ITLB_REFILL			= 0x02,
-	ARMV7_PERFCTR_L1_DCACHE_REFILL			= 0x03,
-	ARMV7_PERFCTR_L1_DCACHE_ACCESS			= 0x04,
-	ARMV7_PERFCTR_DTLB_REFILL			= 0x05,
-	ARMV7_PERFCTR_MEM_READ				= 0x06,
-	ARMV7_PERFCTR_MEM_WRITE				= 0x07,
-	ARMV7_PERFCTR_INSTR_EXECUTED			= 0x08,
-	ARMV7_PERFCTR_EXC_TAKEN				= 0x09,
-	ARMV7_PERFCTR_EXC_EXECUTED			= 0x0A,
-	ARMV7_PERFCTR_CID_WRITE				= 0x0B,
+#define _ARMV7_PERFCTR_PMNC_SW_INCR			  0x00
+	ARMV7_PERFCTR_PMNC_SW_INCR
+	= _ARMV7_PERFCTR_PMNC_SW_INCR,
+#define _ARMV7_PERFCTR_L1_ICACHE_REFILL			  0x01
+	ARMV7_PERFCTR_L1_ICACHE_REFILL
+	= _ARMV7_PERFCTR_L1_ICACHE_REFILL,
+#define _ARMV7_PERFCTR_ITLB_REFILL			  0x02
+	ARMV7_PERFCTR_ITLB_REFILL
+	= _ARMV7_PERFCTR_ITLB_REFILL,
+#define _ARMV7_PERFCTR_L1_DCACHE_REFILL			  0x03
+	ARMV7_PERFCTR_L1_DCACHE_REFILL
+	= _ARMV7_PERFCTR_L1_DCACHE_REFILL,
+#define _ARMV7_PERFCTR_L1_DCACHE_ACCESS			  0x04
+	ARMV7_PERFCTR_L1_DCACHE_ACCESS
+	= _ARMV7_PERFCTR_L1_DCACHE_ACCESS,
+#define _ARMV7_PERFCTR_DTLB_REFILL			  0x05
+	ARMV7_PERFCTR_DTLB_REFILL
+	= _ARMV7_PERFCTR_DTLB_REFILL,
+#define _ARMV7_PERFCTR_MEM_READ				  0x06
+	ARMV7_PERFCTR_MEM_READ
+	= _ARMV7_PERFCTR_MEM_READ,
+#define _ARMV7_PERFCTR_MEM_WRITE			  0x07
+	ARMV7_PERFCTR_MEM_WRITE
+	= _ARMV7_PERFCTR_MEM_WRITE,
+#define _ARMV7_PERFCTR_INSTR_EXECUTED			  0x08
+	ARMV7_PERFCTR_INSTR_EXECUTED
+	= _ARMV7_PERFCTR_INSTR_EXECUTED,
+#define _ARMV7_PERFCTR_EXC_TAKEN			  0x09
+	ARMV7_PERFCTR_EXC_TAKEN
+	= _ARMV7_PERFCTR_EXC_TAKEN,
+#define _ARMV7_PERFCTR_EXC_EXECUTED			  0x0A
+	ARMV7_PERFCTR_EXC_EXECUTED
+	= _ARMV7_PERFCTR_EXC_EXECUTED,
+#define _ARMV7_PERFCTR_CID_WRITE			  0x0B
+	ARMV7_PERFCTR_CID_WRITE
+	= _ARMV7_PERFCTR_CID_WRITE,
 
 	/*
 	 * ARMV7_PERFCTR_PC_WRITE is equivalent to HW_BRANCH_INSTRUCTIONS.
@@ -56,26 +80,62 @@ enum armv7_perf_types {
 	 *  - instructions that explicitly write the PC,
 	 *  - exception generating instructions.
 	 */
-	ARMV7_PERFCTR_PC_WRITE				= 0x0C,
-	ARMV7_PERFCTR_PC_IMM_BRANCH			= 0x0D,
-	ARMV7_PERFCTR_PC_PROC_RETURN			= 0x0E,
-	ARMV7_PERFCTR_MEM_UNALIGNED_ACCESS		= 0x0F,
-	ARMV7_PERFCTR_PC_BRANCH_MIS_PRED		= 0x10,
-	ARMV7_PERFCTR_CLOCK_CYCLES			= 0x11,
-	ARMV7_PERFCTR_PC_BRANCH_PRED			= 0x12,
+#define _ARMV7_PERFCTR_PC_WRITE				  0x0C
+	ARMV7_PERFCTR_PC_WRITE
+	= _ARMV7_PERFCTR_PC_WRITE,
+#define _ARMV7_PERFCTR_PC_IMM_BRANCH			  0x0D
+	ARMV7_PERFCTR_PC_IMM_BRANCH
+	= _ARMV7_PERFCTR_PC_IMM_BRANCH,
+#define _ARMV7_PERFCTR_PC_PROC_RETURN			  0x0E
+	ARMV7_PERFCTR_PC_PROC_RETURN
+	= _ARMV7_PERFCTR_PC_PROC_RETURN,
+#define _ARMV7_PERFCTR_MEM_UNALIGNED_ACCESS		  0x0F
+	ARMV7_PERFCTR_MEM_UNALIGNED_ACCESS
+	= _ARMV7_PERFCTR_MEM_UNALIGNED_ACCESS,
+#define _ARMV7_PERFCTR_PC_BRANCH_MIS_PRED		  0x10
+	ARMV7_PERFCTR_PC_BRANCH_MIS_PRED
+	= _ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
+#define _ARMV7_PERFCTR_CLOCK_CYCLES			  0x11
+	ARMV7_PERFCTR_CLOCK_CYCLES
+	= _ARMV7_PERFCTR_CLOCK_CYCLES,
+#define _ARMV7_PERFCTR_PC_BRANCH_PRED			  0x12
+	ARMV7_PERFCTR_PC_BRANCH_PRED
+	= _ARMV7_PERFCTR_PC_BRANCH_PRED,
 
 	/* These events are defined by the PMUv2 supplement (ARM DDI 0457A). */
-	ARMV7_PERFCTR_MEM_ACCESS			= 0x13,
-	ARMV7_PERFCTR_L1_ICACHE_ACCESS			= 0x14,
-	ARMV7_PERFCTR_L1_DCACHE_WB			= 0x15,
-	ARMV7_PERFCTR_L2_CACHE_ACCESS			= 0x16,
-	ARMV7_PERFCTR_L2_CACHE_REFILL			= 0x17,
-	ARMV7_PERFCTR_L2_CACHE_WB			= 0x18,
-	ARMV7_PERFCTR_BUS_ACCESS			= 0x19,
-	ARMV7_PERFCTR_MEM_ERROR				= 0x1A,
-	ARMV7_PERFCTR_INSTR_SPEC			= 0x1B,
-	ARMV7_PERFCTR_TTBR_WRITE			= 0x1C,
-	ARMV7_PERFCTR_BUS_CYCLES			= 0x1D,
+#define _ARMV7_PERFCTR_MEM_ACCESS			  0x13
+	ARMV7_PERFCTR_MEM_ACCESS
+	= _ARMV7_PERFCTR_MEM_ACCESS,
+#define _ARMV7_PERFCTR_L1_ICACHE_ACCESS			  0x14
+	ARMV7_PERFCTR_L1_ICACHE_ACCESS
+	= _ARMV7_PERFCTR_L1_ICACHE_ACCESS,
+#define _ARMV7_PERFCTR_L1_DCACHE_WB			  0x15
+	ARMV7_PERFCTR_L1_DCACHE_WB
+	= _ARMV7_PERFCTR_L1_DCACHE_WB,
+#define _ARMV7_PERFCTR_L2_CACHE_ACCESS			  0x16
+	ARMV7_PERFCTR_L2_CACHE_ACCESS
+	= _ARMV7_PERFCTR_L2_CACHE_ACCESS,
+#define _ARMV7_PERFCTR_L2_CACHE_REFILL			  0x17
+	ARMV7_PERFCTR_L2_CACHE_REFILL
+	= _ARMV7_PERFCTR_L2_CACHE_REFILL,
+#define _ARMV7_PERFCTR_L2_CACHE_WB			  0x18
+	ARMV7_PERFCTR_L2_CACHE_WB
+	= _ARMV7_PERFCTR_L2_CACHE_WB,
+#define _ARMV7_PERFCTR_BUS_ACCESS			  0x19
+	ARMV7_PERFCTR_BUS_ACCESS
+	= _ARMV7_PERFCTR_BUS_ACCESS,
+#define _ARMV7_PERFCTR_MEM_ERROR			  0x1A
+	ARMV7_PERFCTR_MEM_ERROR
+	= _ARMV7_PERFCTR_MEM_ERROR,
+#define _ARMV7_PERFCTR_INSTR_SPEC			  0x1B
+	ARMV7_PERFCTR_INSTR_SPEC
+	= _ARMV7_PERFCTR_INSTR_SPEC,
+#define _ARMV7_PERFCTR_TTBR_WRITE			  0x1C
+	ARMV7_PERFCTR_TTBR_WRITE
+	= _ARMV7_PERFCTR_TTBR_WRITE,
+#define _ARMV7_PERFCTR_BUS_CYCLES			  0x1D
+	ARMV7_PERFCTR_BUS_CYCLES
+	= _ARMV7_PERFCTR_BUS_CYCLES,
 
 	ARMV7_PERFCTR_CPU_CYCLES			= 0xFF
 };
@@ -547,6 +607,120 @@ static const unsigned scorpion_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
 	[C(BPU)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
 };
 
+#define ARMV7_EVENT_ATTR_RESOLVE(m) #m
+#define ARMV7_EVENT_ATTR(name, config) \
+	PMU_EVENT_ATTR_STRING(name, armv7_event_attr_##name, \
+			      "event=" ARMV7_EVENT_ATTR_RESOLVE(config))
+
+ARMV7_EVENT_ATTR(sw_incr, _ARMV7_PERFCTR_PMNC_SW_INCR);
+ARMV7_EVENT_ATTR(l1i_cache_refill, _ARMV7_PERFCTR_L1_ICACHE_REFILL);
+ARMV7_EVENT_ATTR(l1i_tlb_refill, _ARMV7_PERFCTR_ITLB_REFILL);
+ARMV7_EVENT_ATTR(l1d_cache_refill, _ARMV7_PERFCTR_L1_DCACHE_REFILL);
+ARMV7_EVENT_ATTR(l1d_cache, _ARMV7_PERFCTR_L1_DCACHE_ACCESS);
+ARMV7_EVENT_ATTR(l1d_tlb_refill, _ARMV7_PERFCTR_DTLB_REFILL);
+ARMV7_EVENT_ATTR(ld_retired, _ARMV7_PERFCTR_MEM_READ);
+ARMV7_EVENT_ATTR(st_retired, _ARMV7_PERFCTR_MEM_WRITE);
+ARMV7_EVENT_ATTR(inst_retired, _ARMV7_PERFCTR_INSTR_EXECUTED);
+ARMV7_EVENT_ATTR(exc_taken, _ARMV7_PERFCTR_EXC_TAKEN);
+ARMV7_EVENT_ATTR(exc_return, _ARMV7_PERFCTR_EXC_EXECUTED);
+ARMV7_EVENT_ATTR(cid_write_retired, _ARMV7_PERFCTR_CID_WRITE);
+ARMV7_EVENT_ATTR(pc_write_retired, _ARMV7_PERFCTR_PC_WRITE);
+ARMV7_EVENT_ATTR(br_immed_retired, _ARMV7_PERFCTR_PC_IMM_BRANCH);
+ARMV7_EVENT_ATTR(br_return_retired, _ARMV7_PERFCTR_PC_PROC_RETURN);
+ARMV7_EVENT_ATTR(unaligned_ldst_retired, _ARMV7_PERFCTR_MEM_UNALIGNED_ACCESS);
+ARMV7_EVENT_ATTR(br_mis_pred, _ARMV7_PERFCTR_PC_BRANCH_MIS_PRED);
+ARMV7_EVENT_ATTR(cpu_cycles, _ARMV7_PERFCTR_CLOCK_CYCLES);
+ARMV7_EVENT_ATTR(br_pred, _ARMV7_PERFCTR_PC_BRANCH_PRED);
+
+static struct attribute *armv7_pmuv1_event_attrs[] = {
+	&armv7_event_attr_sw_incr.attr.attr,
+	&armv7_event_attr_l1i_cache_refill.attr.attr,
+	&armv7_event_attr_l1i_tlb_refill.attr.attr,
+	&armv7_event_attr_l1d_cache_refill.attr.attr,
+	&armv7_event_attr_l1d_cache.attr.attr,
+	&armv7_event_attr_l1d_tlb_refill.attr.attr,
+	&armv7_event_attr_ld_retired.attr.attr,
+	&armv7_event_attr_st_retired.attr.attr,
+	&armv7_event_attr_inst_retired.attr.attr,
+	&armv7_event_attr_exc_taken.attr.attr,
+	&armv7_event_attr_exc_return.attr.attr,
+	&armv7_event_attr_cid_write_retired.attr.attr,
+	&armv7_event_attr_pc_write_retired.attr.attr,
+	&armv7_event_attr_br_immed_retired.attr.attr,
+	&armv7_event_attr_br_return_retired.attr.attr,
+	&armv7_event_attr_unaligned_ldst_retired.attr.attr,
+	&armv7_event_attr_br_mis_pred.attr.attr,
+	&armv7_event_attr_cpu_cycles.attr.attr,
+	&armv7_event_attr_br_pred.attr.attr,
+	NULL
+};
+
+static struct attribute_group armv7_pmuv1_events_attr_group = {
+	.name = "events",
+	.attrs = armv7_pmuv1_event_attrs,
+};
+
+static const struct attribute_group *armv7_pmuv1_attr_groups[] = {
+	&armv7_pmuv1_events_attr_group,
+	NULL
+};
+
+ARMV7_EVENT_ATTR(mem_access, _ARMV7_PERFCTR_MEM_ACCESS);
+ARMV7_EVENT_ATTR(l1i_cache, _ARMV7_PERFCTR_L1_ICACHE_ACCESS);
+ARMV7_EVENT_ATTR(l1d_cache_wb, _ARMV7_PERFCTR_L1_DCACHE_WB);
+ARMV7_EVENT_ATTR(l2d_cache, _ARMV7_PERFCTR_L2_CACHE_ACCESS);
+ARMV7_EVENT_ATTR(l2d_cache_refill, _ARMV7_PERFCTR_L2_CACHE_REFILL);
+ARMV7_EVENT_ATTR(l2d_cache_wb, _ARMV7_PERFCTR_L2_CACHE_WB);
+ARMV7_EVENT_ATTR(bus_access, _ARMV7_PERFCTR_BUS_ACCESS);
+ARMV7_EVENT_ATTR(memory_error, _ARMV7_PERFCTR_MEM_ERROR);
+ARMV7_EVENT_ATTR(inst_spec, _ARMV7_PERFCTR_INSTR_SPEC);
+ARMV7_EVENT_ATTR(ttbr_write_retired, _ARMV7_PERFCTR_TTBR_WRITE);
+ARMV7_EVENT_ATTR(bus_cycles, _ARMV7_PERFCTR_BUS_CYCLES);
+
+static struct attribute *armv7_pmuv2_event_attrs[] = {
+	&armv7_event_attr_sw_incr.attr.attr,
+	&armv7_event_attr_l1i_cache_refill.attr.attr,
+	&armv7_event_attr_l1i_tlb_refill.attr.attr,
+	&armv7_event_attr_l1d_cache_refill.attr.attr,
+	&armv7_event_attr_l1d_cache.attr.attr,
+	&armv7_event_attr_l1d_tlb_refill.attr.attr,
+	&armv7_event_attr_ld_retired.attr.attr,
+	&armv7_event_attr_st_retired.attr.attr,
+	&armv7_event_attr_inst_retired.attr.attr,
+	&armv7_event_attr_exc_taken.attr.attr,
+	&armv7_event_attr_exc_return.attr.attr,
+	&armv7_event_attr_cid_write_retired.attr.attr,
+	&armv7_event_attr_pc_write_retired.attr.attr,
+	&armv7_event_attr_br_immed_retired.attr.attr,
+	&armv7_event_attr_br_return_retired.attr.attr,
+	&armv7_event_attr_unaligned_ldst_retired.attr.attr,
+	&armv7_event_attr_br_mis_pred.attr.attr,
+	&armv7_event_attr_cpu_cycles.attr.attr,
+	&armv7_event_attr_br_pred.attr.attr,
+	&armv7_event_attr_mem_access.attr.attr,
+	&armv7_event_attr_l1i_cache.attr.attr,
+	&armv7_event_attr_l1d_cache_wb.attr.attr,
+	&armv7_event_attr_l2d_cache.attr.attr,
+	&armv7_event_attr_l2d_cache_refill.attr.attr,
+	&armv7_event_attr_l2d_cache_wb.attr.attr,
+	&armv7_event_attr_bus_access.attr.attr,
+	&armv7_event_attr_memory_error.attr.attr,
+	&armv7_event_attr_inst_spec.attr.attr,
+	&armv7_event_attr_ttbr_write_retired.attr.attr,
+	&armv7_event_attr_bus_cycles.attr.attr,
+	NULL
+};
+
+static struct attribute_group armv7_pmuv2_events_attr_group = {
+	.name = "events",
+	.attrs = armv7_pmuv2_event_attrs,
+};
+
+static const struct attribute_group *armv7_pmuv2_attr_groups[] = {
+	&armv7_pmuv2_events_attr_group,
+	NULL
+};
+
 /*
  * Perf Events' indices
  */
@@ -1085,6 +1259,7 @@ static int armv7_a8_pmu_init(struct arm_pmu *cpu_pmu)
 	armv7pmu_init(cpu_pmu);
 	cpu_pmu->name		= "armv7_cortex_a8";
 	cpu_pmu->map_event	= armv7_a8_map_event;
+	cpu_pmu->pmu.attr_groups = armv7_pmuv1_attr_groups;
 	return armv7_probe_num_events(cpu_pmu);
 }
 
@@ -1093,6 +1268,7 @@ static int armv7_a9_pmu_init(struct arm_pmu *cpu_pmu)
 	armv7pmu_init(cpu_pmu);
 	cpu_pmu->name		= "armv7_cortex_a9";
 	cpu_pmu->map_event	= armv7_a9_map_event;
+	cpu_pmu->pmu.attr_groups = armv7_pmuv1_attr_groups;
 	return armv7_probe_num_events(cpu_pmu);
 }
 
@@ -1101,6 +1277,7 @@ static int armv7_a5_pmu_init(struct arm_pmu *cpu_pmu)
 	armv7pmu_init(cpu_pmu);
 	cpu_pmu->name		= "armv7_cortex_a5";
 	cpu_pmu->map_event	= armv7_a5_map_event;
+	cpu_pmu->pmu.attr_groups = armv7_pmuv1_attr_groups;
 	return armv7_probe_num_events(cpu_pmu);
 }
 
@@ -1110,6 +1287,7 @@ static int armv7_a15_pmu_init(struct arm_pmu *cpu_pmu)
 	cpu_pmu->name		= "armv7_cortex_a15";
 	cpu_pmu->map_event	= armv7_a15_map_event;
 	cpu_pmu->set_event_filter = armv7pmu_set_event_filter;
+	cpu_pmu->pmu.attr_groups = armv7_pmuv2_attr_groups;
 	return armv7_probe_num_events(cpu_pmu);
 }
 
@@ -1119,6 +1297,7 @@ static int armv7_a7_pmu_init(struct arm_pmu *cpu_pmu)
 	cpu_pmu->name		= "armv7_cortex_a7";
 	cpu_pmu->map_event	= armv7_a7_map_event;
 	cpu_pmu->set_event_filter = armv7pmu_set_event_filter;
+	cpu_pmu->pmu.attr_groups = armv7_pmuv2_attr_groups;
 	return armv7_probe_num_events(cpu_pmu);
 }
 
@@ -1128,6 +1307,7 @@ static int armv7_a12_pmu_init(struct arm_pmu *cpu_pmu)
 	cpu_pmu->name		= "armv7_cortex_a12";
 	cpu_pmu->map_event	= armv7_a12_map_event;
 	cpu_pmu->set_event_filter = armv7pmu_set_event_filter;
+	cpu_pmu->pmu.attr_groups = armv7_pmuv2_attr_groups;
 	return armv7_probe_num_events(cpu_pmu);
 }
 
@@ -1135,6 +1315,7 @@ static int armv7_a17_pmu_init(struct arm_pmu *cpu_pmu)
 {
 	int ret = armv7_a12_pmu_init(cpu_pmu);
 	cpu_pmu->name = "armv7_cortex_a17";
+	cpu_pmu->pmu.attr_groups = armv7_pmuv2_attr_groups;
 	return ret;
 }
 
diff --git a/drivers/perf/arm_pmu.c b/drivers/perf/arm_pmu.c
index 2365a32a595e..e933d2dd71c0 100644
--- a/drivers/perf/arm_pmu.c
+++ b/drivers/perf/arm_pmu.c
@@ -548,6 +548,7 @@ static void armpmu_init(struct arm_pmu *armpmu)
 		.stop		= armpmu_stop,
 		.read		= armpmu_read,
 		.filter_match	= armpmu_filter_match,
+		.attr_groups	= armpmu->pmu.attr_groups,
 	};
 }
 
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCHv2] arm: perf: Add event descriptions
  2015-10-12 18:10       ` Drew Richardson
@ 2015-10-13 14:15         ` Will Deacon
  2015-10-13 15:34         ` [PATCH v5 0/2] " Drew Richardson
                           ` (2 subsequent siblings)
  3 siblings, 0 replies; 23+ messages in thread
From: Will Deacon @ 2015-10-13 14:15 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Oct 12, 2015 at 11:10:38AM -0700, Drew Richardson wrote:
> On Mon, Oct 12, 2015 at 03:30:25PM +0100, Will Deacon wrote:
> > I think this looks much better, thanks. The only thing left to do is
> > re-use some of the existing event descriptions from the enum
> > armv7_perf_types that we have at the top of the file, rather than
> > duplicate the event -> ID mapping. Feel free to extend the enumeration
> > if you need to (it's intended to cover all of the architected events).
> 
> OK, here you go. I agree that duplicating the event -> ID mapping is
> undesirable, but some rather ugly preprocessor stuff is required to
> convert the enum into it's hex value (is there a better way to do
> this?). I think it may be less ugly if we build the string at runtime
> instead of at compile time (ie, going back to using PMU_EVENT_ATTR
> instead of PMU_EVENT_ATTR_STRING).

Yeah, I see what you mean. However, I don't think we actually need these
as an enum, do we? So maybe just replace the whole lot with a bunch of
#defines (mechanical change since they're already namespaced, separate
patch before this one) and then have this patch use those #defines for
the sysfs stuff.

Sorry for the to-and-fro-ing on this.

Will

^ permalink raw reply	[flat|nested] 23+ messages in thread

* [PATCH v5 0/2] arm: perf: Add event descriptions
  2015-10-12 18:10       ` Drew Richardson
  2015-10-13 14:15         ` Will Deacon
@ 2015-10-13 15:34         ` Drew Richardson
  2015-10-13 15:35         ` [PATCH v5 1/2] arm: perf: Convert event enums to #defines Drew Richardson
  2015-10-13 15:36         ` [PATCH v5 2/2] arm: perf: Add event descriptions Drew Richardson
  3 siblings, 0 replies; 23+ messages in thread
From: Drew Richardson @ 2015-10-13 15:34 UTC (permalink / raw)
  To: linux-arm-kernel

I've done as suggested and converted all the events to #defines and
split it up into two patches.

GIT: [PATCH 1/2] arm: perf: Convert event enums to #defines
GIT: [PATCH 2/2] arm: perf: Add event descriptions

^ permalink raw reply	[flat|nested] 23+ messages in thread

* [PATCH v5 1/2] arm: perf: Convert event enums to #defines
  2015-10-12 18:10       ` Drew Richardson
  2015-10-13 14:15         ` Will Deacon
  2015-10-13 15:34         ` [PATCH v5 0/2] " Drew Richardson
@ 2015-10-13 15:35         ` Drew Richardson
  2015-10-13 15:36         ` [PATCH v5 2/2] arm: perf: Add event descriptions Drew Richardson
  3 siblings, 0 replies; 23+ messages in thread
From: Drew Richardson @ 2015-10-13 15:35 UTC (permalink / raw)
  To: linux-arm-kernel

The enums are not necessary and this allows the event values to be
used to construct static strings at compile time.

Signed-off-by: Drew Richardson <drew.richardson@arm.com>
---
 arch/arm/kernel/perf_event_v7.c | 186 ++++++++++++++++++----------------------
 1 file changed, 85 insertions(+), 101 deletions(-)

diff --git a/arch/arm/kernel/perf_event_v7.c b/arch/arm/kernel/perf_event_v7.c
index 126dc679b230..dc979724e3bb 100644
--- a/arch/arm/kernel/perf_event_v7.c
+++ b/arch/arm/kernel/perf_event_v7.c
@@ -35,133 +35,117 @@
  * but the encodings are considered to be `reserved' in the case that
  * they are not available.
  */
-enum armv7_perf_types {
-	ARMV7_PERFCTR_PMNC_SW_INCR			= 0x00,
-	ARMV7_PERFCTR_L1_ICACHE_REFILL			= 0x01,
-	ARMV7_PERFCTR_ITLB_REFILL			= 0x02,
-	ARMV7_PERFCTR_L1_DCACHE_REFILL			= 0x03,
-	ARMV7_PERFCTR_L1_DCACHE_ACCESS			= 0x04,
-	ARMV7_PERFCTR_DTLB_REFILL			= 0x05,
-	ARMV7_PERFCTR_MEM_READ				= 0x06,
-	ARMV7_PERFCTR_MEM_WRITE				= 0x07,
-	ARMV7_PERFCTR_INSTR_EXECUTED			= 0x08,
-	ARMV7_PERFCTR_EXC_TAKEN				= 0x09,
-	ARMV7_PERFCTR_EXC_EXECUTED			= 0x0A,
-	ARMV7_PERFCTR_CID_WRITE				= 0x0B,
+#define ARMV7_PERFCTR_PMNC_SW_INCR			0x00
+#define ARMV7_PERFCTR_L1_ICACHE_REFILL			0x01
+#define ARMV7_PERFCTR_ITLB_REFILL			0x02
+#define ARMV7_PERFCTR_L1_DCACHE_REFILL			0x03
+#define ARMV7_PERFCTR_L1_DCACHE_ACCESS			0x04
+#define ARMV7_PERFCTR_DTLB_REFILL			0x05
+#define ARMV7_PERFCTR_MEM_READ				0x06
+#define ARMV7_PERFCTR_MEM_WRITE				0x07
+#define ARMV7_PERFCTR_INSTR_EXECUTED			0x08
+#define ARMV7_PERFCTR_EXC_TAKEN				0x09
+#define ARMV7_PERFCTR_EXC_EXECUTED			0x0A
+#define ARMV7_PERFCTR_CID_WRITE				0x0B
 
-	/*
-	 * ARMV7_PERFCTR_PC_WRITE is equivalent to HW_BRANCH_INSTRUCTIONS.
-	 * It counts:
-	 *  - all (taken) branch instructions,
-	 *  - instructions that explicitly write the PC,
-	 *  - exception generating instructions.
-	 */
-	ARMV7_PERFCTR_PC_WRITE				= 0x0C,
-	ARMV7_PERFCTR_PC_IMM_BRANCH			= 0x0D,
-	ARMV7_PERFCTR_PC_PROC_RETURN			= 0x0E,
-	ARMV7_PERFCTR_MEM_UNALIGNED_ACCESS		= 0x0F,
-	ARMV7_PERFCTR_PC_BRANCH_MIS_PRED		= 0x10,
-	ARMV7_PERFCTR_CLOCK_CYCLES			= 0x11,
-	ARMV7_PERFCTR_PC_BRANCH_PRED			= 0x12,
-
-	/* These events are defined by the PMUv2 supplement (ARM DDI 0457A). */
-	ARMV7_PERFCTR_MEM_ACCESS			= 0x13,
-	ARMV7_PERFCTR_L1_ICACHE_ACCESS			= 0x14,
-	ARMV7_PERFCTR_L1_DCACHE_WB			= 0x15,
-	ARMV7_PERFCTR_L2_CACHE_ACCESS			= 0x16,
-	ARMV7_PERFCTR_L2_CACHE_REFILL			= 0x17,
-	ARMV7_PERFCTR_L2_CACHE_WB			= 0x18,
-	ARMV7_PERFCTR_BUS_ACCESS			= 0x19,
-	ARMV7_PERFCTR_MEM_ERROR				= 0x1A,
-	ARMV7_PERFCTR_INSTR_SPEC			= 0x1B,
-	ARMV7_PERFCTR_TTBR_WRITE			= 0x1C,
-	ARMV7_PERFCTR_BUS_CYCLES			= 0x1D,
-
-	ARMV7_PERFCTR_CPU_CYCLES			= 0xFF
-};
+/*
+ * ARMV7_PERFCTR_PC_WRITE is equivalent to HW_BRANCH_INSTRUCTIONS.
+ * It counts:
+ *  - all (taken) branch instructions,
+ *  - instructions that explicitly write the PC,
+ *  - exception generating instructions.
+ */
+#define ARMV7_PERFCTR_PC_WRITE				0x0C
+#define ARMV7_PERFCTR_PC_IMM_BRANCH			0x0D
+#define ARMV7_PERFCTR_PC_PROC_RETURN			0x0E
+#define ARMV7_PERFCTR_MEM_UNALIGNED_ACCESS		0x0F
+#define ARMV7_PERFCTR_PC_BRANCH_MIS_PRED		0x10
+#define ARMV7_PERFCTR_CLOCK_CYCLES			0x11
+#define ARMV7_PERFCTR_PC_BRANCH_PRED			0x12
+
+/* These events are defined by the PMUv2 supplement (ARM DDI 0457A). */
+#define ARMV7_PERFCTR_MEM_ACCESS			0x13
+#define ARMV7_PERFCTR_L1_ICACHE_ACCESS			0x14
+#define ARMV7_PERFCTR_L1_DCACHE_WB			0x15
+#define ARMV7_PERFCTR_L2_CACHE_ACCESS			0x16
+#define ARMV7_PERFCTR_L2_CACHE_REFILL			0x17
+#define ARMV7_PERFCTR_L2_CACHE_WB			0x18
+#define ARMV7_PERFCTR_BUS_ACCESS			0x19
+#define ARMV7_PERFCTR_MEM_ERROR				0x1A
+#define ARMV7_PERFCTR_INSTR_SPEC			0x1B
+#define ARMV7_PERFCTR_TTBR_WRITE			0x1C
+#define ARMV7_PERFCTR_BUS_CYCLES			0x1D
+
+#define ARMV7_PERFCTR_CPU_CYCLES			0xFF
 
 /* ARMv7 Cortex-A8 specific event types */
-enum armv7_a8_perf_types {
-	ARMV7_A8_PERFCTR_L2_CACHE_ACCESS		= 0x43,
-	ARMV7_A8_PERFCTR_L2_CACHE_REFILL		= 0x44,
-	ARMV7_A8_PERFCTR_L1_ICACHE_ACCESS		= 0x50,
-	ARMV7_A8_PERFCTR_STALL_ISIDE			= 0x56,
-};
+#define ARMV7_A8_PERFCTR_L2_CACHE_ACCESS		0x43
+#define ARMV7_A8_PERFCTR_L2_CACHE_REFILL		0x44
+#define ARMV7_A8_PERFCTR_L1_ICACHE_ACCESS		0x50
+#define ARMV7_A8_PERFCTR_STALL_ISIDE			0x56
 
 /* ARMv7 Cortex-A9 specific event types */
-enum armv7_a9_perf_types {
-	ARMV7_A9_PERFCTR_INSTR_CORE_RENAME		= 0x68,
-	ARMV7_A9_PERFCTR_STALL_ICACHE			= 0x60,
-	ARMV7_A9_PERFCTR_STALL_DISPATCH			= 0x66,
-};
+#define ARMV7_A9_PERFCTR_INSTR_CORE_RENAME		0x68
+#define ARMV7_A9_PERFCTR_STALL_ICACHE			0x60
+#define ARMV7_A9_PERFCTR_STALL_DISPATCH			0x66
 
 /* ARMv7 Cortex-A5 specific event types */
-enum armv7_a5_perf_types {
-	ARMV7_A5_PERFCTR_PREFETCH_LINEFILL		= 0xc2,
-	ARMV7_A5_PERFCTR_PREFETCH_LINEFILL_DROP		= 0xc3,
-};
+#define ARMV7_A5_PERFCTR_PREFETCH_LINEFILL		0xc2
+#define ARMV7_A5_PERFCTR_PREFETCH_LINEFILL_DROP		0xc3
 
 /* ARMv7 Cortex-A15 specific event types */
-enum armv7_a15_perf_types {
-	ARMV7_A15_PERFCTR_L1_DCACHE_ACCESS_READ		= 0x40,
-	ARMV7_A15_PERFCTR_L1_DCACHE_ACCESS_WRITE	= 0x41,
-	ARMV7_A15_PERFCTR_L1_DCACHE_REFILL_READ		= 0x42,
-	ARMV7_A15_PERFCTR_L1_DCACHE_REFILL_WRITE	= 0x43,
+#define ARMV7_A15_PERFCTR_L1_DCACHE_ACCESS_READ		0x40
+#define ARMV7_A15_PERFCTR_L1_DCACHE_ACCESS_WRITE	0x41
+#define ARMV7_A15_PERFCTR_L1_DCACHE_REFILL_READ		0x42
+#define ARMV7_A15_PERFCTR_L1_DCACHE_REFILL_WRITE	0x43
 
-	ARMV7_A15_PERFCTR_DTLB_REFILL_L1_READ		= 0x4C,
-	ARMV7_A15_PERFCTR_DTLB_REFILL_L1_WRITE		= 0x4D,
+#define ARMV7_A15_PERFCTR_DTLB_REFILL_L1_READ		0x4C
+#define ARMV7_A15_PERFCTR_DTLB_REFILL_L1_WRITE		0x4D
 
-	ARMV7_A15_PERFCTR_L2_CACHE_ACCESS_READ		= 0x50,
-	ARMV7_A15_PERFCTR_L2_CACHE_ACCESS_WRITE		= 0x51,
-	ARMV7_A15_PERFCTR_L2_CACHE_REFILL_READ		= 0x52,
-	ARMV7_A15_PERFCTR_L2_CACHE_REFILL_WRITE		= 0x53,
+#define ARMV7_A15_PERFCTR_L2_CACHE_ACCESS_READ		0x50
+#define ARMV7_A15_PERFCTR_L2_CACHE_ACCESS_WRITE		0x51
+#define ARMV7_A15_PERFCTR_L2_CACHE_REFILL_READ		0x52
+#define ARMV7_A15_PERFCTR_L2_CACHE_REFILL_WRITE		0x53
 
-	ARMV7_A15_PERFCTR_PC_WRITE_SPEC			= 0x76,
-};
+#define ARMV7_A15_PERFCTR_PC_WRITE_SPEC			0x76
 
 /* ARMv7 Cortex-A12 specific event types */
-enum armv7_a12_perf_types {
-	ARMV7_A12_PERFCTR_L1_DCACHE_ACCESS_READ		= 0x40,
-	ARMV7_A12_PERFCTR_L1_DCACHE_ACCESS_WRITE	= 0x41,
+#define ARMV7_A12_PERFCTR_L1_DCACHE_ACCESS_READ		0x40
+#define ARMV7_A12_PERFCTR_L1_DCACHE_ACCESS_WRITE	0x41
 
-	ARMV7_A12_PERFCTR_L2_CACHE_ACCESS_READ		= 0x50,
-	ARMV7_A12_PERFCTR_L2_CACHE_ACCESS_WRITE		= 0x51,
+#define ARMV7_A12_PERFCTR_L2_CACHE_ACCESS_READ		0x50
+#define ARMV7_A12_PERFCTR_L2_CACHE_ACCESS_WRITE		0x51
 
-	ARMV7_A12_PERFCTR_PC_WRITE_SPEC			= 0x76,
+#define ARMV7_A12_PERFCTR_PC_WRITE_SPEC			0x76
 
-	ARMV7_A12_PERFCTR_PF_TLB_REFILL			= 0xe7,
-};
+#define ARMV7_A12_PERFCTR_PF_TLB_REFILL			0xe7
 
 /* ARMv7 Krait specific event types */
-enum krait_perf_types {
-	KRAIT_PMRESR0_GROUP0				= 0xcc,
-	KRAIT_PMRESR1_GROUP0				= 0xd0,
-	KRAIT_PMRESR2_GROUP0				= 0xd4,
-	KRAIT_VPMRESR0_GROUP0				= 0xd8,
+#define KRAIT_PMRESR0_GROUP0				0xcc
+#define KRAIT_PMRESR1_GROUP0				0xd0
+#define KRAIT_PMRESR2_GROUP0				0xd4
+#define KRAIT_VPMRESR0_GROUP0				0xd8
 
-	KRAIT_PERFCTR_L1_ICACHE_ACCESS			= 0x10011,
-	KRAIT_PERFCTR_L1_ICACHE_MISS			= 0x10010,
+#define KRAIT_PERFCTR_L1_ICACHE_ACCESS			0x10011
+#define KRAIT_PERFCTR_L1_ICACHE_MISS			0x10010
 
-	KRAIT_PERFCTR_L1_ITLB_ACCESS			= 0x12222,
-	KRAIT_PERFCTR_L1_DTLB_ACCESS			= 0x12210,
-};
+#define KRAIT_PERFCTR_L1_ITLB_ACCESS			0x12222
+#define KRAIT_PERFCTR_L1_DTLB_ACCESS			0x12210
 
 /* ARMv7 Scorpion specific event types */
-enum scorpion_perf_types {
-	SCORPION_LPM0_GROUP0				= 0x4c,
-	SCORPION_LPM1_GROUP0				= 0x50,
-	SCORPION_LPM2_GROUP0				= 0x54,
-	SCORPION_L2LPM_GROUP0				= 0x58,
-	SCORPION_VLPM_GROUP0				= 0x5c,
+#define SCORPION_LPM0_GROUP0				0x4c
+#define SCORPION_LPM1_GROUP0				0x50
+#define SCORPION_LPM2_GROUP0				0x54
+#define SCORPION_L2LPM_GROUP0				0x58
+#define SCORPION_VLPM_GROUP0				0x5c
 
-	SCORPION_ICACHE_ACCESS				= 0x10053,
-	SCORPION_ICACHE_MISS				= 0x10052,
+#define SCORPION_ICACHE_ACCESS				0x10053
+#define SCORPION_ICACHE_MISS				0x10052
 
-	SCORPION_DTLB_ACCESS				= 0x12013,
-	SCORPION_DTLB_MISS				= 0x12012,
+#define SCORPION_DTLB_ACCESS				0x12013
+#define SCORPION_DTLB_MISS				0x12012
 
-	SCORPION_ITLB_MISS				= 0x12021,
-};
+#define SCORPION_ITLB_MISS				0x12021
 
 /*
  * Cortex-A8 HW events mapping
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH v5 2/2] arm: perf: Add event descriptions
  2015-10-12 18:10       ` Drew Richardson
                           ` (2 preceding siblings ...)
  2015-10-13 15:35         ` [PATCH v5 1/2] arm: perf: Convert event enums to #defines Drew Richardson
@ 2015-10-13 15:36         ` Drew Richardson
  2015-10-15 13:21           ` Will Deacon
  3 siblings, 1 reply; 23+ messages in thread
From: Drew Richardson @ 2015-10-13 15:36 UTC (permalink / raw)
  To: linux-arm-kernel

Add additional information about the ARM architected hardware events
to make counters self describing. This makes the hardware PMUs easier
to use as perf list contains possible events instead of users having
to refer to documentation like the ARM TRMs.

Signed-off-by: Drew Richardson <drew.richardson@arm.com>
---
 arch/arm/kernel/perf_event_v7.c | 121 ++++++++++++++++++++++++++++++++++++++++
 drivers/perf/arm_pmu.c          |   1 +
 2 files changed, 122 insertions(+)

diff --git a/arch/arm/kernel/perf_event_v7.c b/arch/arm/kernel/perf_event_v7.c
index dc979724e3bb..970e1364e484 100644
--- a/arch/arm/kernel/perf_event_v7.c
+++ b/arch/arm/kernel/perf_event_v7.c
@@ -531,6 +531,120 @@ static const unsigned scorpion_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
 	[C(BPU)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
 };
 
+#define ARMV7_EVENT_ATTR_RESOLVE(m) #m
+#define ARMV7_EVENT_ATTR(name, config) \
+	PMU_EVENT_ATTR_STRING(name, armv7_event_attr_##name, \
+			      "event=" ARMV7_EVENT_ATTR_RESOLVE(config))
+
+ARMV7_EVENT_ATTR(sw_incr, ARMV7_PERFCTR_PMNC_SW_INCR);
+ARMV7_EVENT_ATTR(l1i_cache_refill, ARMV7_PERFCTR_L1_ICACHE_REFILL);
+ARMV7_EVENT_ATTR(l1i_tlb_refill, ARMV7_PERFCTR_ITLB_REFILL);
+ARMV7_EVENT_ATTR(l1d_cache_refill, ARMV7_PERFCTR_L1_DCACHE_REFILL);
+ARMV7_EVENT_ATTR(l1d_cache, ARMV7_PERFCTR_L1_DCACHE_ACCESS);
+ARMV7_EVENT_ATTR(l1d_tlb_refill, ARMV7_PERFCTR_DTLB_REFILL);
+ARMV7_EVENT_ATTR(ld_retired, ARMV7_PERFCTR_MEM_READ);
+ARMV7_EVENT_ATTR(st_retired, ARMV7_PERFCTR_MEM_WRITE);
+ARMV7_EVENT_ATTR(inst_retired, ARMV7_PERFCTR_INSTR_EXECUTED);
+ARMV7_EVENT_ATTR(exc_taken, ARMV7_PERFCTR_EXC_TAKEN);
+ARMV7_EVENT_ATTR(exc_return, ARMV7_PERFCTR_EXC_EXECUTED);
+ARMV7_EVENT_ATTR(cid_write_retired, ARMV7_PERFCTR_CID_WRITE);
+ARMV7_EVENT_ATTR(pc_write_retired, ARMV7_PERFCTR_PC_WRITE);
+ARMV7_EVENT_ATTR(br_immed_retired, ARMV7_PERFCTR_PC_IMM_BRANCH);
+ARMV7_EVENT_ATTR(br_return_retired, ARMV7_PERFCTR_PC_PROC_RETURN);
+ARMV7_EVENT_ATTR(unaligned_ldst_retired, ARMV7_PERFCTR_MEM_UNALIGNED_ACCESS);
+ARMV7_EVENT_ATTR(br_mis_pred, ARMV7_PERFCTR_PC_BRANCH_MIS_PRED);
+ARMV7_EVENT_ATTR(cpu_cycles, ARMV7_PERFCTR_CLOCK_CYCLES);
+ARMV7_EVENT_ATTR(br_pred, ARMV7_PERFCTR_PC_BRANCH_PRED);
+
+static struct attribute *armv7_pmuv1_event_attrs[] = {
+	&armv7_event_attr_sw_incr.attr.attr,
+	&armv7_event_attr_l1i_cache_refill.attr.attr,
+	&armv7_event_attr_l1i_tlb_refill.attr.attr,
+	&armv7_event_attr_l1d_cache_refill.attr.attr,
+	&armv7_event_attr_l1d_cache.attr.attr,
+	&armv7_event_attr_l1d_tlb_refill.attr.attr,
+	&armv7_event_attr_ld_retired.attr.attr,
+	&armv7_event_attr_st_retired.attr.attr,
+	&armv7_event_attr_inst_retired.attr.attr,
+	&armv7_event_attr_exc_taken.attr.attr,
+	&armv7_event_attr_exc_return.attr.attr,
+	&armv7_event_attr_cid_write_retired.attr.attr,
+	&armv7_event_attr_pc_write_retired.attr.attr,
+	&armv7_event_attr_br_immed_retired.attr.attr,
+	&armv7_event_attr_br_return_retired.attr.attr,
+	&armv7_event_attr_unaligned_ldst_retired.attr.attr,
+	&armv7_event_attr_br_mis_pred.attr.attr,
+	&armv7_event_attr_cpu_cycles.attr.attr,
+	&armv7_event_attr_br_pred.attr.attr,
+	NULL
+};
+
+static struct attribute_group armv7_pmuv1_events_attr_group = {
+	.name = "events",
+	.attrs = armv7_pmuv1_event_attrs,
+};
+
+static const struct attribute_group *armv7_pmuv1_attr_groups[] = {
+	&armv7_pmuv1_events_attr_group,
+	NULL
+};
+
+ARMV7_EVENT_ATTR(mem_access, ARMV7_PERFCTR_MEM_ACCESS);
+ARMV7_EVENT_ATTR(l1i_cache, ARMV7_PERFCTR_L1_ICACHE_ACCESS);
+ARMV7_EVENT_ATTR(l1d_cache_wb, ARMV7_PERFCTR_L1_DCACHE_WB);
+ARMV7_EVENT_ATTR(l2d_cache, ARMV7_PERFCTR_L2_CACHE_ACCESS);
+ARMV7_EVENT_ATTR(l2d_cache_refill, ARMV7_PERFCTR_L2_CACHE_REFILL);
+ARMV7_EVENT_ATTR(l2d_cache_wb, ARMV7_PERFCTR_L2_CACHE_WB);
+ARMV7_EVENT_ATTR(bus_access, ARMV7_PERFCTR_BUS_ACCESS);
+ARMV7_EVENT_ATTR(memory_error, ARMV7_PERFCTR_MEM_ERROR);
+ARMV7_EVENT_ATTR(inst_spec, ARMV7_PERFCTR_INSTR_SPEC);
+ARMV7_EVENT_ATTR(ttbr_write_retired, ARMV7_PERFCTR_TTBR_WRITE);
+ARMV7_EVENT_ATTR(bus_cycles, ARMV7_PERFCTR_BUS_CYCLES);
+
+static struct attribute *armv7_pmuv2_event_attrs[] = {
+	&armv7_event_attr_sw_incr.attr.attr,
+	&armv7_event_attr_l1i_cache_refill.attr.attr,
+	&armv7_event_attr_l1i_tlb_refill.attr.attr,
+	&armv7_event_attr_l1d_cache_refill.attr.attr,
+	&armv7_event_attr_l1d_cache.attr.attr,
+	&armv7_event_attr_l1d_tlb_refill.attr.attr,
+	&armv7_event_attr_ld_retired.attr.attr,
+	&armv7_event_attr_st_retired.attr.attr,
+	&armv7_event_attr_inst_retired.attr.attr,
+	&armv7_event_attr_exc_taken.attr.attr,
+	&armv7_event_attr_exc_return.attr.attr,
+	&armv7_event_attr_cid_write_retired.attr.attr,
+	&armv7_event_attr_pc_write_retired.attr.attr,
+	&armv7_event_attr_br_immed_retired.attr.attr,
+	&armv7_event_attr_br_return_retired.attr.attr,
+	&armv7_event_attr_unaligned_ldst_retired.attr.attr,
+	&armv7_event_attr_br_mis_pred.attr.attr,
+	&armv7_event_attr_cpu_cycles.attr.attr,
+	&armv7_event_attr_br_pred.attr.attr,
+	&armv7_event_attr_mem_access.attr.attr,
+	&armv7_event_attr_l1i_cache.attr.attr,
+	&armv7_event_attr_l1d_cache_wb.attr.attr,
+	&armv7_event_attr_l2d_cache.attr.attr,
+	&armv7_event_attr_l2d_cache_refill.attr.attr,
+	&armv7_event_attr_l2d_cache_wb.attr.attr,
+	&armv7_event_attr_bus_access.attr.attr,
+	&armv7_event_attr_memory_error.attr.attr,
+	&armv7_event_attr_inst_spec.attr.attr,
+	&armv7_event_attr_ttbr_write_retired.attr.attr,
+	&armv7_event_attr_bus_cycles.attr.attr,
+	NULL
+};
+
+static struct attribute_group armv7_pmuv2_events_attr_group = {
+	.name = "events",
+	.attrs = armv7_pmuv2_event_attrs,
+};
+
+static const struct attribute_group *armv7_pmuv2_attr_groups[] = {
+	&armv7_pmuv2_events_attr_group,
+	NULL
+};
+
 /*
  * Perf Events' indices
  */
@@ -1069,6 +1183,7 @@ static int armv7_a8_pmu_init(struct arm_pmu *cpu_pmu)
 	armv7pmu_init(cpu_pmu);
 	cpu_pmu->name		= "armv7_cortex_a8";
 	cpu_pmu->map_event	= armv7_a8_map_event;
+	cpu_pmu->pmu.attr_groups = armv7_pmuv1_attr_groups;
 	return armv7_probe_num_events(cpu_pmu);
 }
 
@@ -1077,6 +1192,7 @@ static int armv7_a9_pmu_init(struct arm_pmu *cpu_pmu)
 	armv7pmu_init(cpu_pmu);
 	cpu_pmu->name		= "armv7_cortex_a9";
 	cpu_pmu->map_event	= armv7_a9_map_event;
+	cpu_pmu->pmu.attr_groups = armv7_pmuv1_attr_groups;
 	return armv7_probe_num_events(cpu_pmu);
 }
 
@@ -1085,6 +1201,7 @@ static int armv7_a5_pmu_init(struct arm_pmu *cpu_pmu)
 	armv7pmu_init(cpu_pmu);
 	cpu_pmu->name		= "armv7_cortex_a5";
 	cpu_pmu->map_event	= armv7_a5_map_event;
+	cpu_pmu->pmu.attr_groups = armv7_pmuv1_attr_groups;
 	return armv7_probe_num_events(cpu_pmu);
 }
 
@@ -1094,6 +1211,7 @@ static int armv7_a15_pmu_init(struct arm_pmu *cpu_pmu)
 	cpu_pmu->name		= "armv7_cortex_a15";
 	cpu_pmu->map_event	= armv7_a15_map_event;
 	cpu_pmu->set_event_filter = armv7pmu_set_event_filter;
+	cpu_pmu->pmu.attr_groups = armv7_pmuv2_attr_groups;
 	return armv7_probe_num_events(cpu_pmu);
 }
 
@@ -1103,6 +1221,7 @@ static int armv7_a7_pmu_init(struct arm_pmu *cpu_pmu)
 	cpu_pmu->name		= "armv7_cortex_a7";
 	cpu_pmu->map_event	= armv7_a7_map_event;
 	cpu_pmu->set_event_filter = armv7pmu_set_event_filter;
+	cpu_pmu->pmu.attr_groups = armv7_pmuv2_attr_groups;
 	return armv7_probe_num_events(cpu_pmu);
 }
 
@@ -1112,6 +1231,7 @@ static int armv7_a12_pmu_init(struct arm_pmu *cpu_pmu)
 	cpu_pmu->name		= "armv7_cortex_a12";
 	cpu_pmu->map_event	= armv7_a12_map_event;
 	cpu_pmu->set_event_filter = armv7pmu_set_event_filter;
+	cpu_pmu->pmu.attr_groups = armv7_pmuv2_attr_groups;
 	return armv7_probe_num_events(cpu_pmu);
 }
 
@@ -1119,6 +1239,7 @@ static int armv7_a17_pmu_init(struct arm_pmu *cpu_pmu)
 {
 	int ret = armv7_a12_pmu_init(cpu_pmu);
 	cpu_pmu->name = "armv7_cortex_a17";
+	cpu_pmu->pmu.attr_groups = armv7_pmuv2_attr_groups;
 	return ret;
 }
 
diff --git a/drivers/perf/arm_pmu.c b/drivers/perf/arm_pmu.c
index 2365a32a595e..e933d2dd71c0 100644
--- a/drivers/perf/arm_pmu.c
+++ b/drivers/perf/arm_pmu.c
@@ -548,6 +548,7 @@ static void armpmu_init(struct arm_pmu *armpmu)
 		.stop		= armpmu_stop,
 		.read		= armpmu_read,
 		.filter_match	= armpmu_filter_match,
+		.attr_groups	= armpmu->pmu.attr_groups,
 	};
 }
 
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH v5 2/2] arm: perf: Add event descriptions
  2015-10-13 15:36         ` [PATCH v5 2/2] arm: perf: Add event descriptions Drew Richardson
@ 2015-10-15 13:21           ` Will Deacon
  2015-10-15 15:15             ` Drew Richardson
  0 siblings, 1 reply; 23+ messages in thread
From: Will Deacon @ 2015-10-15 13:21 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Oct 13, 2015 at 08:36:45AM -0700, Drew Richardson wrote:
> Add additional information about the ARM architected hardware events
> to make counters self describing. This makes the hardware PMUs easier
> to use as perf list contains possible events instead of users having
> to refer to documentation like the ARM TRMs.
> 
> Signed-off-by: Drew Richardson <drew.richardson@arm.com>
> ---
>  arch/arm/kernel/perf_event_v7.c | 121 ++++++++++++++++++++++++++++++++++++++++
>  drivers/perf/arm_pmu.c          |   1 +
>  2 files changed, 122 insertions(+)

[...]

> diff --git a/drivers/perf/arm_pmu.c b/drivers/perf/arm_pmu.c
> index 2365a32a595e..e933d2dd71c0 100644
> --- a/drivers/perf/arm_pmu.c
> +++ b/drivers/perf/arm_pmu.c
> @@ -548,6 +548,7 @@ static void armpmu_init(struct arm_pmu *armpmu)
>  		.stop		= armpmu_stop,
>  		.read		= armpmu_read,
>  		.filter_match	= armpmu_filter_match,
> +		.attr_groups	= armpmu->pmu.attr_groups,

I don't understand this hunk. What's it doing?

Will

^ permalink raw reply	[flat|nested] 23+ messages in thread

* [PATCH v5 2/2] arm: perf: Add event descriptions
  2015-10-15 13:21           ` Will Deacon
@ 2015-10-15 15:15             ` Drew Richardson
  2015-10-15 15:20               ` Pawel Moll
  2015-10-15 15:29               ` Will Deacon
  0 siblings, 2 replies; 23+ messages in thread
From: Drew Richardson @ 2015-10-15 15:15 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Oct 15, 2015 at 02:21:12PM +0100, Will Deacon wrote:
> On Tue, Oct 13, 2015 at 08:36:45AM -0700, Drew Richardson wrote:
> > Add additional information about the ARM architected hardware events
> > to make counters self describing. This makes the hardware PMUs easier
> > to use as perf list contains possible events instead of users having
> > to refer to documentation like the ARM TRMs.
> > 
> > Signed-off-by: Drew Richardson <drew.richardson@arm.com>
> > ---
> >  arch/arm/kernel/perf_event_v7.c | 121 ++++++++++++++++++++++++++++++++++++++++
> >  drivers/perf/arm_pmu.c          |   1 +
> >  2 files changed, 122 insertions(+)
> 
> [...]
> 
> > diff --git a/drivers/perf/arm_pmu.c b/drivers/perf/arm_pmu.c
> > index 2365a32a595e..e933d2dd71c0 100644
> > --- a/drivers/perf/arm_pmu.c
> > +++ b/drivers/perf/arm_pmu.c
> > @@ -548,6 +548,7 @@ static void armpmu_init(struct arm_pmu *armpmu)
> >  		.stop		= armpmu_stop,
> >  		.read		= armpmu_read,
> >  		.filter_match	= armpmu_filter_match,
> > +		.attr_groups	= armpmu->pmu.attr_groups,
> 
> I don't understand this hunk. What's it doing?

I'm not 100% clear either on what it's doing. But without this line
the attr_groups don't get passed on and I don't see them on my TC2. I
debugged the issue down to this but it may not be the proper way to
solve the problem.

Drew

^ permalink raw reply	[flat|nested] 23+ messages in thread

* [PATCH v5 2/2] arm: perf: Add event descriptions
  2015-10-15 15:15             ` Drew Richardson
@ 2015-10-15 15:20               ` Pawel Moll
  2015-10-15 15:42                 ` Mark Rutland
  2015-10-15 15:29               ` Will Deacon
  1 sibling, 1 reply; 23+ messages in thread
From: Pawel Moll @ 2015-10-15 15:20 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, 2015-10-15 at 08:15 -0700, Drew Richardson wrote:
> On Thu, Oct 15, 2015 at 02:21:12PM +0100, Will Deacon wrote:
> > On Tue, Oct 13, 2015 at 08:36:45AM -0700, Drew Richardson wrote:
> > > Add additional information about the ARM architected hardware events
> > > to make counters self describing. This makes the hardware PMUs easier
> > > to use as perf list contains possible events instead of users having
> > > to refer to documentation like the ARM TRMs.
> > > 
> > > Signed-off-by: Drew Richardson <drew.richardson@arm.com>
> > > ---
> > >  arch/arm/kernel/perf_event_v7.c | 121 ++++++++++++++++++++++++++++++++++++++++
> > >  drivers/perf/arm_pmu.c          |   1 +
> > >  2 files changed, 122 insertions(+)
> > 
> > [...]
> > 
> > > diff --git a/drivers/perf/arm_pmu.c b/drivers/perf/arm_pmu.c
> > > index 2365a32a595e..e933d2dd71c0 100644
> > > --- a/drivers/perf/arm_pmu.c
> > > +++ b/drivers/perf/arm_pmu.c
> > > @@ -548,6 +548,7 @@ static void armpmu_init(struct arm_pmu *armpmu)
> > >  		.stop		= armpmu_stop,
> > >  		.read		= armpmu_read,
> > >  		.filter_match	= armpmu_filter_match,
> > > +		.attr_groups	= armpmu->pmu.attr_groups,
> > 
> > I don't understand this hunk. What's it doing?
> 
> I'm not 100% clear either on what it's doing. But without this line
> the attr_groups don't get passed on and I don't see them on my TC2. I
> debugged the issue down to this but it may not be the proper way to
> solve the problem.

The perf core creates attributes passed as pmu.attr_groups
in /sys/bus/events/devices/<pmu>.

Pawel

^ permalink raw reply	[flat|nested] 23+ messages in thread

* [PATCH v5 2/2] arm: perf: Add event descriptions
  2015-10-15 15:15             ` Drew Richardson
  2015-10-15 15:20               ` Pawel Moll
@ 2015-10-15 15:29               ` Will Deacon
  2015-10-15 15:41                 ` Mark Rutland
  1 sibling, 1 reply; 23+ messages in thread
From: Will Deacon @ 2015-10-15 15:29 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Oct 15, 2015 at 08:15:06AM -0700, Drew Richardson wrote:
> On Thu, Oct 15, 2015 at 02:21:12PM +0100, Will Deacon wrote:
> > On Tue, Oct 13, 2015 at 08:36:45AM -0700, Drew Richardson wrote:
> > > Add additional information about the ARM architected hardware events
> > > to make counters self describing. This makes the hardware PMUs easier
> > > to use as perf list contains possible events instead of users having
> > > to refer to documentation like the ARM TRMs.
> > > 
> > > Signed-off-by: Drew Richardson <drew.richardson@arm.com>
> > > ---
> > >  arch/arm/kernel/perf_event_v7.c | 121 ++++++++++++++++++++++++++++++++++++++++
> > >  drivers/perf/arm_pmu.c          |   1 +
> > >  2 files changed, 122 insertions(+)
> > 
> > [...]
> > 
> > > diff --git a/drivers/perf/arm_pmu.c b/drivers/perf/arm_pmu.c
> > > index 2365a32a595e..e933d2dd71c0 100644
> > > --- a/drivers/perf/arm_pmu.c
> > > +++ b/drivers/perf/arm_pmu.c
> > > @@ -548,6 +548,7 @@ static void armpmu_init(struct arm_pmu *armpmu)
> > >  		.stop		= armpmu_stop,
> > >  		.read		= armpmu_read,
> > >  		.filter_match	= armpmu_filter_match,
> > > +		.attr_groups	= armpmu->pmu.attr_groups,
> > 
> > I don't understand this hunk. What's it doing?
> 
> I'm not 100% clear either on what it's doing. But without this line
> the attr_groups don't get passed on and I don't see them on my TC2. I
> debugged the issue down to this but it may not be the proper way to
> solve the problem.

Oh yuck, it's because we call armpmu_init after cpu_pmu_init and the former
uses struct initialisation and ends up zeroing anything set previously.

We should probably tidy all this up:

  * Remove armpmu_register and call perf_pmu_register directly from
    arm_pmu_device_probe instead

  * Call armpmu_init immediately prior to arm_cpu_init

Will

^ permalink raw reply	[flat|nested] 23+ messages in thread

* [PATCH v5 2/2] arm: perf: Add event descriptions
  2015-10-15 15:29               ` Will Deacon
@ 2015-10-15 15:41                 ` Mark Rutland
  2015-10-15 16:31                   ` Drew Richardson
  0 siblings, 1 reply; 23+ messages in thread
From: Mark Rutland @ 2015-10-15 15:41 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Oct 15, 2015 at 04:29:15PM +0100, Will Deacon wrote:
> On Thu, Oct 15, 2015 at 08:15:06AM -0700, Drew Richardson wrote:
> > On Thu, Oct 15, 2015 at 02:21:12PM +0100, Will Deacon wrote:
> > > On Tue, Oct 13, 2015 at 08:36:45AM -0700, Drew Richardson wrote:
> > > > Add additional information about the ARM architected hardware events
> > > > to make counters self describing. This makes the hardware PMUs easier
> > > > to use as perf list contains possible events instead of users having
> > > > to refer to documentation like the ARM TRMs.
> > > > 
> > > > Signed-off-by: Drew Richardson <drew.richardson@arm.com>
> > > > ---
> > > >  arch/arm/kernel/perf_event_v7.c | 121 ++++++++++++++++++++++++++++++++++++++++
> > > >  drivers/perf/arm_pmu.c          |   1 +
> > > >  2 files changed, 122 insertions(+)
> > > 
> > > [...]
> > > 
> > > > diff --git a/drivers/perf/arm_pmu.c b/drivers/perf/arm_pmu.c
> > > > index 2365a32a595e..e933d2dd71c0 100644
> > > > --- a/drivers/perf/arm_pmu.c
> > > > +++ b/drivers/perf/arm_pmu.c
> > > > @@ -548,6 +548,7 @@ static void armpmu_init(struct arm_pmu *armpmu)
> > > >  		.stop		= armpmu_stop,
> > > >  		.read		= armpmu_read,
> > > >  		.filter_match	= armpmu_filter_match,
> > > > +		.attr_groups	= armpmu->pmu.attr_groups,
> > > 
> > > I don't understand this hunk. What's it doing?
> > 
> > I'm not 100% clear either on what it's doing. But without this line
> > the attr_groups don't get passed on and I don't see them on my TC2. I
> > debugged the issue down to this but it may not be the proper way to
> > solve the problem.
> 
> Oh yuck, it's because we call armpmu_init after cpu_pmu_init and the former
> uses struct initialisation and ends up zeroing anything set previously.
> 
> We should probably tidy all this up:
> 
>   * Remove armpmu_register and call perf_pmu_register directly from
>     arm_pmu_device_probe instead
> 
>   * Call armpmu_init immediately prior to arm_cpu_init

Assuming you mean cpu_pmu_init, how about the below?

Thanks,
Mark.

---->8----
>From f8a99a406f3dd7a272a6dee4a551436fea851f38 Mon Sep 17 00:00:00 2001
From: Mark Rutland <mark.rutland@arm.com>
Date: Thu, 15 Oct 2015 16:32:17 +0100
Subject: [PATCH] drivers/perf: kill armpmu_register

Nothing outside of drivers/perf/arm_pmu.c should call armpmu_register
any more, so it no longer needs to be in include/linux/perf/arm_pmu.h.
Additionally, by folding it in to arm_pmu_device_probe we can allow
drivers to override struct pmu fields without getting blatted by the
armpmu code.

This patch folds armpmu_register into arm_pmu_device_probe. The logging
to the console is moved to after the PMU is successfully registered with
the core perf code.

Signed-off-by: Mark Rutland <mark.rutland@arm.com>
Suggested-by: Will Deacon <will.deacon@arm.com>
Cc: Drew Richardson <drew.richardson@arm.com>
Cc: Pawel Moll <pawel.moll@arm.com>
---
 drivers/perf/arm_pmu.c       | 14 +++++---------
 include/linux/perf/arm_pmu.h |  2 --
 2 files changed, 5 insertions(+), 11 deletions(-)

diff --git a/drivers/perf/arm_pmu.c b/drivers/perf/arm_pmu.c
index f346960..15463cb 100644
--- a/drivers/perf/arm_pmu.c
+++ b/drivers/perf/arm_pmu.c
@@ -583,14 +583,6 @@ static void armpmu_init(struct arm_pmu *armpmu)
 	};
 }
 
-int armpmu_register(struct arm_pmu *armpmu, int type)
-{
-	armpmu_init(armpmu);
-	pr_info("enabled with %s PMU driver, %d counters available\n",
-			armpmu->name, armpmu->num_events);
-	return perf_pmu_register(&armpmu->pmu, armpmu->name, type);
-}
-
 /* Set at runtime when we know what CPU type we are. */
 static struct arm_pmu *__oprofile_cpu_pmu;
 
@@ -934,14 +926,18 @@ int arm_pmu_device_probe(struct platform_device *pdev,
 		goto out_free;
 	}
 
+	armpmu_init(pmu);
 	ret = cpu_pmu_init(pmu);
 	if (ret)
 		goto out_free;
 
-	ret = armpmu_register(pmu, -1);
+	ret = perf_pmu_register(&pmu->pmu, pmu->name, -1);
 	if (ret)
 		goto out_destroy;
 
+	pr_info("enabled with %s PMU driver, %d counters available\n",
+			pmu->name, pmu->num_events);
+
 	return 0;
 
 out_destroy:
diff --git a/include/linux/perf/arm_pmu.h b/include/linux/perf/arm_pmu.h
index bfa673b..83b5e34 100644
--- a/include/linux/perf/arm_pmu.h
+++ b/include/linux/perf/arm_pmu.h
@@ -111,8 +111,6 @@ struct arm_pmu {
 
 #define to_arm_pmu(p) (container_of(p, struct arm_pmu, pmu))
 
-int armpmu_register(struct arm_pmu *armpmu, int type);
-
 u64 armpmu_event_update(struct perf_event *event);
 
 int armpmu_event_set_period(struct perf_event *event);
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH v5 2/2] arm: perf: Add event descriptions
  2015-10-15 15:20               ` Pawel Moll
@ 2015-10-15 15:42                 ` Mark Rutland
  2015-10-15 15:49                   ` Pawel Moll
  0 siblings, 1 reply; 23+ messages in thread
From: Mark Rutland @ 2015-10-15 15:42 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Oct 15, 2015 at 04:20:37PM +0100, Pawel Moll wrote:
> On Thu, 2015-10-15 at 08:15 -0700, Drew Richardson wrote:
> > On Thu, Oct 15, 2015 at 02:21:12PM +0100, Will Deacon wrote:
> > > On Tue, Oct 13, 2015 at 08:36:45AM -0700, Drew Richardson wrote:
> > > > Add additional information about the ARM architected hardware events
> > > > to make counters self describing. This makes the hardware PMUs easier
> > > > to use as perf list contains possible events instead of users having
> > > > to refer to documentation like the ARM TRMs.
> > > > 
> > > > Signed-off-by: Drew Richardson <drew.richardson@arm.com>
> > > > ---
> > > >  arch/arm/kernel/perf_event_v7.c | 121 ++++++++++++++++++++++++++++++++++++++++
> > > >  drivers/perf/arm_pmu.c          |   1 +
> > > >  2 files changed, 122 insertions(+)
> > > 
> > > [...]
> > > 
> > > > diff --git a/drivers/perf/arm_pmu.c b/drivers/perf/arm_pmu.c
> > > > index 2365a32a595e..e933d2dd71c0 100644
> > > > --- a/drivers/perf/arm_pmu.c
> > > > +++ b/drivers/perf/arm_pmu.c
> > > > @@ -548,6 +548,7 @@ static void armpmu_init(struct arm_pmu *armpmu)
> > > >  		.stop		= armpmu_stop,
> > > >  		.read		= armpmu_read,
> > > >  		.filter_match	= armpmu_filter_match,
> > > > +		.attr_groups	= armpmu->pmu.attr_groups,
> > > 
> > > I don't understand this hunk. What's it doing?
> > 
> > I'm not 100% clear either on what it's doing. But without this line
> > the attr_groups don't get passed on and I don't see them on my TC2. I
> > debugged the issue down to this but it may not be the proper way to
> > solve the problem.
> 
> The perf core creates attributes passed as pmu.attr_groups
> in /sys/bus/events/devices/<pmu>.

Sure, but the confusion here had to do with why we were re-assigning the
field to itself rather than what the purpose of said field was.

Thanks,
Mark.

^ permalink raw reply	[flat|nested] 23+ messages in thread

* [PATCH v5 2/2] arm: perf: Add event descriptions
  2015-10-15 15:42                 ` Mark Rutland
@ 2015-10-15 15:49                   ` Pawel Moll
  0 siblings, 0 replies; 23+ messages in thread
From: Pawel Moll @ 2015-10-15 15:49 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, 2015-10-15 at 16:42 +0100, Mark Rutland wrote:
> On Thu, Oct 15, 2015 at 04:20:37PM +0100, Pawel Moll wrote:
> > On Thu, 2015-10-15 at 08:15 -0700, Drew Richardson wrote:
> > > On Thu, Oct 15, 2015 at 02:21:12PM +0100, Will Deacon wrote:
> > > > On Tue, Oct 13, 2015 at 08:36:45AM -0700, Drew Richardson wrote:
> > > > > Add additional information about the ARM architected hardware events
> > > > > to make counters self describing. This makes the hardware PMUs easier
> > > > > to use as perf list contains possible events instead of users having
> > > > > to refer to documentation like the ARM TRMs.
> > > > > 
> > > > > Signed-off-by: Drew Richardson <drew.richardson@arm.com>
> > > > > ---
> > > > >  arch/arm/kernel/perf_event_v7.c | 121 ++++++++++++++++++++++++++++++++++++++++
> > > > >  drivers/perf/arm_pmu.c          |   1 +
> > > > >  2 files changed, 122 insertions(+)
> > > > 
> > > > [...]
> > > > 
> > > > > diff --git a/drivers/perf/arm_pmu.c b/drivers/perf/arm_pmu.c
> > > > > index 2365a32a595e..e933d2dd71c0 100644
> > > > > --- a/drivers/perf/arm_pmu.c
> > > > > +++ b/drivers/perf/arm_pmu.c
> > > > > @@ -548,6 +548,7 @@ static void armpmu_init(struct arm_pmu *armpmu)
> > > > >  		.stop		= armpmu_stop,
> > > > >  		.read		= armpmu_read,
> > > > >  		.filter_match	= armpmu_filter_match,
> > > > > +		.attr_groups	= armpmu->pmu.attr_groups,
> > > > 
> > > > I don't understand this hunk. What's it doing?
> > > 
> > > I'm not 100% clear either on what it's doing. But without this line
> > > the attr_groups don't get passed on and I don't see them on my TC2. I
> > > debugged the issue down to this but it may not be the proper way to
> > > solve the problem.
> > 
> > The perf core creates attributes passed as pmu.attr_groups
> > in /sys/bus/events/devices/<pmu>.
> 
> Sure, but the confusion here had to do with why we were re-assigning the
> field to itself rather than what the purpose of said field was.

Ah, right. Sorry. I must admit I haven't looked to the right from the =
sign...

Pawel

^ permalink raw reply	[flat|nested] 23+ messages in thread

* [PATCH v5 2/2] arm: perf: Add event descriptions
  2015-10-15 15:41                 ` Mark Rutland
@ 2015-10-15 16:31                   ` Drew Richardson
  2015-10-15 16:44                     ` Mark Rutland
  0 siblings, 1 reply; 23+ messages in thread
From: Drew Richardson @ 2015-10-15 16:31 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Oct 15, 2015 at 04:41:26PM +0100, Mark Rutland wrote:
> On Thu, Oct 15, 2015 at 04:29:15PM +0100, Will Deacon wrote:
> > On Thu, Oct 15, 2015 at 08:15:06AM -0700, Drew Richardson wrote:
> > > On Thu, Oct 15, 2015 at 02:21:12PM +0100, Will Deacon wrote:
> > > > On Tue, Oct 13, 2015 at 08:36:45AM -0700, Drew Richardson wrote:
> > > > > Add additional information about the ARM architected hardware events
> > > > > to make counters self describing. This makes the hardware PMUs easier
> > > > > to use as perf list contains possible events instead of users having
> > > > > to refer to documentation like the ARM TRMs.
> > > > > 
> > > > > Signed-off-by: Drew Richardson <drew.richardson@arm.com>
> > > > > ---
> > > > >  arch/arm/kernel/perf_event_v7.c | 121 ++++++++++++++++++++++++++++++++++++++++
> > > > >  drivers/perf/arm_pmu.c          |   1 +
> > > > >  2 files changed, 122 insertions(+)
> > > > 
> > > > [...]
> > > > 
> > > > > diff --git a/drivers/perf/arm_pmu.c b/drivers/perf/arm_pmu.c
> > > > > index 2365a32a595e..e933d2dd71c0 100644
> > > > > --- a/drivers/perf/arm_pmu.c
> > > > > +++ b/drivers/perf/arm_pmu.c
> > > > > @@ -548,6 +548,7 @@ static void armpmu_init(struct arm_pmu *armpmu)
> > > > >  		.stop		= armpmu_stop,
> > > > >  		.read		= armpmu_read,
> > > > >  		.filter_match	= armpmu_filter_match,
> > > > > +		.attr_groups	= armpmu->pmu.attr_groups,
> > > > 
> > > > I don't understand this hunk. What's it doing?
> > > 
> > > I'm not 100% clear either on what it's doing. But without this line
> > > the attr_groups don't get passed on and I don't see them on my TC2. I
> > > debugged the issue down to this but it may not be the proper way to
> > > solve the problem.
> > 
> > Oh yuck, it's because we call armpmu_init after cpu_pmu_init and the former
> > uses struct initialisation and ends up zeroing anything set previously.
> > 
> > We should probably tidy all this up:
> > 
> >   * Remove armpmu_register and call perf_pmu_register directly from
> >     arm_pmu_device_probe instead
> > 
> >   * Call armpmu_init immediately prior to arm_cpu_init
> 
> Assuming you mean cpu_pmu_init, how about the below?
> 
> Thanks,
> Mark.
> 
> ---->8----
> From f8a99a406f3dd7a272a6dee4a551436fea851f38 Mon Sep 17 00:00:00 2001
> From: Mark Rutland <mark.rutland@arm.com>
> Date: Thu, 15 Oct 2015 16:32:17 +0100
> Subject: [PATCH] drivers/perf: kill armpmu_register
> 
> Nothing outside of drivers/perf/arm_pmu.c should call armpmu_register
> any more, so it no longer needs to be in include/linux/perf/arm_pmu.h.
> Additionally, by folding it in to arm_pmu_device_probe we can allow
> drivers to override struct pmu fields without getting blatted by the
> armpmu code.
> 
> This patch folds armpmu_register into arm_pmu_device_probe. The logging
> to the console is moved to after the PMU is successfully registered with
> the core perf code.
> 
> Signed-off-by: Mark Rutland <mark.rutland@arm.com>
> Suggested-by: Will Deacon <will.deacon@arm.com>
> Cc: Drew Richardson <drew.richardson@arm.com>
> Cc: Pawel Moll <pawel.moll@arm.com>
> ---
>  drivers/perf/arm_pmu.c       | 14 +++++---------
>  include/linux/perf/arm_pmu.h |  2 --
>  2 files changed, 5 insertions(+), 11 deletions(-)
> 
> diff --git a/drivers/perf/arm_pmu.c b/drivers/perf/arm_pmu.c
> index f346960..15463cb 100644
> --- a/drivers/perf/arm_pmu.c
> +++ b/drivers/perf/arm_pmu.c
> @@ -583,14 +583,6 @@ static void armpmu_init(struct arm_pmu *armpmu)
>  	};
>  }
>  
> -int armpmu_register(struct arm_pmu *armpmu, int type)
> -{
> -	armpmu_init(armpmu);
> -	pr_info("enabled with %s PMU driver, %d counters available\n",
> -			armpmu->name, armpmu->num_events);
> -	return perf_pmu_register(&armpmu->pmu, armpmu->name, type);
> -}
> -
>  /* Set at runtime when we know what CPU type we are. */
>  static struct arm_pmu *__oprofile_cpu_pmu;
>  
> @@ -934,14 +926,18 @@ int arm_pmu_device_probe(struct platform_device *pdev,
>  		goto out_free;
>  	}
>  
> +	armpmu_init(pmu);
>  	ret = cpu_pmu_init(pmu);
>  	if (ret)
>  		goto out_free;
>  
> -	ret = armpmu_register(pmu, -1);
> +	ret = perf_pmu_register(&pmu->pmu, pmu->name, -1);
>  	if (ret)
>  		goto out_destroy;
>  
> +	pr_info("enabled with %s PMU driver, %d counters available\n",
> +			pmu->name, pmu->num_events);
> +
>  	return 0;
>  
>  out_destroy:
> diff --git a/include/linux/perf/arm_pmu.h b/include/linux/perf/arm_pmu.h
> index bfa673b..83b5e34 100644
> --- a/include/linux/perf/arm_pmu.h
> +++ b/include/linux/perf/arm_pmu.h
> @@ -111,8 +111,6 @@ struct arm_pmu {
>  
>  #define to_arm_pmu(p) (container_of(p, struct arm_pmu, pmu))
>  
> -int armpmu_register(struct arm_pmu *armpmu, int type);
> -
>  u64 armpmu_event_update(struct perf_event *event);
>  
>  int armpmu_event_set_period(struct perf_event *event);
> -- 
> 1.9.1
> 

Unfortunately the copy of attr_groups in armpmu_init is still required
even with this patch. The armv7_a*_pmu_init functions are obtained
from the platform_device (assigned to init_fn) and called before
armpmu_init.

Drew

^ permalink raw reply	[flat|nested] 23+ messages in thread

* [PATCH v5 2/2] arm: perf: Add event descriptions
  2015-10-15 16:31                   ` Drew Richardson
@ 2015-10-15 16:44                     ` Mark Rutland
  0 siblings, 0 replies; 23+ messages in thread
From: Mark Rutland @ 2015-10-15 16:44 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Oct 15, 2015 at 09:31:46AM -0700, Drew Richardson wrote:
> On Thu, Oct 15, 2015 at 04:41:26PM +0100, Mark Rutland wrote:
> > On Thu, Oct 15, 2015 at 04:29:15PM +0100, Will Deacon wrote:
> > > On Thu, Oct 15, 2015 at 08:15:06AM -0700, Drew Richardson wrote:
> > > > On Thu, Oct 15, 2015 at 02:21:12PM +0100, Will Deacon wrote:
> > > > > On Tue, Oct 13, 2015 at 08:36:45AM -0700, Drew Richardson wrote:
> > > > > > Add additional information about the ARM architected hardware events
> > > > > > to make counters self describing. This makes the hardware PMUs easier
> > > > > > to use as perf list contains possible events instead of users having
> > > > > > to refer to documentation like the ARM TRMs.
> > > > > > 
> > > > > > Signed-off-by: Drew Richardson <drew.richardson@arm.com>
> > > > > > ---
> > > > > >  arch/arm/kernel/perf_event_v7.c | 121 ++++++++++++++++++++++++++++++++++++++++
> > > > > >  drivers/perf/arm_pmu.c          |   1 +
> > > > > >  2 files changed, 122 insertions(+)
> > > > > 
> > > > > [...]
> > > > > 
> > > > > > diff --git a/drivers/perf/arm_pmu.c b/drivers/perf/arm_pmu.c
> > > > > > index 2365a32a595e..e933d2dd71c0 100644
> > > > > > --- a/drivers/perf/arm_pmu.c
> > > > > > +++ b/drivers/perf/arm_pmu.c
> > > > > > @@ -548,6 +548,7 @@ static void armpmu_init(struct arm_pmu *armpmu)
> > > > > >  		.stop		= armpmu_stop,
> > > > > >  		.read		= armpmu_read,
> > > > > >  		.filter_match	= armpmu_filter_match,
> > > > > > +		.attr_groups	= armpmu->pmu.attr_groups,
> > > > > 
> > > > > I don't understand this hunk. What's it doing?
> > > > 
> > > > I'm not 100% clear either on what it's doing. But without this line
> > > > the attr_groups don't get passed on and I don't see them on my TC2. I
> > > > debugged the issue down to this but it may not be the proper way to
> > > > solve the problem.
> > > 
> > > Oh yuck, it's because we call armpmu_init after cpu_pmu_init and the former
> > > uses struct initialisation and ends up zeroing anything set previously.
> > > 
> > > We should probably tidy all this up:
> > > 
> > >   * Remove armpmu_register and call perf_pmu_register directly from
> > >     arm_pmu_device_probe instead
> > > 
> > >   * Call armpmu_init immediately prior to arm_cpu_init
> > 
> > Assuming you mean cpu_pmu_init, how about the below?
> > 
> > Thanks,
> > Mark.
> > 
> > ---->8----
> > From f8a99a406f3dd7a272a6dee4a551436fea851f38 Mon Sep 17 00:00:00 2001
> > From: Mark Rutland <mark.rutland@arm.com>
> > Date: Thu, 15 Oct 2015 16:32:17 +0100
> > Subject: [PATCH] drivers/perf: kill armpmu_register
> > 
> > Nothing outside of drivers/perf/arm_pmu.c should call armpmu_register
> > any more, so it no longer needs to be in include/linux/perf/arm_pmu.h.
> > Additionally, by folding it in to arm_pmu_device_probe we can allow
> > drivers to override struct pmu fields without getting blatted by the
> > armpmu code.
> > 
> > This patch folds armpmu_register into arm_pmu_device_probe. The logging
> > to the console is moved to after the PMU is successfully registered with
> > the core perf code.
> > 
> > Signed-off-by: Mark Rutland <mark.rutland@arm.com>
> > Suggested-by: Will Deacon <will.deacon@arm.com>
> > Cc: Drew Richardson <drew.richardson@arm.com>
> > Cc: Pawel Moll <pawel.moll@arm.com>
> > ---
> >  drivers/perf/arm_pmu.c       | 14 +++++---------
> >  include/linux/perf/arm_pmu.h |  2 --
> >  2 files changed, 5 insertions(+), 11 deletions(-)
> > 
> > diff --git a/drivers/perf/arm_pmu.c b/drivers/perf/arm_pmu.c
> > index f346960..15463cb 100644
> > --- a/drivers/perf/arm_pmu.c
> > +++ b/drivers/perf/arm_pmu.c
> > @@ -583,14 +583,6 @@ static void armpmu_init(struct arm_pmu *armpmu)
> >  	};
> >  }
> >  
> > -int armpmu_register(struct arm_pmu *armpmu, int type)
> > -{
> > -	armpmu_init(armpmu);
> > -	pr_info("enabled with %s PMU driver, %d counters available\n",
> > -			armpmu->name, armpmu->num_events);
> > -	return perf_pmu_register(&armpmu->pmu, armpmu->name, type);
> > -}
> > -
> >  /* Set at runtime when we know what CPU type we are. */
> >  static struct arm_pmu *__oprofile_cpu_pmu;
> >  
> > @@ -934,14 +926,18 @@ int arm_pmu_device_probe(struct platform_device *pdev,
> >  		goto out_free;
> >  	}
> >  
> > +	armpmu_init(pmu);
> >  	ret = cpu_pmu_init(pmu);
> >  	if (ret)
> >  		goto out_free;
> >  
> > -	ret = armpmu_register(pmu, -1);
> > +	ret = perf_pmu_register(&pmu->pmu, pmu->name, -1);
> >  	if (ret)
> >  		goto out_destroy;
> >  
> > +	pr_info("enabled with %s PMU driver, %d counters available\n",
> > +			pmu->name, pmu->num_events);
> > +
> >  	return 0;
> >  
> >  out_destroy:
> > diff --git a/include/linux/perf/arm_pmu.h b/include/linux/perf/arm_pmu.h
> > index bfa673b..83b5e34 100644
> > --- a/include/linux/perf/arm_pmu.h
> > +++ b/include/linux/perf/arm_pmu.h
> > @@ -111,8 +111,6 @@ struct arm_pmu {
> >  
> >  #define to_arm_pmu(p) (container_of(p, struct arm_pmu, pmu))
> >  
> > -int armpmu_register(struct arm_pmu *armpmu, int type);
> > -
> >  u64 armpmu_event_update(struct perf_event *event);
> >  
> >  int armpmu_event_set_period(struct perf_event *event);
> > -- 
> > 1.9.1
> > 
> 
> Unfortunately the copy of attr_groups in armpmu_init is still required
> even with this patch. The armv7_a*_pmu_init functions are obtained
> from the platform_device (assigned to init_fn) and called before
> armpmu_init.

Ah, whoops. Sorry about that.

It looks like I should be able to move armpmu_init immediately after it
gets allocated, before the init_fn gets called. I'll respin (and test)
the patch.

Thanks,
Mark.

^ permalink raw reply	[flat|nested] 23+ messages in thread

* [PATCHv2] arm: perf: Add event descriptions
  2015-10-09 10:13 ` Will Deacon
  2015-10-09 16:53   ` Drew Richardson
@ 2015-10-22 14:05   ` Drew Richardson
  2015-10-22 14:07     ` [PATCH 1/2] arm64: perf: Convert event enums to #defines Drew Richardson
                       ` (2 more replies)
  1 sibling, 3 replies; 23+ messages in thread
From: Drew Richardson @ 2015-10-22 14:05 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, Oct 09, 2015 at 03:13:38AM -0700, Will Deacon wrote:
> Also, would you be able to do something similar for AArch64 too, please?
> (take a look at our for-next/core branch for the latest perf changes).

Here are some almost identical patches for AArch64 based on arm64
tree's for-next/core branch. Please note that this is dependent on
some change to drivers/perf/arm_pmu.c so that pmu.attr_groups is
preserved.

Drew

^ permalink raw reply	[flat|nested] 23+ messages in thread

* [PATCH 1/2] arm64: perf: Convert event enums to #defines
  2015-10-22 14:05   ` [PATCHv2] " Drew Richardson
@ 2015-10-22 14:07     ` Drew Richardson
  2015-10-22 14:07     ` [PATCH 2/2] arm64: perf: Add event descriptions Drew Richardson
  2015-10-27 17:32     ` [PATCHv2] arm: " Will Deacon
  2 siblings, 0 replies; 23+ messages in thread
From: Drew Richardson @ 2015-10-22 14:07 UTC (permalink / raw)
  To: linux-arm-kernel

The enums are not necessary and this allows the event values to be
used to construct static strings at compile time.

Signed-off-by: Drew Richardson <drew.richardson@arm.com>
---
 arch/arm64/kernel/perf_event.c | 95 ++++++++++++++++++++----------------------
 1 file changed, 45 insertions(+), 50 deletions(-)

diff --git a/arch/arm64/kernel/perf_event.c b/arch/arm64/kernel/perf_event.c
index 5b1897e8ca24..7e4372ee4dfb 100644
--- a/arch/arm64/kernel/perf_event.c
+++ b/arch/arm64/kernel/perf_event.c
@@ -29,60 +29,55 @@
  * ARMv8 PMUv3 Performance Events handling code.
  * Common event types.
  */
-enum armv8_pmuv3_perf_types {
-	/* Required events. */
-	ARMV8_PMUV3_PERFCTR_PMNC_SW_INCR			= 0x00,
-	ARMV8_PMUV3_PERFCTR_L1_DCACHE_REFILL			= 0x03,
-	ARMV8_PMUV3_PERFCTR_L1_DCACHE_ACCESS			= 0x04,
-	ARMV8_PMUV3_PERFCTR_PC_BRANCH_MIS_PRED			= 0x10,
-	ARMV8_PMUV3_PERFCTR_CLOCK_CYCLES			= 0x11,
-	ARMV8_PMUV3_PERFCTR_PC_BRANCH_PRED			= 0x12,
-
-	/* At least one of the following is required. */
-	ARMV8_PMUV3_PERFCTR_INSTR_EXECUTED			= 0x08,
-	ARMV8_PMUV3_PERFCTR_OP_SPEC				= 0x1B,
-
-	/* Common architectural events. */
-	ARMV8_PMUV3_PERFCTR_MEM_READ				= 0x06,
-	ARMV8_PMUV3_PERFCTR_MEM_WRITE				= 0x07,
-	ARMV8_PMUV3_PERFCTR_EXC_TAKEN				= 0x09,
-	ARMV8_PMUV3_PERFCTR_EXC_EXECUTED			= 0x0A,
-	ARMV8_PMUV3_PERFCTR_CID_WRITE				= 0x0B,
-	ARMV8_PMUV3_PERFCTR_PC_WRITE				= 0x0C,
-	ARMV8_PMUV3_PERFCTR_PC_IMM_BRANCH			= 0x0D,
-	ARMV8_PMUV3_PERFCTR_PC_PROC_RETURN			= 0x0E,
-	ARMV8_PMUV3_PERFCTR_MEM_UNALIGNED_ACCESS		= 0x0F,
-	ARMV8_PMUV3_PERFCTR_TTBR_WRITE				= 0x1C,
-
-	/* Common microarchitectural events. */
-	ARMV8_PMUV3_PERFCTR_L1_ICACHE_REFILL			= 0x01,
-	ARMV8_PMUV3_PERFCTR_ITLB_REFILL				= 0x02,
-	ARMV8_PMUV3_PERFCTR_DTLB_REFILL				= 0x05,
-	ARMV8_PMUV3_PERFCTR_MEM_ACCESS				= 0x13,
-	ARMV8_PMUV3_PERFCTR_L1_ICACHE_ACCESS			= 0x14,
-	ARMV8_PMUV3_PERFCTR_L1_DCACHE_WB			= 0x15,
-	ARMV8_PMUV3_PERFCTR_L2_CACHE_ACCESS			= 0x16,
-	ARMV8_PMUV3_PERFCTR_L2_CACHE_REFILL			= 0x17,
-	ARMV8_PMUV3_PERFCTR_L2_CACHE_WB				= 0x18,
-	ARMV8_PMUV3_PERFCTR_BUS_ACCESS				= 0x19,
-	ARMV8_PMUV3_PERFCTR_MEM_ERROR				= 0x1A,
-	ARMV8_PMUV3_PERFCTR_BUS_CYCLES				= 0x1D,
-};
+
+/* Required events. */
+#define ARMV8_PMUV3_PERFCTR_PMNC_SW_INCR			0x00
+#define ARMV8_PMUV3_PERFCTR_L1_DCACHE_REFILL			0x03
+#define ARMV8_PMUV3_PERFCTR_L1_DCACHE_ACCESS			0x04
+#define ARMV8_PMUV3_PERFCTR_PC_BRANCH_MIS_PRED			0x10
+#define ARMV8_PMUV3_PERFCTR_CLOCK_CYCLES			0x11
+#define ARMV8_PMUV3_PERFCTR_PC_BRANCH_PRED			0x12
+
+/* At least one of the following is required. */
+#define ARMV8_PMUV3_PERFCTR_INSTR_EXECUTED			0x08
+#define ARMV8_PMUV3_PERFCTR_OP_SPEC				0x1B
+
+/* Common architectural events. */
+#define ARMV8_PMUV3_PERFCTR_MEM_READ				0x06
+#define ARMV8_PMUV3_PERFCTR_MEM_WRITE				0x07
+#define ARMV8_PMUV3_PERFCTR_EXC_TAKEN				0x09
+#define ARMV8_PMUV3_PERFCTR_EXC_EXECUTED			0x0A
+#define ARMV8_PMUV3_PERFCTR_CID_WRITE				0x0B
+#define ARMV8_PMUV3_PERFCTR_PC_WRITE				0x0C
+#define ARMV8_PMUV3_PERFCTR_PC_IMM_BRANCH			0x0D
+#define ARMV8_PMUV3_PERFCTR_PC_PROC_RETURN			0x0E
+#define ARMV8_PMUV3_PERFCTR_MEM_UNALIGNED_ACCESS		0x0F
+#define ARMV8_PMUV3_PERFCTR_TTBR_WRITE				0x1C
+
+/* Common microarchitectural events. */
+#define ARMV8_PMUV3_PERFCTR_L1_ICACHE_REFILL			0x01
+#define ARMV8_PMUV3_PERFCTR_ITLB_REFILL				0x02
+#define ARMV8_PMUV3_PERFCTR_DTLB_REFILL				0x05
+#define ARMV8_PMUV3_PERFCTR_MEM_ACCESS				0x13
+#define ARMV8_PMUV3_PERFCTR_L1_ICACHE_ACCESS			0x14
+#define ARMV8_PMUV3_PERFCTR_L1_DCACHE_WB			0x15
+#define ARMV8_PMUV3_PERFCTR_L2_CACHE_ACCESS			0x16
+#define ARMV8_PMUV3_PERFCTR_L2_CACHE_REFILL			0x17
+#define ARMV8_PMUV3_PERFCTR_L2_CACHE_WB				0x18
+#define ARMV8_PMUV3_PERFCTR_BUS_ACCESS				0x19
+#define ARMV8_PMUV3_PERFCTR_MEM_ERROR				0x1A
+#define ARMV8_PMUV3_PERFCTR_BUS_CYCLES				0x1D
 
 /* ARMv8 Cortex-A53 specific event types. */
-enum armv8_a53_pmu_perf_types {
-	ARMV8_A53_PERFCTR_PREFETCH_LINEFILL			= 0xC2,
-};
+#define ARMV8_A53_PERFCTR_PREFETCH_LINEFILL			0xC2
 
 /* ARMv8 Cortex-A57 specific event types. */
-enum armv8_a57_perf_types {
-	ARMV8_A57_PERFCTR_L1_DCACHE_ACCESS_LD			= 0x40,
-	ARMV8_A57_PERFCTR_L1_DCACHE_ACCESS_ST			= 0x41,
-	ARMV8_A57_PERFCTR_L1_DCACHE_REFILL_LD			= 0x42,
-	ARMV8_A57_PERFCTR_L1_DCACHE_REFILL_ST			= 0x43,
-	ARMV8_A57_PERFCTR_DTLB_REFILL_LD			= 0x4c,
-	ARMV8_A57_PERFCTR_DTLB_REFILL_ST			= 0x4d,
-};
+#define ARMV8_A57_PERFCTR_L1_DCACHE_ACCESS_LD			0x40
+#define ARMV8_A57_PERFCTR_L1_DCACHE_ACCESS_ST			0x41
+#define ARMV8_A57_PERFCTR_L1_DCACHE_REFILL_LD			0x42
+#define ARMV8_A57_PERFCTR_L1_DCACHE_REFILL_ST			0x43
+#define ARMV8_A57_PERFCTR_DTLB_REFILL_LD			0x4c
+#define ARMV8_A57_PERFCTR_DTLB_REFILL_ST			0x4d
 
 /* PMUv3 HW events mapping. */
 static const unsigned armv8_pmuv3_perf_map[PERF_COUNT_HW_MAX] = {
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH 2/2] arm64: perf: Add event descriptions
  2015-10-22 14:05   ` [PATCHv2] " Drew Richardson
  2015-10-22 14:07     ` [PATCH 1/2] arm64: perf: Convert event enums to #defines Drew Richardson
@ 2015-10-22 14:07     ` Drew Richardson
  2015-10-27 17:32     ` [PATCHv2] arm: " Will Deacon
  2 siblings, 0 replies; 23+ messages in thread
From: Drew Richardson @ 2015-10-22 14:07 UTC (permalink / raw)
  To: linux-arm-kernel

Add additional information about the ARM architected hardware events
to make counters self describing. This makes the hardware PMUs easier
to use as perf list contains possible events instead of users having
to refer to documentation like the ARM TRMs.

Signed-off-by: Drew Richardson <drew.richardson@arm.com>
---
 arch/arm64/kernel/perf_event.c | 138 +++++++++++++++++++++++++++++++++++++++++
 1 file changed, 138 insertions(+)

diff --git a/arch/arm64/kernel/perf_event.c b/arch/arm64/kernel/perf_event.c
index 7e4372ee4dfb..d880e9cf058b 100644
--- a/arch/arm64/kernel/perf_event.c
+++ b/arch/arm64/kernel/perf_event.c
@@ -53,6 +53,8 @@
 #define ARMV8_PMUV3_PERFCTR_PC_PROC_RETURN			0x0E
 #define ARMV8_PMUV3_PERFCTR_MEM_UNALIGNED_ACCESS		0x0F
 #define ARMV8_PMUV3_PERFCTR_TTBR_WRITE				0x1C
+#define ARMV8_PMUV3_PERFCTR_CHAIN				0x1E
+#define ARMV8_PMUV3_PERFCTR_BR_RETIRED				0x21
 
 /* Common microarchitectural events. */
 #define ARMV8_PMUV3_PERFCTR_L1_ICACHE_REFILL			0x01
@@ -67,6 +69,23 @@
 #define ARMV8_PMUV3_PERFCTR_BUS_ACCESS				0x19
 #define ARMV8_PMUV3_PERFCTR_MEM_ERROR				0x1A
 #define ARMV8_PMUV3_PERFCTR_BUS_CYCLES				0x1D
+#define ARMV8_PMUV3_PERFCTR_L1D_CACHE_ALLOCATE			0x1F
+#define ARMV8_PMUV3_PERFCTR_L2D_CACHE_ALLOCATE			0x20
+#define ARMV8_PMUV3_PERFCTR_BR_MIS_PRED_RETIRED			0x22
+#define ARMV8_PMUV3_PERFCTR_STALL_FRONTEND			0x23
+#define ARMV8_PMUV3_PERFCTR_STALL_BACKEND			0x24
+#define ARMV8_PMUV3_PERFCTR_L1D_TLB				0x25
+#define ARMV8_PMUV3_PERFCTR_L1I_TLB				0x26
+#define ARMV8_PMUV3_PERFCTR_L2I_CACHE				0x27
+#define ARMV8_PMUV3_PERFCTR_L2I_CACHE_REFILL			0x28
+#define ARMV8_PMUV3_PERFCTR_L3D_CACHE_ALLOCATE			0x29
+#define ARMV8_PMUV3_PERFCTR_L3D_CACHE_REFILL			0x2A
+#define ARMV8_PMUV3_PERFCTR_L3D_CACHE				0x2B
+#define ARMV8_PMUV3_PERFCTR_L3D_CACHE_WB			0x2C
+#define ARMV8_PMUV3_PERFCTR_L2D_TLB_REFILL			0x2D
+#define ARMV8_PMUV3_PERFCTR_L21_TLB_REFILL			0x2E
+#define ARMV8_PMUV3_PERFCTR_L2D_TLB				0x2F
+#define ARMV8_PMUV3_PERFCTR_L21_TLB				0x30
 
 /* ARMv8 Cortex-A53 specific event types. */
 #define ARMV8_A53_PERFCTR_PREFETCH_LINEFILL			0xC2
@@ -173,6 +192,123 @@ static const unsigned armv8_a57_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
 	[C(BPU)][C(OP_WRITE)][C(RESULT_MISS)]	= ARMV8_PMUV3_PERFCTR_PC_BRANCH_MIS_PRED,
 };
 
+#define ARMV8_EVENT_ATTR_RESOLVE(m) #m
+#define ARMV8_EVENT_ATTR(name, config) \
+	PMU_EVENT_ATTR_STRING(name, armv8_event_attr_##name, \
+			      "event=" ARMV8_EVENT_ATTR_RESOLVE(config))
+
+ARMV8_EVENT_ATTR(sw_incr, ARMV8_PMUV3_PERFCTR_PMNC_SW_INCR);
+ARMV8_EVENT_ATTR(l1i_cache_refill, ARMV8_PMUV3_PERFCTR_L1_ICACHE_REFILL);
+ARMV8_EVENT_ATTR(l1i_tlb_refill, ARMV8_PMUV3_PERFCTR_ITLB_REFILL);
+ARMV8_EVENT_ATTR(l1d_cache_refill, ARMV8_PMUV3_PERFCTR_L1_DCACHE_REFILL);
+ARMV8_EVENT_ATTR(l1d_cache, ARMV8_PMUV3_PERFCTR_L1_DCACHE_ACCESS);
+ARMV8_EVENT_ATTR(l1d_tlb_refill, ARMV8_PMUV3_PERFCTR_DTLB_REFILL);
+ARMV8_EVENT_ATTR(ld_retired, ARMV8_PMUV3_PERFCTR_MEM_READ);
+ARMV8_EVENT_ATTR(st_retired, ARMV8_PMUV3_PERFCTR_MEM_WRITE);
+ARMV8_EVENT_ATTR(inst_retired, ARMV8_PMUV3_PERFCTR_INSTR_EXECUTED);
+ARMV8_EVENT_ATTR(exc_taken, ARMV8_PMUV3_PERFCTR_EXC_TAKEN);
+ARMV8_EVENT_ATTR(exc_return, ARMV8_PMUV3_PERFCTR_EXC_EXECUTED);
+ARMV8_EVENT_ATTR(cid_write_retired, ARMV8_PMUV3_PERFCTR_CID_WRITE);
+ARMV8_EVENT_ATTR(pc_write_retired, ARMV8_PMUV3_PERFCTR_PC_WRITE);
+ARMV8_EVENT_ATTR(br_immed_retired, ARMV8_PMUV3_PERFCTR_PC_IMM_BRANCH);
+ARMV8_EVENT_ATTR(br_return_retired, ARMV8_PMUV3_PERFCTR_PC_PROC_RETURN);
+ARMV8_EVENT_ATTR(unaligned_ldst_retired, ARMV8_PMUV3_PERFCTR_MEM_UNALIGNED_ACCESS);
+ARMV8_EVENT_ATTR(br_mis_pred, ARMV8_PMUV3_PERFCTR_PC_BRANCH_MIS_PRED);
+ARMV8_EVENT_ATTR(cpu_cycles, ARMV8_PMUV3_PERFCTR_CLOCK_CYCLES);
+ARMV8_EVENT_ATTR(br_pred, ARMV8_PMUV3_PERFCTR_PC_BRANCH_PRED);
+ARMV8_EVENT_ATTR(mem_access, ARMV8_PMUV3_PERFCTR_MEM_ACCESS);
+ARMV8_EVENT_ATTR(l1i_cache, ARMV8_PMUV3_PERFCTR_L1_ICACHE_ACCESS);
+ARMV8_EVENT_ATTR(l1d_cache_wb, ARMV8_PMUV3_PERFCTR_L1_DCACHE_WB);
+ARMV8_EVENT_ATTR(l2d_cache, ARMV8_PMUV3_PERFCTR_L2_CACHE_ACCESS);
+ARMV8_EVENT_ATTR(l2d_cache_refill, ARMV8_PMUV3_PERFCTR_L2_CACHE_REFILL);
+ARMV8_EVENT_ATTR(l2d_cache_wb, ARMV8_PMUV3_PERFCTR_L2_CACHE_WB);
+ARMV8_EVENT_ATTR(bus_access, ARMV8_PMUV3_PERFCTR_BUS_ACCESS);
+ARMV8_EVENT_ATTR(memory_error, ARMV8_PMUV3_PERFCTR_MEM_ERROR);
+ARMV8_EVENT_ATTR(inst_spec, ARMV8_PMUV3_PERFCTR_OP_SPEC);
+ARMV8_EVENT_ATTR(ttbr_write_retired, ARMV8_PMUV3_PERFCTR_TTBR_WRITE);
+ARMV8_EVENT_ATTR(bus_cycles, ARMV8_PMUV3_PERFCTR_BUS_CYCLES);
+ARMV8_EVENT_ATTR(chain, ARMV8_PMUV3_PERFCTR_CHAIN);
+ARMV8_EVENT_ATTR(l1d_cache_allocate, ARMV8_PMUV3_PERFCTR_L1D_CACHE_ALLOCATE);
+ARMV8_EVENT_ATTR(l2d_cache_allocate, ARMV8_PMUV3_PERFCTR_L2D_CACHE_ALLOCATE);
+ARMV8_EVENT_ATTR(br_retired, ARMV8_PMUV3_PERFCTR_BR_RETIRED);
+ARMV8_EVENT_ATTR(br_mis_pred_retired, ARMV8_PMUV3_PERFCTR_BR_MIS_PRED_RETIRED);
+ARMV8_EVENT_ATTR(stall_frontend, ARMV8_PMUV3_PERFCTR_STALL_FRONTEND);
+ARMV8_EVENT_ATTR(stall_backend, ARMV8_PMUV3_PERFCTR_STALL_BACKEND);
+ARMV8_EVENT_ATTR(l1d_tlb, ARMV8_PMUV3_PERFCTR_L1D_TLB);
+ARMV8_EVENT_ATTR(l1i_tlb, ARMV8_PMUV3_PERFCTR_L1I_TLB);
+ARMV8_EVENT_ATTR(l2i_cache, ARMV8_PMUV3_PERFCTR_L2I_CACHE);
+ARMV8_EVENT_ATTR(l2i_cache_refill, ARMV8_PMUV3_PERFCTR_L2I_CACHE_REFILL);
+ARMV8_EVENT_ATTR(l3d_cache_allocate, ARMV8_PMUV3_PERFCTR_L3D_CACHE_ALLOCATE);
+ARMV8_EVENT_ATTR(l3d_cache_refill, ARMV8_PMUV3_PERFCTR_L3D_CACHE_REFILL);
+ARMV8_EVENT_ATTR(l3d_cache, ARMV8_PMUV3_PERFCTR_L3D_CACHE);
+ARMV8_EVENT_ATTR(l3d_cache_wb, ARMV8_PMUV3_PERFCTR_L3D_CACHE_WB);
+ARMV8_EVENT_ATTR(l2d_tlb_refill, ARMV8_PMUV3_PERFCTR_L2D_TLB_REFILL);
+ARMV8_EVENT_ATTR(l21_tlb_refill, ARMV8_PMUV3_PERFCTR_L21_TLB_REFILL);
+ARMV8_EVENT_ATTR(l2d_tlb, ARMV8_PMUV3_PERFCTR_L2D_TLB);
+ARMV8_EVENT_ATTR(l21_tlb, ARMV8_PMUV3_PERFCTR_L21_TLB);
+
+static struct attribute *armv8_pmuv3_event_attrs[] = {
+	&armv8_event_attr_sw_incr.attr.attr,
+	&armv8_event_attr_l1i_cache_refill.attr.attr,
+	&armv8_event_attr_l1i_tlb_refill.attr.attr,
+	&armv8_event_attr_l1d_cache_refill.attr.attr,
+	&armv8_event_attr_l1d_cache.attr.attr,
+	&armv8_event_attr_l1d_tlb_refill.attr.attr,
+	&armv8_event_attr_ld_retired.attr.attr,
+	&armv8_event_attr_st_retired.attr.attr,
+	&armv8_event_attr_inst_retired.attr.attr,
+	&armv8_event_attr_exc_taken.attr.attr,
+	&armv8_event_attr_exc_return.attr.attr,
+	&armv8_event_attr_cid_write_retired.attr.attr,
+	&armv8_event_attr_pc_write_retired.attr.attr,
+	&armv8_event_attr_br_immed_retired.attr.attr,
+	&armv8_event_attr_br_return_retired.attr.attr,
+	&armv8_event_attr_unaligned_ldst_retired.attr.attr,
+	&armv8_event_attr_br_mis_pred.attr.attr,
+	&armv8_event_attr_cpu_cycles.attr.attr,
+	&armv8_event_attr_br_pred.attr.attr,
+	&armv8_event_attr_mem_access.attr.attr,
+	&armv8_event_attr_l1i_cache.attr.attr,
+	&armv8_event_attr_l1d_cache_wb.attr.attr,
+	&armv8_event_attr_l2d_cache.attr.attr,
+	&armv8_event_attr_l2d_cache_refill.attr.attr,
+	&armv8_event_attr_l2d_cache_wb.attr.attr,
+	&armv8_event_attr_bus_access.attr.attr,
+	&armv8_event_attr_memory_error.attr.attr,
+	&armv8_event_attr_inst_spec.attr.attr,
+	&armv8_event_attr_ttbr_write_retired.attr.attr,
+	&armv8_event_attr_bus_cycles.attr.attr,
+	&armv8_event_attr_chain.attr.attr,
+	&armv8_event_attr_l1d_cache_allocate.attr.attr,
+	&armv8_event_attr_l2d_cache_allocate.attr.attr,
+	&armv8_event_attr_br_retired.attr.attr,
+	&armv8_event_attr_br_mis_pred_retired.attr.attr,
+	&armv8_event_attr_stall_frontend.attr.attr,
+	&armv8_event_attr_stall_backend.attr.attr,
+	&armv8_event_attr_l1d_tlb.attr.attr,
+	&armv8_event_attr_l1i_tlb.attr.attr,
+	&armv8_event_attr_l2i_cache.attr.attr,
+	&armv8_event_attr_l2i_cache_refill.attr.attr,
+	&armv8_event_attr_l3d_cache_allocate.attr.attr,
+	&armv8_event_attr_l3d_cache_refill.attr.attr,
+	&armv8_event_attr_l3d_cache.attr.attr,
+	&armv8_event_attr_l3d_cache_wb.attr.attr,
+	&armv8_event_attr_l2d_tlb_refill.attr.attr,
+	&armv8_event_attr_l21_tlb_refill.attr.attr,
+	&armv8_event_attr_l2d_tlb.attr.attr,
+	&armv8_event_attr_l21_tlb.attr.attr,
+	NULL
+};
+
+static struct attribute_group armv8_pmuv3_events_attr_group = {
+	.name = "events",
+	.attrs = armv8_pmuv3_event_attrs,
+};
+
+static const struct attribute_group *armv8_pmuv3_attr_groups[] = {
+	&armv8_pmuv3_events_attr_group,
+	NULL
+};
 
 /*
  * Perf Events' indices
@@ -641,6 +777,7 @@ static int armv8_a53_pmu_init(struct arm_pmu *cpu_pmu)
 	armv8_pmu_init(cpu_pmu);
 	cpu_pmu->name			= "armv8_cortex_a53";
 	cpu_pmu->map_event		= armv8_a53_map_event;
+	cpu_pmu->pmu.attr_groups	= armv8_pmuv3_attr_groups;
 	return armv8pmu_probe_num_events(cpu_pmu);
 }
 
@@ -649,6 +786,7 @@ static int armv8_a57_pmu_init(struct arm_pmu *cpu_pmu)
 	armv8_pmu_init(cpu_pmu);
 	cpu_pmu->name			= "armv8_cortex_a57";
 	cpu_pmu->map_event		= armv8_a57_map_event;
+	cpu_pmu->pmu.attr_groups	= armv8_pmuv3_attr_groups;
 	return armv8pmu_probe_num_events(cpu_pmu);
 }
 
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCHv2] arm: perf: Add event descriptions
  2015-10-22 14:05   ` [PATCHv2] " Drew Richardson
  2015-10-22 14:07     ` [PATCH 1/2] arm64: perf: Convert event enums to #defines Drew Richardson
  2015-10-22 14:07     ` [PATCH 2/2] arm64: perf: Add event descriptions Drew Richardson
@ 2015-10-27 17:32     ` Will Deacon
  2015-10-28 12:33       ` Mark Rutland
  2 siblings, 1 reply; 23+ messages in thread
From: Will Deacon @ 2015-10-27 17:32 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Oct 22, 2015 at 07:05:58AM -0700, Drew Richardson wrote:
> On Fri, Oct 09, 2015 at 03:13:38AM -0700, Will Deacon wrote:
> > Also, would you be able to do something similar for AArch64 too, please?
> > (take a look at our for-next/core branch for the latest perf changes).
> 
> Here are some almost identical patches for AArch64 based on arm64
> tree's for-next/core branch. Please note that this is dependent on
> some change to drivers/perf/arm_pmu.c so that pmu.attr_groups is
> preserved.

Has a revised version of that prerequisite patch been posted anywhere? I
can't seem to find it in my inbox...

Will

^ permalink raw reply	[flat|nested] 23+ messages in thread

* [PATCHv2] arm: perf: Add event descriptions
  2015-10-27 17:32     ` [PATCHv2] arm: " Will Deacon
@ 2015-10-28 12:33       ` Mark Rutland
  0 siblings, 0 replies; 23+ messages in thread
From: Mark Rutland @ 2015-10-28 12:33 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Oct 27, 2015 at 05:32:38PM +0000, Will Deacon wrote:
> On Thu, Oct 22, 2015 at 07:05:58AM -0700, Drew Richardson wrote:
> > On Fri, Oct 09, 2015 at 03:13:38AM -0700, Will Deacon wrote:
> > > Also, would you be able to do something similar for AArch64 too, please?
> > > (take a look at our for-next/core branch for the latest perf changes).
> > 
> > Here are some almost identical patches for AArch64 based on arm64
> > tree's for-next/core branch. Please note that this is dependent on
> > some change to drivers/perf/arm_pmu.c so that pmu.attr_groups is
> > preserved.
> 
> Has a revised version of that prerequisite patch been posted anywhere? I
> can't seem to find it in my inbox...

I've just posted it [1], having had the chance to test it.

Mark.

[1] http://lists.infradead.org/pipermail/linux-arm-kernel/2015-October/381480.html

^ permalink raw reply	[flat|nested] 23+ messages in thread

end of thread, other threads:[~2015-10-28 12:33 UTC | newest]

Thread overview: 23+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-10-07 18:28 [PATCHv2] arm: perf: Add event descriptions Drew Richardson
2015-10-09 10:13 ` Will Deacon
2015-10-09 16:53   ` Drew Richardson
2015-10-12 14:30     ` Will Deacon
2015-10-12 18:10       ` Drew Richardson
2015-10-13 14:15         ` Will Deacon
2015-10-13 15:34         ` [PATCH v5 0/2] " Drew Richardson
2015-10-13 15:35         ` [PATCH v5 1/2] arm: perf: Convert event enums to #defines Drew Richardson
2015-10-13 15:36         ` [PATCH v5 2/2] arm: perf: Add event descriptions Drew Richardson
2015-10-15 13:21           ` Will Deacon
2015-10-15 15:15             ` Drew Richardson
2015-10-15 15:20               ` Pawel Moll
2015-10-15 15:42                 ` Mark Rutland
2015-10-15 15:49                   ` Pawel Moll
2015-10-15 15:29               ` Will Deacon
2015-10-15 15:41                 ` Mark Rutland
2015-10-15 16:31                   ` Drew Richardson
2015-10-15 16:44                     ` Mark Rutland
2015-10-22 14:05   ` [PATCHv2] " Drew Richardson
2015-10-22 14:07     ` [PATCH 1/2] arm64: perf: Convert event enums to #defines Drew Richardson
2015-10-22 14:07     ` [PATCH 2/2] arm64: perf: Add event descriptions Drew Richardson
2015-10-27 17:32     ` [PATCHv2] arm: " Will Deacon
2015-10-28 12:33       ` Mark Rutland

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).