diff mbox series

arm64: perf: Simplify the ARMv8 PMUv3 event attributes

Message ID 1572407177-48229-1-git-send-email-zhangshaokun@hisilicon.com (mailing list archive)
State New, archived
Headers show
Series arm64: perf: Simplify the ARMv8 PMUv3 event attributes | expand

Commit Message

Shaokun Zhang Oct. 30, 2019, 3:46 a.m. UTC
For each PMU event, there is a ARMV8_EVENT_ATTR(xx, XX) and
&armv8_event_attr_xx.attr.attr. Let's redefine the ARMV8_EVENT_ATTR
to simplify the armv8_pmuv3_event_attrs.

Cc: Will Deacon <will@kernel.org>
Cc: Mark Rutland <mark.rutland@arm.com>
Signed-off-by: Shaokun Zhang <zhangshaokun@hisilicon.com>
---
 arch/arm64/kernel/perf_event.c | 189 ++++++++++++++---------------------------
 1 file changed, 65 insertions(+), 124 deletions(-)

Comments

Richard Henderson Oct. 30, 2019, 1:34 p.m. UTC | #1
On 10/30/19 4:46 AM, Shaokun Zhang wrote:
> For each PMU event, there is a ARMV8_EVENT_ATTR(xx, XX) and
> &armv8_event_attr_xx.attr.attr. Let's redefine the ARMV8_EVENT_ATTR
> to simplify the armv8_pmuv3_event_attrs.
...
>  #define ARMV8_EVENT_ATTR(name, config) \
> +	(&((struct perf_pmu_events_attr[]) { \
> +		{ .attr = __ATTR(name, 0444, armv8pmu_events_sysfs_show, NULL), \
> +		  .id = config, } \
> +	})[0].attr.attr)
>  
>  static struct attribute *armv8_pmuv3_event_attrs[] = {
> +	ARMV8_EVENT_ATTR(sw_incr, ARMV8_PMUV3_PERFCTR_SW_INCR),

You do realize this creates complete perf_pmu_events_attr structures, most of
which is unused and unreachable, right?

Also, why not take the opportunity to assert that the armv8_pmuv3_event_attrs
array cannot get out of sync with the ARMV8_PMUV3_* defines?

Slightly better would seem to be

#define ARMV8_EVENT_ATTR(name, config) \
	[config] = &((struct device_attribute) \
		__ATTR(name, 0444, armv8pmu_events_sysfs_show, NULL)).attr

though I'm not sure why __ATTR is particularly desired above

#define ARMV8_EVENT_ATTR(name, config)      \
	[config] = &(struct attribute){     \
		.name = __stringify(name),  \
		.mode = 0444,               \
	}


r~
Mark Rutland Oct. 31, 2019, 7:55 a.m. UTC | #2
On Wed, Oct 30, 2019 at 02:34:37PM +0100, Richard Henderson wrote:
> On 10/30/19 4:46 AM, Shaokun Zhang wrote:
> > For each PMU event, there is a ARMV8_EVENT_ATTR(xx, XX) and
> > &armv8_event_attr_xx.attr.attr. Let's redefine the ARMV8_EVENT_ATTR
> > to simplify the armv8_pmuv3_event_attrs.
> ...
> >  #define ARMV8_EVENT_ATTR(name, config) \
> > +	(&((struct perf_pmu_events_attr[]) { \
> > +		{ .attr = __ATTR(name, 0444, armv8pmu_events_sysfs_show, NULL), \
> > +		  .id = config, } \
> > +	})[0].attr.attr)
> >  
> >  static struct attribute *armv8_pmuv3_event_attrs[] = {
> > +	ARMV8_EVENT_ATTR(sw_incr, ARMV8_PMUV3_PERFCTR_SW_INCR),
> 
> You do realize this creates complete perf_pmu_events_attr structures, most of
> which is unused and unreachable, right?

In armv8pmu_events_sysfs_show() we use container_of() to access the
perf_pmu_events_attr, and extracts the id field:

| static ssize_t
| armv8pmu_events_sysfs_show(struct device *dev,
|                            struct device_attribute *attr, char *page)
| {
|         struct perf_pmu_events_attr *pmu_attr;
| 
|         pmu_attr = container_of(attr, struct perf_pmu_events_attr, attr);
| 
|         return sprintf(page, "event=0x%03llx\n", pmu_attr->id);
| }

> Also, why not take the opportunity to assert that the armv8_pmuv3_event_attrs
> array cannot get out of sync with the ARMV8_PMUV3_* defines?
> 
> Slightly better would seem to be
> 
> #define ARMV8_EVENT_ATTR(name, config) \
> 	[config] = &((struct device_attribute) \
> 		__ATTR(name, 0444, armv8pmu_events_sysfs_show, NULL)).attr

I'm not sure I follow. This is not equivalent, and you're using the config
field in a very different way -- that's not an index in the parent array in the
current code. How do you expect armv8pmu_events_sysfs_show to get the config
value in this case?

> 
> though I'm not sure why __ATTR is particularly desired above
> 
> #define ARMV8_EVENT_ATTR(name, config)      \
> 	[config] = &(struct attribute){     \
> 		.name = __stringify(name),  \
> 		.mode = 0444,               \
> 	}

Using __ATTR is consistent with other drivers, so I don't see a reason to
change that unless there's a significant simplification, or a functional
improvement

Thanks,
Mark.
Shaokun Zhang Oct. 31, 2019, 8:45 a.m. UTC | #3
Hi Richard,

Thanks your comments and Mark has helped to reply some.

On 2019/10/30 21:34, Richard Henderson wrote:
> On 10/30/19 4:46 AM, Shaokun Zhang wrote:
>> For each PMU event, there is a ARMV8_EVENT_ATTR(xx, XX) and
>> &armv8_event_attr_xx.attr.attr. Let's redefine the ARMV8_EVENT_ATTR
>> to simplify the armv8_pmuv3_event_attrs.
> ...
>>  #define ARMV8_EVENT_ATTR(name, config) \
>> +	(&((struct perf_pmu_events_attr[]) { \
>> +		{ .attr = __ATTR(name, 0444, armv8pmu_events_sysfs_show, NULL), \
>> +		  .id = config, } \
>> +	})[0].attr.attr)
>>  
>>  static struct attribute *armv8_pmuv3_event_attrs[] = {
>> +	ARMV8_EVENT_ATTR(sw_incr, ARMV8_PMUV3_PERFCTR_SW_INCR),
> 
> You do realize this creates complete perf_pmu_events_attr structures, most of
> which is unused and unreachable, right?
> 
> Also, why not take the opportunity to assert that the armv8_pmuv3_event_attrs
> array cannot get out of sync with the ARMV8_PMUV3_* defines?
> 

For my initial purpose: remove the &armv8_event_attr_xx.attr.attr and only
maintain the armv8_pmuv3_event_attrs array directly when we want to add one new
PMU event. For example:
#define ARMV8_PMUV3_PERFCTR_OP_RETIRED 		0x3A
.....
static struct attribute *armv8_pmuv3_event_attrs[] = {
	......
	ARMV8_EVENT_ATTR(op_retired, ARMV8_PMUV3_PERFCTR_OP_RETIRED),
	NULL,
};

Thanks,
Shaokun

> Slightly better would seem to be
> 
> #define ARMV8_EVENT_ATTR(name, config) \
> 	[config] = &((struct device_attribute) \
> 		__ATTR(name, 0444, armv8pmu_events_sysfs_show, NULL)).attr
> 
> though I'm not sure why __ATTR is particularly desired above
> 
> #define ARMV8_EVENT_ATTR(name, config)      \
> 	[config] = &(struct attribute){     \
> 		.name = __stringify(name),  \
> 		.mode = 0444,               \
> 	}
> 
> 
> r~
> 
>
Will Deacon Oct. 31, 2019, 4:08 p.m. UTC | #4
On Wed, Oct 30, 2019 at 11:46:17AM +0800, Shaokun Zhang wrote:
> For each PMU event, there is a ARMV8_EVENT_ATTR(xx, XX) and
> &armv8_event_attr_xx.attr.attr. Let's redefine the ARMV8_EVENT_ATTR
> to simplify the armv8_pmuv3_event_attrs.
> 
> Cc: Will Deacon <will@kernel.org>
> Cc: Mark Rutland <mark.rutland@arm.com>
> Signed-off-by: Shaokun Zhang <zhangshaokun@hisilicon.com>
> ---
>  arch/arm64/kernel/perf_event.c | 189 ++++++++++++++---------------------------
>  1 file changed, 65 insertions(+), 124 deletions(-)
> 
> diff --git a/arch/arm64/kernel/perf_event.c b/arch/arm64/kernel/perf_event.c
> index a0b4f1bca491..d0f084939bcf 100644
> --- a/arch/arm64/kernel/perf_event.c
> +++ b/arch/arm64/kernel/perf_event.c
> @@ -159,132 +159,73 @@ armv8pmu_events_sysfs_show(struct device *dev,
>  }

[...]

> +	(&((struct perf_pmu_events_attr[]) { \
> +		{ .attr = __ATTR(name, 0444, armv8pmu_events_sysfs_show, NULL), \
> +		  .id = config, } \
> +	})[0].attr.attr)

I don't get the need for the array here. Why can't you do:

	(&((struct perf_pmu_events_attr) {
		.attr = ...,
		.id = ...,
	}).attr.attr)

?

Will
Shaokun Zhang Nov. 1, 2019, 3:45 a.m. UTC | #5
Hi Will,

On 2019/11/1 0:08, Will Deacon wrote:
> On Wed, Oct 30, 2019 at 11:46:17AM +0800, Shaokun Zhang wrote:
>> For each PMU event, there is a ARMV8_EVENT_ATTR(xx, XX) and
>> &armv8_event_attr_xx.attr.attr. Let's redefine the ARMV8_EVENT_ATTR
>> to simplify the armv8_pmuv3_event_attrs.
>>
>> Cc: Will Deacon <will@kernel.org>
>> Cc: Mark Rutland <mark.rutland@arm.com>
>> Signed-off-by: Shaokun Zhang <zhangshaokun@hisilicon.com>
>> ---
>>  arch/arm64/kernel/perf_event.c | 189 ++++++++++++++---------------------------
>>  1 file changed, 65 insertions(+), 124 deletions(-)
>>
>> diff --git a/arch/arm64/kernel/perf_event.c b/arch/arm64/kernel/perf_event.c
>> index a0b4f1bca491..d0f084939bcf 100644
>> --- a/arch/arm64/kernel/perf_event.c
>> +++ b/arch/arm64/kernel/perf_event.c
>> @@ -159,132 +159,73 @@ armv8pmu_events_sysfs_show(struct device *dev,
>>  }
> 
> [...]
> 
>> +	(&((struct perf_pmu_events_attr[]) { \
>> +		{ .attr = __ATTR(name, 0444, armv8pmu_events_sysfs_show, NULL), \
>> +		  .id = config, } \
>> +	})[0].attr.attr)
> 
> I don't get the need for the array here. Why can't you do:
> 
> 	(&((struct perf_pmu_events_attr) {
> 		.attr = ...,
> 		.id = ...,
> 	}).attr.attr)
> 
> ?

I try it and there is a compiler error:

zhangshaokun@ubuntu:~/linux$ make Image -j64
  CALL    scripts/atomic/check-atomics.sh
  CALL    scripts/checksyscalls.sh
  CHK     include/generated/compile.h
  CC      arch/arm64/kernel/perf_event.o
arch/arm64/kernel/perf_event.c:162:13: error: unknown field ‘attr’ specified in initializer
  (&((struct perf_pmu_events_attr) { \
             ^
arch/arm64/kernel/perf_event.c:168:2: note: in expansion of macro ‘ARMV8_EVENT_ATTR’
  ARMV8_EVENT_ATTR(sw_incr, ARMV8_PMUV3_PERFCTR_SW_INCR),
  ^
arch/arm64/kernel/perf_event.c:162:13: warning: braces around scalar initializer
  (&((struct perf_pmu_events_attr) { \
             ^
arch/arm64/kernel/perf_event.c:168:2: note: in expansion of macro ‘ARMV8_EVENT_ATTR’
  ARMV8_EVENT_ATTR(sw_incr, ARMV8_PMUV3_PERFCTR_SW_INCR),

It seems that it became completely anonymous and the compiler can't find its member.

Thanks,
Shaokun

> 
> Will
> 
> .
>
Mark Rutland Nov. 1, 2019, 8:53 a.m. UTC | #6
On Thu, Oct 31, 2019 at 04:08:04PM +0000, Will Deacon wrote:
> On Wed, Oct 30, 2019 at 11:46:17AM +0800, Shaokun Zhang wrote:
> > For each PMU event, there is a ARMV8_EVENT_ATTR(xx, XX) and
> > &armv8_event_attr_xx.attr.attr. Let's redefine the ARMV8_EVENT_ATTR
> > to simplify the armv8_pmuv3_event_attrs.
> > 
> > Cc: Will Deacon <will@kernel.org>
> > Cc: Mark Rutland <mark.rutland@arm.com>
> > Signed-off-by: Shaokun Zhang <zhangshaokun@hisilicon.com>
> > ---
> >  arch/arm64/kernel/perf_event.c | 189 ++++++++++++++---------------------------
> >  1 file changed, 65 insertions(+), 124 deletions(-)
> > 
> > diff --git a/arch/arm64/kernel/perf_event.c b/arch/arm64/kernel/perf_event.c
> > index a0b4f1bca491..d0f084939bcf 100644
> > --- a/arch/arm64/kernel/perf_event.c
> > +++ b/arch/arm64/kernel/perf_event.c
> > @@ -159,132 +159,73 @@ armv8pmu_events_sysfs_show(struct device *dev,
> >  }
> 
> [...]
> 
> > +	(&((struct perf_pmu_events_attr[]) { \
> > +		{ .attr = __ATTR(name, 0444, armv8pmu_events_sysfs_show, NULL), \
> > +		  .id = config, } \
> > +	})[0].attr.attr)
> 
> I don't get the need for the array here. Why can't you do:
> 
> 	(&((struct perf_pmu_events_attr) {
> 		.attr = ...,
> 		.id = ...,
> 	}).attr.attr)

You need want &(obj.attr.attr) rather than &(obj).attr.attr, i.e.

#define ARMV8_EVENT_ATTR(name, config) \
	(&((struct perf_pmu_events_attr) { \
		.attr = __ATTR(name, 0444, armv8pmu_events_sysfs_show, NULL), \
		.id = config, \
	}.attr.attr))
 
... which compiles for me.

It'd be worth checking that yields a working data structure at runtime.

I'm not sure why I did the array hack in the other PMU drivers -- looks like we
can simplify those assuming this works. :)

THanks,
Mark.
Will Deacon Nov. 1, 2019, 10:36 a.m. UTC | #7
On Fri, Nov 01, 2019 at 08:53:19AM +0000, Mark Rutland wrote:
> On Thu, Oct 31, 2019 at 04:08:04PM +0000, Will Deacon wrote:
> > On Wed, Oct 30, 2019 at 11:46:17AM +0800, Shaokun Zhang wrote:
> > > For each PMU event, there is a ARMV8_EVENT_ATTR(xx, XX) and
> > > &armv8_event_attr_xx.attr.attr. Let's redefine the ARMV8_EVENT_ATTR
> > > to simplify the armv8_pmuv3_event_attrs.
> > > 
> > > Cc: Will Deacon <will@kernel.org>
> > > Cc: Mark Rutland <mark.rutland@arm.com>
> > > Signed-off-by: Shaokun Zhang <zhangshaokun@hisilicon.com>
> > > ---
> > >  arch/arm64/kernel/perf_event.c | 189 ++++++++++++++---------------------------
> > >  1 file changed, 65 insertions(+), 124 deletions(-)
> > > 
> > > diff --git a/arch/arm64/kernel/perf_event.c b/arch/arm64/kernel/perf_event.c
> > > index a0b4f1bca491..d0f084939bcf 100644
> > > --- a/arch/arm64/kernel/perf_event.c
> > > +++ b/arch/arm64/kernel/perf_event.c
> > > @@ -159,132 +159,73 @@ armv8pmu_events_sysfs_show(struct device *dev,
> > >  }
> > 
> > [...]
> > 
> > > +	(&((struct perf_pmu_events_attr[]) { \
> > > +		{ .attr = __ATTR(name, 0444, armv8pmu_events_sysfs_show, NULL), \
> > > +		  .id = config, } \
> > > +	})[0].attr.attr)
> > 
> > I don't get the need for the array here. Why can't you do:
> > 
> > 	(&((struct perf_pmu_events_attr) {
> > 		.attr = ...,
> > 		.id = ...,
> > 	}).attr.attr)
> 
> You need want &(obj.attr.attr) rather than &(obj).attr.attr, i.e.
> 
> #define ARMV8_EVENT_ATTR(name, config) \
> 	(&((struct perf_pmu_events_attr) { \
> 		.attr = __ATTR(name, 0444, armv8pmu_events_sysfs_show, NULL), \
> 		.id = config, \
> 	}.attr.attr))
>  
> ... which compiles for me.

Weird, the following compiles fine for me with both GCC and clang:

#define ARMV8_EVENT_ATTR(name, config)						\
	(&((struct perf_pmu_events_attr) {					\
		.attr = __ATTR(name, 0444, armv8pmu_events_sysfs_show, NULL),	\
		.id = config,							\
	}).attr.attr)

> It'd be worth checking that yields a working data structure at runtime.

...and perf list works as expected.

Will
Robin Murphy Nov. 1, 2019, 10:54 a.m. UTC | #8
On 2019-11-01 10:36 am, Will Deacon wrote:
> On Fri, Nov 01, 2019 at 08:53:19AM +0000, Mark Rutland wrote:
>> On Thu, Oct 31, 2019 at 04:08:04PM +0000, Will Deacon wrote:
>>> On Wed, Oct 30, 2019 at 11:46:17AM +0800, Shaokun Zhang wrote:
>>>> For each PMU event, there is a ARMV8_EVENT_ATTR(xx, XX) and
>>>> &armv8_event_attr_xx.attr.attr. Let's redefine the ARMV8_EVENT_ATTR
>>>> to simplify the armv8_pmuv3_event_attrs.
>>>>
>>>> Cc: Will Deacon <will@kernel.org>
>>>> Cc: Mark Rutland <mark.rutland@arm.com>
>>>> Signed-off-by: Shaokun Zhang <zhangshaokun@hisilicon.com>
>>>> ---
>>>>   arch/arm64/kernel/perf_event.c | 189 ++++++++++++++---------------------------
>>>>   1 file changed, 65 insertions(+), 124 deletions(-)
>>>>
>>>> diff --git a/arch/arm64/kernel/perf_event.c b/arch/arm64/kernel/perf_event.c
>>>> index a0b4f1bca491..d0f084939bcf 100644
>>>> --- a/arch/arm64/kernel/perf_event.c
>>>> +++ b/arch/arm64/kernel/perf_event.c
>>>> @@ -159,132 +159,73 @@ armv8pmu_events_sysfs_show(struct device *dev,
>>>>   }
>>>
>>> [...]
>>>
>>>> +	(&((struct perf_pmu_events_attr[]) { \
>>>> +		{ .attr = __ATTR(name, 0444, armv8pmu_events_sysfs_show, NULL), \
>>>> +		  .id = config, } \
>>>> +	})[0].attr.attr)
>>>
>>> I don't get the need for the array here. Why can't you do:
>>>
>>> 	(&((struct perf_pmu_events_attr) {
>>> 		.attr = ...,
>>> 		.id = ...,
>>> 	}).attr.attr)
>>
>> You need want &(obj.attr.attr) rather than &(obj).attr.attr, i.e.
>>
>> #define ARMV8_EVENT_ATTR(name, config) \
>> 	(&((struct perf_pmu_events_attr) { \
>> 		.attr = __ATTR(name, 0444, armv8pmu_events_sysfs_show, NULL), \
>> 		.id = config, \
>> 	}.attr.attr))
>>   
>> ... which compiles for me.
> 
> Weird, the following compiles fine for me with both GCC and clang:
> 
> #define ARMV8_EVENT_ATTR(name, config)						\
> 	(&((struct perf_pmu_events_attr) {					\
> 		.attr = __ATTR(name, 0444, armv8pmu_events_sysfs_show, NULL),	\
> 		.id = config,							\
> 	}).attr.attr)

You know that the expressions are equivalent because unary "&" has lower 
precedence than ".", right? ;)

Robin.

>> It'd be worth checking that yields a working data structure at runtime.
> 
> ...and perf list works as expected.
> 
> Will
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
>
Will Deacon Nov. 1, 2019, 10:55 a.m. UTC | #9
On Fri, Nov 01, 2019 at 10:54:21AM +0000, Robin Murphy wrote:
> On 2019-11-01 10:36 am, Will Deacon wrote:
> > On Fri, Nov 01, 2019 at 08:53:19AM +0000, Mark Rutland wrote:
> > > On Thu, Oct 31, 2019 at 04:08:04PM +0000, Will Deacon wrote:
> > > > On Wed, Oct 30, 2019 at 11:46:17AM +0800, Shaokun Zhang wrote:
> > > > > For each PMU event, there is a ARMV8_EVENT_ATTR(xx, XX) and
> > > > > &armv8_event_attr_xx.attr.attr. Let's redefine the ARMV8_EVENT_ATTR
> > > > > to simplify the armv8_pmuv3_event_attrs.
> > > > > 
> > > > > Cc: Will Deacon <will@kernel.org>
> > > > > Cc: Mark Rutland <mark.rutland@arm.com>
> > > > > Signed-off-by: Shaokun Zhang <zhangshaokun@hisilicon.com>
> > > > > ---
> > > > >   arch/arm64/kernel/perf_event.c | 189 ++++++++++++++---------------------------
> > > > >   1 file changed, 65 insertions(+), 124 deletions(-)
> > > > > 
> > > > > diff --git a/arch/arm64/kernel/perf_event.c b/arch/arm64/kernel/perf_event.c
> > > > > index a0b4f1bca491..d0f084939bcf 100644
> > > > > --- a/arch/arm64/kernel/perf_event.c
> > > > > +++ b/arch/arm64/kernel/perf_event.c
> > > > > @@ -159,132 +159,73 @@ armv8pmu_events_sysfs_show(struct device *dev,
> > > > >   }
> > > > 
> > > > [...]
> > > > 
> > > > > +	(&((struct perf_pmu_events_attr[]) { \
> > > > > +		{ .attr = __ATTR(name, 0444, armv8pmu_events_sysfs_show, NULL), \
> > > > > +		  .id = config, } \
> > > > > +	})[0].attr.attr)
> > > > 
> > > > I don't get the need for the array here. Why can't you do:
> > > > 
> > > > 	(&((struct perf_pmu_events_attr) {
> > > > 		.attr = ...,
> > > > 		.id = ...,
> > > > 	}).attr.attr)
> > > 
> > > You need want &(obj.attr.attr) rather than &(obj).attr.attr, i.e.
> > > 
> > > #define ARMV8_EVENT_ATTR(name, config) \
> > > 	(&((struct perf_pmu_events_attr) { \
> > > 		.attr = __ATTR(name, 0444, armv8pmu_events_sysfs_show, NULL), \
> > > 		.id = config, \
> > > 	}.attr.attr))
> > > ... which compiles for me.
> > 
> > Weird, the following compiles fine for me with both GCC and clang:
> > 
> > #define ARMV8_EVENT_ATTR(name, config)						\
> > 	(&((struct perf_pmu_events_attr) {					\
> > 		.attr = __ATTR(name, 0444, armv8pmu_events_sysfs_show, NULL),	\
> > 		.id = config,							\
> > 	}).attr.attr)
> 
> You know that the expressions are equivalent because unary "&" has lower
> precedence than ".", right? ;)

Right, which is why it's weird that Shaokun claims that the version I posted
doesn't compile. I assume it didn't build for Mark either, hence his extra
brackets.

Will
Robin Murphy Nov. 1, 2019, 11:11 a.m. UTC | #10
On 2019-11-01 10:55 am, Will Deacon wrote:
> On Fri, Nov 01, 2019 at 10:54:21AM +0000, Robin Murphy wrote:
>> On 2019-11-01 10:36 am, Will Deacon wrote:
>>> On Fri, Nov 01, 2019 at 08:53:19AM +0000, Mark Rutland wrote:
>>>> On Thu, Oct 31, 2019 at 04:08:04PM +0000, Will Deacon wrote:
>>>>> On Wed, Oct 30, 2019 at 11:46:17AM +0800, Shaokun Zhang wrote:
>>>>>> For each PMU event, there is a ARMV8_EVENT_ATTR(xx, XX) and
>>>>>> &armv8_event_attr_xx.attr.attr. Let's redefine the ARMV8_EVENT_ATTR
>>>>>> to simplify the armv8_pmuv3_event_attrs.
>>>>>>
>>>>>> Cc: Will Deacon <will@kernel.org>
>>>>>> Cc: Mark Rutland <mark.rutland@arm.com>
>>>>>> Signed-off-by: Shaokun Zhang <zhangshaokun@hisilicon.com>
>>>>>> ---
>>>>>>    arch/arm64/kernel/perf_event.c | 189 ++++++++++++++---------------------------
>>>>>>    1 file changed, 65 insertions(+), 124 deletions(-)
>>>>>>
>>>>>> diff --git a/arch/arm64/kernel/perf_event.c b/arch/arm64/kernel/perf_event.c
>>>>>> index a0b4f1bca491..d0f084939bcf 100644
>>>>>> --- a/arch/arm64/kernel/perf_event.c
>>>>>> +++ b/arch/arm64/kernel/perf_event.c
>>>>>> @@ -159,132 +159,73 @@ armv8pmu_events_sysfs_show(struct device *dev,
>>>>>>    }
>>>>>
>>>>> [...]
>>>>>
>>>>>> +	(&((struct perf_pmu_events_attr[]) { \
>>>>>> +		{ .attr = __ATTR(name, 0444, armv8pmu_events_sysfs_show, NULL), \
>>>>>> +		  .id = config, } \
>>>>>> +	})[0].attr.attr)
>>>>>
>>>>> I don't get the need for the array here. Why can't you do:
>>>>>
>>>>> 	(&((struct perf_pmu_events_attr) {
>>>>> 		.attr = ...,
>>>>> 		.id = ...,
>>>>> 	}).attr.attr)
>>>>
>>>> You need want &(obj.attr.attr) rather than &(obj).attr.attr, i.e.
>>>>
>>>> #define ARMV8_EVENT_ATTR(name, config) \
>>>> 	(&((struct perf_pmu_events_attr) { \
>>>> 		.attr = __ATTR(name, 0444, armv8pmu_events_sysfs_show, NULL), \
>>>> 		.id = config, \
>>>> 	}.attr.attr))
>>>> ... which compiles for me.
>>>
>>> Weird, the following compiles fine for me with both GCC and clang:
>>>
>>> #define ARMV8_EVENT_ATTR(name, config)						\
>>> 	(&((struct perf_pmu_events_attr) {					\
>>> 		.attr = __ATTR(name, 0444, armv8pmu_events_sysfs_show, NULL),	\
>>> 		.id = config,							\
>>> 	}).attr.attr)
>>
>> You know that the expressions are equivalent because unary "&" has lower
>> precedence than ".", right? ;)
> 
> Right, which is why it's weird that Shaokun claims that the version I posted
> doesn't compile. I assume it didn't build for Mark either, hence his extra
> brackets.

Because different compilers have different ideas of whether "obj" is a 
valid thing to dereference at all, regardless of where you put 
parentheses. From what I remember, the array trick was the only way to 
convince older GCCs to treat the floating struct initialiser as an 
actual object definition. I guess newer versions are a bit more lenient.

Robin.
Mark Rutland Nov. 1, 2019, 2:32 p.m. UTC | #11
On Fri, Nov 01, 2019 at 10:36:17AM +0000, Will Deacon wrote:
> On Fri, Nov 01, 2019 at 08:53:19AM +0000, Mark Rutland wrote:
> > On Thu, Oct 31, 2019 at 04:08:04PM +0000, Will Deacon wrote:
> > > On Wed, Oct 30, 2019 at 11:46:17AM +0800, Shaokun Zhang wrote:
> > > > For each PMU event, there is a ARMV8_EVENT_ATTR(xx, XX) and
> > > > &armv8_event_attr_xx.attr.attr. Let's redefine the ARMV8_EVENT_ATTR
> > > > to simplify the armv8_pmuv3_event_attrs.
> > > > 
> > > > Cc: Will Deacon <will@kernel.org>
> > > > Cc: Mark Rutland <mark.rutland@arm.com>
> > > > Signed-off-by: Shaokun Zhang <zhangshaokun@hisilicon.com>
> > > > ---
> > > >  arch/arm64/kernel/perf_event.c | 189 ++++++++++++++---------------------------
> > > >  1 file changed, 65 insertions(+), 124 deletions(-)
> > > > 
> > > > diff --git a/arch/arm64/kernel/perf_event.c b/arch/arm64/kernel/perf_event.c
> > > > index a0b4f1bca491..d0f084939bcf 100644
> > > > --- a/arch/arm64/kernel/perf_event.c
> > > > +++ b/arch/arm64/kernel/perf_event.c
> > > > @@ -159,132 +159,73 @@ armv8pmu_events_sysfs_show(struct device *dev,
> > > >  }
> > > 
> > > [...]
> > > 
> > > > +	(&((struct perf_pmu_events_attr[]) { \
> > > > +		{ .attr = __ATTR(name, 0444, armv8pmu_events_sysfs_show, NULL), \
> > > > +		  .id = config, } \
> > > > +	})[0].attr.attr)
> > > 
> > > I don't get the need for the array here. Why can't you do:
> > > 
> > > 	(&((struct perf_pmu_events_attr) {
> > > 		.attr = ...,
> > > 		.id = ...,
> > > 	}).attr.attr)
> > 
> > You need want &(obj.attr.attr) rather than &(obj).attr.attr, i.e.
> > 
> > #define ARMV8_EVENT_ATTR(name, config) \
> > 	(&((struct perf_pmu_events_attr) { \
> > 		.attr = __ATTR(name, 0444, armv8pmu_events_sysfs_show, NULL), \
> > 		.id = config, \
> > 	}.attr.attr))
> >  
> > ... which compiles for me.
> 
> Weird, the following compiles fine for me with both GCC and clang:
> 
> #define ARMV8_EVENT_ATTR(name, config)						\
> 	(&((struct perf_pmu_events_attr) {					\
> 		.attr = __ATTR(name, 0444, armv8pmu_events_sysfs_show, NULL),	\
> 		.id = config,							\
> 	}).attr.attr)

Works for me, too (I'm using the kernel.org crosstool GCC 8.1.0).

I must've messed up locally such that I had (&obj).attr.attr.

> > It'd be worth checking that yields a working data structure at runtime.
> 
> ...and perf list works as expected.

Perfect.

Thanks,
Mark.
Mark Rutland Nov. 1, 2019, 2:36 p.m. UTC | #12
On Fri, Nov 01, 2019 at 11:11:49AM +0000, Robin Murphy wrote:
> On 2019-11-01 10:55 am, Will Deacon wrote:
> > On Fri, Nov 01, 2019 at 10:54:21AM +0000, Robin Murphy wrote:
> > > On 2019-11-01 10:36 am, Will Deacon wrote:
> > > > On Fri, Nov 01, 2019 at 08:53:19AM +0000, Mark Rutland wrote:
> > > > > On Thu, Oct 31, 2019 at 04:08:04PM +0000, Will Deacon wrote:
> > > > > > On Wed, Oct 30, 2019 at 11:46:17AM +0800, Shaokun Zhang wrote:
> > > > > > > For each PMU event, there is a ARMV8_EVENT_ATTR(xx, XX) and
> > > > > > > &armv8_event_attr_xx.attr.attr. Let's redefine the ARMV8_EVENT_ATTR
> > > > > > > to simplify the armv8_pmuv3_event_attrs.
> > > > > > > 
> > > > > > > Cc: Will Deacon <will@kernel.org>
> > > > > > > Cc: Mark Rutland <mark.rutland@arm.com>
> > > > > > > Signed-off-by: Shaokun Zhang <zhangshaokun@hisilicon.com>
> > > > > > > ---
> > > > > > >    arch/arm64/kernel/perf_event.c | 189 ++++++++++++++---------------------------
> > > > > > >    1 file changed, 65 insertions(+), 124 deletions(-)
> > > > > > > 
> > > > > > > diff --git a/arch/arm64/kernel/perf_event.c b/arch/arm64/kernel/perf_event.c
> > > > > > > index a0b4f1bca491..d0f084939bcf 100644
> > > > > > > --- a/arch/arm64/kernel/perf_event.c
> > > > > > > +++ b/arch/arm64/kernel/perf_event.c
> > > > > > > @@ -159,132 +159,73 @@ armv8pmu_events_sysfs_show(struct device *dev,
> > > > > > >    }
> > > > > > 
> > > > > > [...]
> > > > > > 
> > > > > > > +	(&((struct perf_pmu_events_attr[]) { \
> > > > > > > +		{ .attr = __ATTR(name, 0444, armv8pmu_events_sysfs_show, NULL), \
> > > > > > > +		  .id = config, } \
> > > > > > > +	})[0].attr.attr)
> > > > > > 
> > > > > > I don't get the need for the array here. Why can't you do:
> > > > > > 
> > > > > > 	(&((struct perf_pmu_events_attr) {
> > > > > > 		.attr = ...,
> > > > > > 		.id = ...,
> > > > > > 	}).attr.attr)
> > > > > 
> > > > > You need want &(obj.attr.attr) rather than &(obj).attr.attr, i.e.
> > > > > 
> > > > > #define ARMV8_EVENT_ATTR(name, config) \
> > > > > 	(&((struct perf_pmu_events_attr) { \
> > > > > 		.attr = __ATTR(name, 0444, armv8pmu_events_sysfs_show, NULL), \
> > > > > 		.id = config, \
> > > > > 	}.attr.attr))
> > > > > ... which compiles for me.
> > > > 
> > > > Weird, the following compiles fine for me with both GCC and clang:
> > > > 
> > > > #define ARMV8_EVENT_ATTR(name, config)						\
> > > > 	(&((struct perf_pmu_events_attr) {					\
> > > > 		.attr = __ATTR(name, 0444, armv8pmu_events_sysfs_show, NULL),	\
> > > > 		.id = config,							\
> > > > 	}).attr.attr)
> > > 
> > > You know that the expressions are equivalent because unary "&" has lower
> > > precedence than ".", right? ;)
> > 
> > Right, which is why it's weird that Shaokun claims that the version I posted
> > doesn't compile. I assume it didn't build for Mark either, hence his extra
> > brackets.

I must've meessed up locally -- sorry for the noise.

> Because different compilers have different ideas of whether "obj" is a valid
> thing to dereference at all, regardless of where you put parentheses. From
> what I remember, the array trick was the only way to convince older GCCs to
> treat the floating struct initialiser as an actual object definition. I
> guess newer versions are a bit more lenient.

I strongly suspect Will's (much cleaner) version would work with those older
compilers too, and I just didn't know what I was doing ~8 years ago when I came
up with the trick.

I can have a go with my toolchain museum on Monday; if old GCCs are happy we
can clean up the other instances of the trick to be much more legible.

Thanks,
Mark.
Will Deacon Nov. 1, 2019, 4:05 p.m. UTC | #13
On Fri, Nov 01, 2019 at 02:36:03PM +0000, Mark Rutland wrote:
> On Fri, Nov 01, 2019 at 11:11:49AM +0000, Robin Murphy wrote:
> > On 2019-11-01 10:55 am, Will Deacon wrote:
> > > On Fri, Nov 01, 2019 at 10:54:21AM +0000, Robin Murphy wrote:
> > > > On 2019-11-01 10:36 am, Will Deacon wrote:
> > > > > On Fri, Nov 01, 2019 at 08:53:19AM +0000, Mark Rutland wrote:
> > > > > > You need want &(obj.attr.attr) rather than &(obj).attr.attr, i.e.
> > > > > > 
> > > > > > #define ARMV8_EVENT_ATTR(name, config) \
> > > > > > 	(&((struct perf_pmu_events_attr) { \
> > > > > > 		.attr = __ATTR(name, 0444, armv8pmu_events_sysfs_show, NULL), \
> > > > > > 		.id = config, \
> > > > > > 	}.attr.attr))
> > > > > > ... which compiles for me.
> > > > > 
> > > > > Weird, the following compiles fine for me with both GCC and clang:
> > > > > 
> > > > > #define ARMV8_EVENT_ATTR(name, config)						\
> > > > > 	(&((struct perf_pmu_events_attr) {					\
> > > > > 		.attr = __ATTR(name, 0444, armv8pmu_events_sysfs_show, NULL),	\
> > > > > 		.id = config,							\
> > > > > 	}).attr.attr)
> > > > 
> > > > You know that the expressions are equivalent because unary "&" has lower
> > > > precedence than ".", right? ;)
> > > 
> > > Right, which is why it's weird that Shaokun claims that the version I posted
> > > doesn't compile. I assume it didn't build for Mark either, hence his extra
> > > brackets.
> 
> I must've meessed up locally -- sorry for the noise.
> 
> > Because different compilers have different ideas of whether "obj" is a valid
> > thing to dereference at all, regardless of where you put parentheses. From
> > what I remember, the array trick was the only way to convince older GCCs to
> > treat the floating struct initialiser as an actual object definition. I
> > guess newer versions are a bit more lenient.
> 
> I strongly suspect Will's (much cleaner) version would work with those older
> compilers too, and I just didn't know what I was doing ~8 years ago when I came
> up with the trick.
> 
> I can have a go with my toolchain museum on Monday; if old GCCs are happy we
> can clean up the other instances of the trick to be much more legible.

I've thrown it into -next to see how it gets on.

Will
Shaokun Zhang Nov. 4, 2019, 1:02 a.m. UTC | #14
Hi Will,

On 2019/11/1 18:55, Will Deacon wrote:
> On Fri, Nov 01, 2019 at 10:54:21AM +0000, Robin Murphy wrote:
>> On 2019-11-01 10:36 am, Will Deacon wrote:
>>> On Fri, Nov 01, 2019 at 08:53:19AM +0000, Mark Rutland wrote:
>>>> On Thu, Oct 31, 2019 at 04:08:04PM +0000, Will Deacon wrote:
>>>>> On Wed, Oct 30, 2019 at 11:46:17AM +0800, Shaokun Zhang wrote:
>>>>>> For each PMU event, there is a ARMV8_EVENT_ATTR(xx, XX) and
>>>>>> &armv8_event_attr_xx.attr.attr. Let's redefine the ARMV8_EVENT_ATTR
>>>>>> to simplify the armv8_pmuv3_event_attrs.
>>>>>>
>>>>>> Cc: Will Deacon <will@kernel.org>
>>>>>> Cc: Mark Rutland <mark.rutland@arm.com>
>>>>>> Signed-off-by: Shaokun Zhang <zhangshaokun@hisilicon.com>
>>>>>> ---
>>>>>>   arch/arm64/kernel/perf_event.c | 189 ++++++++++++++---------------------------
>>>>>>   1 file changed, 65 insertions(+), 124 deletions(-)
>>>>>>
>>>>>> diff --git a/arch/arm64/kernel/perf_event.c b/arch/arm64/kernel/perf_event.c
>>>>>> index a0b4f1bca491..d0f084939bcf 100644
>>>>>> --- a/arch/arm64/kernel/perf_event.c
>>>>>> +++ b/arch/arm64/kernel/perf_event.c
>>>>>> @@ -159,132 +159,73 @@ armv8pmu_events_sysfs_show(struct device *dev,
>>>>>>   }
>>>>>
>>>>> [...]
>>>>>
>>>>>> +	(&((struct perf_pmu_events_attr[]) { \
>>>>>> +		{ .attr = __ATTR(name, 0444, armv8pmu_events_sysfs_show, NULL), \
>>>>>> +		  .id = config, } \
>>>>>> +	})[0].attr.attr)
>>>>>
>>>>> I don't get the need for the array here. Why can't you do:
>>>>>
>>>>> 	(&((struct perf_pmu_events_attr) {
>>>>> 		.attr = ...,
>>>>> 		.id = ...,
>>>>> 	}).attr.attr)
>>>>
>>>> You need want &(obj.attr.attr) rather than &(obj).attr.attr, i.e.
>>>>
>>>> #define ARMV8_EVENT_ATTR(name, config) \
>>>> 	(&((struct perf_pmu_events_attr) { \
>>>> 		.attr = __ATTR(name, 0444, armv8pmu_events_sysfs_show, NULL), \
>>>> 		.id = config, \
>>>> 	}.attr.attr))
>>>> ... which compiles for me.
>>>
>>> Weird, the following compiles fine for me with both GCC and clang:
>>>
>>> #define ARMV8_EVENT_ATTR(name, config)						\
>>> 	(&((struct perf_pmu_events_attr) {					\
>>> 		.attr = __ATTR(name, 0444, armv8pmu_events_sysfs_show, NULL),	\
>>> 		.id = config,							\
>>> 	}).attr.attr)
>>
>> You know that the expressions are equivalent because unary "&" has lower
>> precedence than ".", right? ;)
> 
> Right, which is why it's weird that Shaokun claims that the version I posted
> doesn't compile. I assume it didn't build for Mark either, hence his extra

The GCC version is gcc (Ubuntu/Linaro 5.4.0-6ubuntu1~16.04.10) 5.4.0 20160609.
It's a little old ;-)

Thanks,
Shaokun

> brackets.
> 
> Will
> 
> .
>
Shaokun Zhang Nov. 4, 2019, 2:02 a.m. UTC | #15
Hi Robin,

On 2019/11/1 19:11, Robin Murphy wrote:
> On 2019-11-01 10:55 am, Will Deacon wrote:
>> On Fri, Nov 01, 2019 at 10:54:21AM +0000, Robin Murphy wrote:
>>> On 2019-11-01 10:36 am, Will Deacon wrote:
>>>> On Fri, Nov 01, 2019 at 08:53:19AM +0000, Mark Rutland wrote:
>>>>> On Thu, Oct 31, 2019 at 04:08:04PM +0000, Will Deacon wrote:
>>>>>> On Wed, Oct 30, 2019 at 11:46:17AM +0800, Shaokun Zhang wrote:
>>>>>>> For each PMU event, there is a ARMV8_EVENT_ATTR(xx, XX) and
>>>>>>> &armv8_event_attr_xx.attr.attr. Let's redefine the ARMV8_EVENT_ATTR
>>>>>>> to simplify the armv8_pmuv3_event_attrs.
>>>>>>>
>>>>>>> Cc: Will Deacon <will@kernel.org>
>>>>>>> Cc: Mark Rutland <mark.rutland@arm.com>
>>>>>>> Signed-off-by: Shaokun Zhang <zhangshaokun@hisilicon.com>
>>>>>>> ---
>>>>>>>    arch/arm64/kernel/perf_event.c | 189 ++++++++++++++---------------------------
>>>>>>>    1 file changed, 65 insertions(+), 124 deletions(-)
>>>>>>>
>>>>>>> diff --git a/arch/arm64/kernel/perf_event.c b/arch/arm64/kernel/perf_event.c
>>>>>>> index a0b4f1bca491..d0f084939bcf 100644
>>>>>>> --- a/arch/arm64/kernel/perf_event.c
>>>>>>> +++ b/arch/arm64/kernel/perf_event.c
>>>>>>> @@ -159,132 +159,73 @@ armv8pmu_events_sysfs_show(struct device *dev,
>>>>>>>    }
>>>>>>
>>>>>> [...]
>>>>>>
>>>>>>> +    (&((struct perf_pmu_events_attr[]) { \
>>>>>>> +        { .attr = __ATTR(name, 0444, armv8pmu_events_sysfs_show, NULL), \
>>>>>>> +          .id = config, } \
>>>>>>> +    })[0].attr.attr)
>>>>>>
>>>>>> I don't get the need for the array here. Why can't you do:
>>>>>>
>>>>>>     (&((struct perf_pmu_events_attr) {
>>>>>>         .attr = ...,
>>>>>>         .id = ...,
>>>>>>     }).attr.attr)
>>>>>
>>>>> You need want &(obj.attr.attr) rather than &(obj).attr.attr, i.e.
>>>>>
>>>>> #define ARMV8_EVENT_ATTR(name, config) \
>>>>>     (&((struct perf_pmu_events_attr) { \
>>>>>         .attr = __ATTR(name, 0444, armv8pmu_events_sysfs_show, NULL), \
>>>>>         .id = config, \
>>>>>     }.attr.attr))
>>>>> ... which compiles for me.
>>>>
>>>> Weird, the following compiles fine for me with both GCC and clang:
>>>>
>>>> #define ARMV8_EVENT_ATTR(name, config)                        \
>>>>     (&((struct perf_pmu_events_attr) {                    \
>>>>         .attr = __ATTR(name, 0444, armv8pmu_events_sysfs_show, NULL),    \
>>>>         .id = config,                            \
>>>>     }).attr.attr)
>>>
>>> You know that the expressions are equivalent because unary "&" has lower
>>> precedence than ".", right? ;)
>>
>> Right, which is why it's weird that Shaokun claims that the version I posted
>> doesn't compile. I assume it didn't build for Mark either, hence his extra
>> brackets.
> 
> Because different compilers have different ideas of whether "obj" is a valid thing to dereference at all, regardless of where you put parentheses. From what I remember, the array trick was the only way to convince older GCCs to treat the floating struct initialiser as an actual object definition. I guess newer versions are a bit more lenient.
> 

Thanks for your detailed explanations, sounds great! Both GCC 5.4 and 7.3 are
unhappy without the array trick.

Thanks,
Shaokun

> Robin.
> 
> .
>
Shaokun Zhang Nov. 4, 2019, 3:18 a.m. UTC | #16
Hi Will,

On 2019/11/4 9:02, Shaokun Zhang wrote:
> Hi Will,
> 
> On 2019/11/1 18:55, Will Deacon wrote:
>> On Fri, Nov 01, 2019 at 10:54:21AM +0000, Robin Murphy wrote:
>>> On 2019-11-01 10:36 am, Will Deacon wrote:
>>>> On Fri, Nov 01, 2019 at 08:53:19AM +0000, Mark Rutland wrote:
>>>>> On Thu, Oct 31, 2019 at 04:08:04PM +0000, Will Deacon wrote:
>>>>>> On Wed, Oct 30, 2019 at 11:46:17AM +0800, Shaokun Zhang wrote:
>>>>>>> For each PMU event, there is a ARMV8_EVENT_ATTR(xx, XX) and
>>>>>>> &armv8_event_attr_xx.attr.attr. Let's redefine the ARMV8_EVENT_ATTR
>>>>>>> to simplify the armv8_pmuv3_event_attrs.
>>>>>>>
>>>>>>> Cc: Will Deacon <will@kernel.org>
>>>>>>> Cc: Mark Rutland <mark.rutland@arm.com>
>>>>>>> Signed-off-by: Shaokun Zhang <zhangshaokun@hisilicon.com>
>>>>>>> ---
>>>>>>>   arch/arm64/kernel/perf_event.c | 189 ++++++++++++++---------------------------
>>>>>>>   1 file changed, 65 insertions(+), 124 deletions(-)
>>>>>>>
>>>>>>> diff --git a/arch/arm64/kernel/perf_event.c b/arch/arm64/kernel/perf_event.c
>>>>>>> index a0b4f1bca491..d0f084939bcf 100644
>>>>>>> --- a/arch/arm64/kernel/perf_event.c
>>>>>>> +++ b/arch/arm64/kernel/perf_event.c
>>>>>>> @@ -159,132 +159,73 @@ armv8pmu_events_sysfs_show(struct device *dev,
>>>>>>>   }
>>>>>>
>>>>>> [...]
>>>>>>
>>>>>>> +	(&((struct perf_pmu_events_attr[]) { \
>>>>>>> +		{ .attr = __ATTR(name, 0444, armv8pmu_events_sysfs_show, NULL), \
>>>>>>> +		  .id = config, } \
>>>>>>> +	})[0].attr.attr)
>>>>>>
>>>>>> I don't get the need for the array here. Why can't you do:
>>>>>>
>>>>>> 	(&((struct perf_pmu_events_attr) {
>>>>>> 		.attr = ...,
>>>>>> 		.id = ...,
>>>>>> 	}).attr.attr)
>>>>>
>>>>> You need want &(obj.attr.attr) rather than &(obj).attr.attr, i.e.
>>>>>
>>>>> #define ARMV8_EVENT_ATTR(name, config) \
>>>>> 	(&((struct perf_pmu_events_attr) { \
>>>>> 		.attr = __ATTR(name, 0444, armv8pmu_events_sysfs_show, NULL), \
>>>>> 		.id = config, \
>>>>> 	}.attr.attr))
>>>>> ... which compiles for me.
>>>>
>>>> Weird, the following compiles fine for me with both GCC and clang:
>>>>
>>>> #define ARMV8_EVENT_ATTR(name, config)						\
>>>> 	(&((struct perf_pmu_events_attr) {					\
>>>> 		.attr = __ATTR(name, 0444, armv8pmu_events_sysfs_show, NULL),	\
>>>> 		.id = config,							\
>>>> 	}).attr.attr)
>>>
>>> You know that the expressions are equivalent because unary "&" has lower
>>> precedence than ".", right? ;)
>>
>> Right, which is why it's weird that Shaokun claims that the version I posted
>> doesn't compile. I assume it didn't build for Mark either, hence his extra
> 
> The GCC version is gcc (Ubuntu/Linaro 5.4.0-6ubuntu1~16.04.10) 5.4.0 20160609.
> It's a little old ;-)

Sorry for my noise, it's my mistake that I forgot to remove the brackets when deleted the array.
 #define ARMV8_EVENT_ATTR(name, config) \
-       (&((struct perf_pmu_events_attr[]) { \
+       (&((struct perf_pmu_events_attr) { \
                { .attr = __ATTR(name, 0444, armv8pmu_events_sysfs_show, NULL), \
                  .id = config, } \
-       })[0].attr.attr)
+       }).attr.attr)

It works now if I follow your proposal completely.:-P

Thanks,
Shaokun

> 
> Thanks,
> Shaokun
> 
>> brackets.
>>
>> Will
>>
>> .
>>
Shaokun Zhang Nov. 4, 2019, 3:25 a.m. UTC | #17
Hi Robin,

Sorry for the noise, it works on both GCC 5.4 and 7.3 using Will's method.

Thanks,
Shaokun

On 2019/11/4 10:02, Shaokun Zhang wrote:
> Hi Robin,
> 
> On 2019/11/1 19:11, Robin Murphy wrote:
>> On 2019-11-01 10:55 am, Will Deacon wrote:
>>> On Fri, Nov 01, 2019 at 10:54:21AM +0000, Robin Murphy wrote:
>>>> On 2019-11-01 10:36 am, Will Deacon wrote:
>>>>> On Fri, Nov 01, 2019 at 08:53:19AM +0000, Mark Rutland wrote:
>>>>>> On Thu, Oct 31, 2019 at 04:08:04PM +0000, Will Deacon wrote:
>>>>>>> On Wed, Oct 30, 2019 at 11:46:17AM +0800, Shaokun Zhang wrote:
>>>>>>>> For each PMU event, there is a ARMV8_EVENT_ATTR(xx, XX) and
>>>>>>>> &armv8_event_attr_xx.attr.attr. Let's redefine the ARMV8_EVENT_ATTR
>>>>>>>> to simplify the armv8_pmuv3_event_attrs.
>>>>>>>>
>>>>>>>> Cc: Will Deacon <will@kernel.org>
>>>>>>>> Cc: Mark Rutland <mark.rutland@arm.com>
>>>>>>>> Signed-off-by: Shaokun Zhang <zhangshaokun@hisilicon.com>
>>>>>>>> ---
>>>>>>>>    arch/arm64/kernel/perf_event.c | 189 ++++++++++++++---------------------------
>>>>>>>>    1 file changed, 65 insertions(+), 124 deletions(-)
>>>>>>>>
>>>>>>>> diff --git a/arch/arm64/kernel/perf_event.c b/arch/arm64/kernel/perf_event.c
>>>>>>>> index a0b4f1bca491..d0f084939bcf 100644
>>>>>>>> --- a/arch/arm64/kernel/perf_event.c
>>>>>>>> +++ b/arch/arm64/kernel/perf_event.c
>>>>>>>> @@ -159,132 +159,73 @@ armv8pmu_events_sysfs_show(struct device *dev,
>>>>>>>>    }
>>>>>>>
>>>>>>> [...]
>>>>>>>
>>>>>>>> +    (&((struct perf_pmu_events_attr[]) { \
>>>>>>>> +        { .attr = __ATTR(name, 0444, armv8pmu_events_sysfs_show, NULL), \
>>>>>>>> +          .id = config, } \
>>>>>>>> +    })[0].attr.attr)
>>>>>>>
>>>>>>> I don't get the need for the array here. Why can't you do:
>>>>>>>
>>>>>>>     (&((struct perf_pmu_events_attr) {
>>>>>>>         .attr = ...,
>>>>>>>         .id = ...,
>>>>>>>     }).attr.attr)
>>>>>>
>>>>>> You need want &(obj.attr.attr) rather than &(obj).attr.attr, i.e.
>>>>>>
>>>>>> #define ARMV8_EVENT_ATTR(name, config) \
>>>>>>     (&((struct perf_pmu_events_attr) { \
>>>>>>         .attr = __ATTR(name, 0444, armv8pmu_events_sysfs_show, NULL), \
>>>>>>         .id = config, \
>>>>>>     }.attr.attr))
>>>>>> ... which compiles for me.
>>>>>
>>>>> Weird, the following compiles fine for me with both GCC and clang:
>>>>>
>>>>> #define ARMV8_EVENT_ATTR(name, config)                        \
>>>>>     (&((struct perf_pmu_events_attr) {                    \
>>>>>         .attr = __ATTR(name, 0444, armv8pmu_events_sysfs_show, NULL),    \
>>>>>         .id = config,                            \
>>>>>     }).attr.attr)
>>>>
>>>> You know that the expressions are equivalent because unary "&" has lower
>>>> precedence than ".", right? ;)
>>>
>>> Right, which is why it's weird that Shaokun claims that the version I posted
>>> doesn't compile. I assume it didn't build for Mark either, hence his extra
>>> brackets.
>>
>> Because different compilers have different ideas of whether "obj" is a valid thing to dereference at all, regardless of where you put parentheses. From what I remember, the array trick was the only way to convince older GCCs to treat the floating struct initialiser as an actual object definition. I guess newer versions are a bit more lenient.
>>
> 
> Thanks for your detailed explanations, sounds great! Both GCC 5.4 and 7.3 are
> unhappy without the array trick.
> 
> Thanks,
> Shaokun
> 
>> Robin.
>>
>> .
>>
diff mbox series

Patch

diff --git a/arch/arm64/kernel/perf_event.c b/arch/arm64/kernel/perf_event.c
index a0b4f1bca491..d0f084939bcf 100644
--- a/arch/arm64/kernel/perf_event.c
+++ b/arch/arm64/kernel/perf_event.c
@@ -159,132 +159,73 @@  armv8pmu_events_sysfs_show(struct device *dev,
 }
 
 #define ARMV8_EVENT_ATTR(name, config) \
-	PMU_EVENT_ATTR(name, armv8_event_attr_##name, \
-		       config, armv8pmu_events_sysfs_show)
-
-ARMV8_EVENT_ATTR(sw_incr, ARMV8_PMUV3_PERFCTR_SW_INCR);
-ARMV8_EVENT_ATTR(l1i_cache_refill, ARMV8_PMUV3_PERFCTR_L1I_CACHE_REFILL);
-ARMV8_EVENT_ATTR(l1i_tlb_refill, ARMV8_PMUV3_PERFCTR_L1I_TLB_REFILL);
-ARMV8_EVENT_ATTR(l1d_cache_refill, ARMV8_PMUV3_PERFCTR_L1D_CACHE_REFILL);
-ARMV8_EVENT_ATTR(l1d_cache, ARMV8_PMUV3_PERFCTR_L1D_CACHE);
-ARMV8_EVENT_ATTR(l1d_tlb_refill, ARMV8_PMUV3_PERFCTR_L1D_TLB_REFILL);
-ARMV8_EVENT_ATTR(ld_retired, ARMV8_PMUV3_PERFCTR_LD_RETIRED);
-ARMV8_EVENT_ATTR(st_retired, ARMV8_PMUV3_PERFCTR_ST_RETIRED);
-ARMV8_EVENT_ATTR(inst_retired, ARMV8_PMUV3_PERFCTR_INST_RETIRED);
-ARMV8_EVENT_ATTR(exc_taken, ARMV8_PMUV3_PERFCTR_EXC_TAKEN);
-ARMV8_EVENT_ATTR(exc_return, ARMV8_PMUV3_PERFCTR_EXC_RETURN);
-ARMV8_EVENT_ATTR(cid_write_retired, ARMV8_PMUV3_PERFCTR_CID_WRITE_RETIRED);
-ARMV8_EVENT_ATTR(pc_write_retired, ARMV8_PMUV3_PERFCTR_PC_WRITE_RETIRED);
-ARMV8_EVENT_ATTR(br_immed_retired, ARMV8_PMUV3_PERFCTR_BR_IMMED_RETIRED);
-ARMV8_EVENT_ATTR(br_return_retired, ARMV8_PMUV3_PERFCTR_BR_RETURN_RETIRED);
-ARMV8_EVENT_ATTR(unaligned_ldst_retired, ARMV8_PMUV3_PERFCTR_UNALIGNED_LDST_RETIRED);
-ARMV8_EVENT_ATTR(br_mis_pred, ARMV8_PMUV3_PERFCTR_BR_MIS_PRED);
-ARMV8_EVENT_ATTR(cpu_cycles, ARMV8_PMUV3_PERFCTR_CPU_CYCLES);
-ARMV8_EVENT_ATTR(br_pred, ARMV8_PMUV3_PERFCTR_BR_PRED);
-ARMV8_EVENT_ATTR(mem_access, ARMV8_PMUV3_PERFCTR_MEM_ACCESS);
-ARMV8_EVENT_ATTR(l1i_cache, ARMV8_PMUV3_PERFCTR_L1I_CACHE);
-ARMV8_EVENT_ATTR(l1d_cache_wb, ARMV8_PMUV3_PERFCTR_L1D_CACHE_WB);
-ARMV8_EVENT_ATTR(l2d_cache, ARMV8_PMUV3_PERFCTR_L2D_CACHE);
-ARMV8_EVENT_ATTR(l2d_cache_refill, ARMV8_PMUV3_PERFCTR_L2D_CACHE_REFILL);
-ARMV8_EVENT_ATTR(l2d_cache_wb, ARMV8_PMUV3_PERFCTR_L2D_CACHE_WB);
-ARMV8_EVENT_ATTR(bus_access, ARMV8_PMUV3_PERFCTR_BUS_ACCESS);
-ARMV8_EVENT_ATTR(memory_error, ARMV8_PMUV3_PERFCTR_MEMORY_ERROR);
-ARMV8_EVENT_ATTR(inst_spec, ARMV8_PMUV3_PERFCTR_INST_SPEC);
-ARMV8_EVENT_ATTR(ttbr_write_retired, ARMV8_PMUV3_PERFCTR_TTBR_WRITE_RETIRED);
-ARMV8_EVENT_ATTR(bus_cycles, ARMV8_PMUV3_PERFCTR_BUS_CYCLES);
-/* Don't expose the chain event in /sys, since it's useless in isolation */
-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(l2i_tlb_refill, ARMV8_PMUV3_PERFCTR_L2I_TLB_REFILL);
-ARMV8_EVENT_ATTR(l2d_tlb, ARMV8_PMUV3_PERFCTR_L2D_TLB);
-ARMV8_EVENT_ATTR(l2i_tlb, ARMV8_PMUV3_PERFCTR_L2I_TLB);
-ARMV8_EVENT_ATTR(remote_access, ARMV8_PMUV3_PERFCTR_REMOTE_ACCESS);
-ARMV8_EVENT_ATTR(ll_cache, ARMV8_PMUV3_PERFCTR_LL_CACHE);
-ARMV8_EVENT_ATTR(ll_cache_miss, ARMV8_PMUV3_PERFCTR_LL_CACHE_MISS);
-ARMV8_EVENT_ATTR(dtlb_walk, ARMV8_PMUV3_PERFCTR_DTLB_WALK);
-ARMV8_EVENT_ATTR(itlb_walk, ARMV8_PMUV3_PERFCTR_ITLB_WALK);
-ARMV8_EVENT_ATTR(ll_cache_rd, ARMV8_PMUV3_PERFCTR_LL_CACHE_RD);
-ARMV8_EVENT_ATTR(ll_cache_miss_rd, ARMV8_PMUV3_PERFCTR_LL_CACHE_MISS_RD);
-ARMV8_EVENT_ATTR(remote_access_rd, ARMV8_PMUV3_PERFCTR_REMOTE_ACCESS_RD);
-ARMV8_EVENT_ATTR(sample_pop, ARMV8_SPE_PERFCTR_SAMPLE_POP);
-ARMV8_EVENT_ATTR(sample_feed, ARMV8_SPE_PERFCTR_SAMPLE_FEED);
-ARMV8_EVENT_ATTR(sample_filtrate, ARMV8_SPE_PERFCTR_SAMPLE_FILTRATE);
-ARMV8_EVENT_ATTR(sample_collision, ARMV8_SPE_PERFCTR_SAMPLE_COLLISION);
+	(&((struct perf_pmu_events_attr[]) { \
+		{ .attr = __ATTR(name, 0444, armv8pmu_events_sysfs_show, NULL), \
+		  .id = config, } \
+	})[0].attr.attr)
 
 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_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_l2i_tlb_refill.attr.attr,
-	&armv8_event_attr_l2d_tlb.attr.attr,
-	&armv8_event_attr_l2i_tlb.attr.attr,
-	&armv8_event_attr_remote_access.attr.attr,
-	&armv8_event_attr_ll_cache.attr.attr,
-	&armv8_event_attr_ll_cache_miss.attr.attr,
-	&armv8_event_attr_dtlb_walk.attr.attr,
-	&armv8_event_attr_itlb_walk.attr.attr,
-	&armv8_event_attr_ll_cache_rd.attr.attr,
-	&armv8_event_attr_ll_cache_miss_rd.attr.attr,
-	&armv8_event_attr_remote_access_rd.attr.attr,
-	&armv8_event_attr_sample_pop.attr.attr,
-	&armv8_event_attr_sample_feed.attr.attr,
-	&armv8_event_attr_sample_filtrate.attr.attr,
-	&armv8_event_attr_sample_collision.attr.attr,
+	ARMV8_EVENT_ATTR(sw_incr, ARMV8_PMUV3_PERFCTR_SW_INCR),
+	ARMV8_EVENT_ATTR(l1i_cache_refill, ARMV8_PMUV3_PERFCTR_L1I_CACHE_REFILL),
+	ARMV8_EVENT_ATTR(l1i_tlb_refill, ARMV8_PMUV3_PERFCTR_L1I_TLB_REFILL),
+	ARMV8_EVENT_ATTR(l1d_cache_refill, ARMV8_PMUV3_PERFCTR_L1D_CACHE_REFILL),
+	ARMV8_EVENT_ATTR(l1d_cache, ARMV8_PMUV3_PERFCTR_L1D_CACHE),
+	ARMV8_EVENT_ATTR(l1d_tlb_refill, ARMV8_PMUV3_PERFCTR_L1D_TLB_REFILL),
+	ARMV8_EVENT_ATTR(ld_retired, ARMV8_PMUV3_PERFCTR_LD_RETIRED),
+	ARMV8_EVENT_ATTR(st_retired, ARMV8_PMUV3_PERFCTR_ST_RETIRED),
+	ARMV8_EVENT_ATTR(inst_retired, ARMV8_PMUV3_PERFCTR_INST_RETIRED),
+	ARMV8_EVENT_ATTR(exc_taken, ARMV8_PMUV3_PERFCTR_EXC_TAKEN),
+	ARMV8_EVENT_ATTR(exc_return, ARMV8_PMUV3_PERFCTR_EXC_RETURN),
+	ARMV8_EVENT_ATTR(cid_write_retired, ARMV8_PMUV3_PERFCTR_CID_WRITE_RETIRED),
+	ARMV8_EVENT_ATTR(pc_write_retired, ARMV8_PMUV3_PERFCTR_PC_WRITE_RETIRED),
+	ARMV8_EVENT_ATTR(br_immed_retired, ARMV8_PMUV3_PERFCTR_BR_IMMED_RETIRED),
+	ARMV8_EVENT_ATTR(br_return_retired, ARMV8_PMUV3_PERFCTR_BR_RETURN_RETIRED),
+	ARMV8_EVENT_ATTR(unaligned_ldst_retired, ARMV8_PMUV3_PERFCTR_UNALIGNED_LDST_RETIRED),
+	ARMV8_EVENT_ATTR(br_mis_pred, ARMV8_PMUV3_PERFCTR_BR_MIS_PRED),
+	ARMV8_EVENT_ATTR(cpu_cycles, ARMV8_PMUV3_PERFCTR_CPU_CYCLES),
+	ARMV8_EVENT_ATTR(br_pred, ARMV8_PMUV3_PERFCTR_BR_PRED),
+	ARMV8_EVENT_ATTR(mem_access, ARMV8_PMUV3_PERFCTR_MEM_ACCESS),
+	ARMV8_EVENT_ATTR(l1i_cache, ARMV8_PMUV3_PERFCTR_L1I_CACHE),
+	ARMV8_EVENT_ATTR(l1d_cache_wb, ARMV8_PMUV3_PERFCTR_L1D_CACHE_WB),
+	ARMV8_EVENT_ATTR(l2d_cache, ARMV8_PMUV3_PERFCTR_L2D_CACHE),
+	ARMV8_EVENT_ATTR(l2d_cache_refill, ARMV8_PMUV3_PERFCTR_L2D_CACHE_REFILL),
+	ARMV8_EVENT_ATTR(l2d_cache_wb, ARMV8_PMUV3_PERFCTR_L2D_CACHE_WB),
+	ARMV8_EVENT_ATTR(bus_access, ARMV8_PMUV3_PERFCTR_BUS_ACCESS),
+	ARMV8_EVENT_ATTR(memory_error, ARMV8_PMUV3_PERFCTR_MEMORY_ERROR),
+	ARMV8_EVENT_ATTR(inst_spec, ARMV8_PMUV3_PERFCTR_INST_SPEC),
+	ARMV8_EVENT_ATTR(ttbr_write_retired, ARMV8_PMUV3_PERFCTR_TTBR_WRITE_RETIRED),
+	ARMV8_EVENT_ATTR(bus_cycles, ARMV8_PMUV3_PERFCTR_BUS_CYCLES),
+	/* Don't expose the chain event in /sys, since it's useless in isolation */
+	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(l2i_tlb_refill, ARMV8_PMUV3_PERFCTR_L2I_TLB_REFILL),
+	ARMV8_EVENT_ATTR(l2d_tlb, ARMV8_PMUV3_PERFCTR_L2D_TLB),
+	ARMV8_EVENT_ATTR(l2i_tlb, ARMV8_PMUV3_PERFCTR_L2I_TLB),
+	ARMV8_EVENT_ATTR(remote_access, ARMV8_PMUV3_PERFCTR_REMOTE_ACCESS),
+	ARMV8_EVENT_ATTR(ll_cache, ARMV8_PMUV3_PERFCTR_LL_CACHE),
+	ARMV8_EVENT_ATTR(ll_cache_miss, ARMV8_PMUV3_PERFCTR_LL_CACHE_MISS),
+	ARMV8_EVENT_ATTR(dtlb_walk, ARMV8_PMUV3_PERFCTR_DTLB_WALK),
+	ARMV8_EVENT_ATTR(itlb_walk, ARMV8_PMUV3_PERFCTR_ITLB_WALK),
+	ARMV8_EVENT_ATTR(ll_cache_rd, ARMV8_PMUV3_PERFCTR_LL_CACHE_RD),
+	ARMV8_EVENT_ATTR(ll_cache_miss_rd, ARMV8_PMUV3_PERFCTR_LL_CACHE_MISS_RD),
+	ARMV8_EVENT_ATTR(remote_access_rd, ARMV8_PMUV3_PERFCTR_REMOTE_ACCESS_RD),
+	ARMV8_EVENT_ATTR(sample_pop, ARMV8_SPE_PERFCTR_SAMPLE_POP),
+	ARMV8_EVENT_ATTR(sample_feed, ARMV8_SPE_PERFCTR_SAMPLE_FEED),
+	ARMV8_EVENT_ATTR(sample_filtrate, ARMV8_SPE_PERFCTR_SAMPLE_FILTRATE),
+	ARMV8_EVENT_ATTR(sample_collision, ARMV8_SPE_PERFCTR_SAMPLE_COLLISION),
 	NULL,
 };