Message ID | 1622269186-10921-1-git-send-email-zhangshaokun@hisilicon.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | [v2] arm64: perf: Add more support on caps under sysfs | expand |
On Sat, May 29, 2021 at 02:19:46PM +0800, Shaokun Zhang wrote: > Armv8.7 has introduced BUS_SLOTS and BUS_WIDTH in PMMIR_EL1 register, > add two entries in caps for bus_slots and bus_width under sysfs. It > will return the true slots and width if the information is available, > otherwise it will return 0. > > Cc: Will Deacon <will@kernel.org> > Cc: Mark Rutland <mark.rutland@arm.com> > Cc: Robin Murphy <robin.murphy@arm.com> > Signed-off-by: Shaokun Zhang <zhangshaokun@hisilicon.com> > --- > ChangeLog: > v1-->v2: > 1. Address Robin's comment on bus_width calculation. > 2. Add the comment on calculation formula. > > Will & Robin, > > I don't change any about visible, if have more comments, > please let me know. > > arch/arm64/include/asm/perf_event.h | 5 +++++ > arch/arm64/kernel/perf_event.c | 35 +++++++++++++++++++++++++++++++++++ > 2 files changed, 40 insertions(+) > > diff --git a/arch/arm64/include/asm/perf_event.h b/arch/arm64/include/asm/perf_event.h > index 60731f602d3e..4ef6f19331f9 100644 > --- a/arch/arm64/include/asm/perf_event.h > +++ b/arch/arm64/include/asm/perf_event.h > @@ -239,6 +239,11 @@ > /* PMMIR_EL1.SLOTS mask */ > #define ARMV8_PMU_SLOTS_MASK 0xff > > +#define ARMV8_PMU_BUS_SLOTS_SHIFT 8 > +#define ARMV8_PMU_BUS_SLOTS_MASK 0xff > +#define ARMV8_PMU_BUS_WIDTH_SHIFT 16 > +#define ARMV8_PMU_BUS_WIDTH_MASK 0xf > + > #ifdef CONFIG_PERF_EVENTS > struct pt_regs; > extern unsigned long perf_instruction_pointer(struct pt_regs *regs); > diff --git a/arch/arm64/kernel/perf_event.c b/arch/arm64/kernel/perf_event.c > index f594957e29bd..453e0d8a442e 100644 > --- a/arch/arm64/kernel/perf_event.c > +++ b/arch/arm64/kernel/perf_event.c > @@ -317,8 +317,43 @@ static ssize_t slots_show(struct device *dev, struct device_attribute *attr, > > static DEVICE_ATTR_RO(slots); > > +static ssize_t bus_slots_show(struct device *dev, struct device_attribute *attr, > + char *page) > +{ > + struct pmu *pmu = dev_get_drvdata(dev); > + struct arm_pmu *cpu_pmu = container_of(pmu, struct arm_pmu, pmu); > + u32 bus_slots = (cpu_pmu->reg_pmmir >> ARMV8_PMU_BUS_SLOTS_SHIFT) > + & ARMV8_PMU_BUS_SLOTS_MASK; > + > + return snprintf(page, PAGE_SIZE, "0x%08x\n", bus_slots); Can you use sysfs_emit() instead? > +} > + > +static DEVICE_ATTR_RO(bus_slots); > + > +static ssize_t bus_width_show(struct device *dev, struct device_attribute *attr, > + char *page) > +{ > + struct pmu *pmu = dev_get_drvdata(dev); > + struct arm_pmu *cpu_pmu = container_of(pmu, struct arm_pmu, pmu); > + u32 bus_width = (cpu_pmu->reg_pmmir >> ARMV8_PMU_BUS_WIDTH_SHIFT) > + & ARMV8_PMU_BUS_WIDTH_MASK; > + u32 val; Just initialise val to 0 here and drop the 'else' below. > + /* Encoded as Log2(number of bytes), plus one */ > + if (bus_width > 2 && bus_width < 13) > + val = 1 << (bus_width - 1); > + else > + val = 0; > + > + return snprintf(page, PAGE_SIZE, "0x%08x\n", val); Again, sysfs_emit? Will
Hi Will, On 2021/6/3 0:42, Will Deacon wrote: > On Sat, May 29, 2021 at 02:19:46PM +0800, Shaokun Zhang wrote: >> Armv8.7 has introduced BUS_SLOTS and BUS_WIDTH in PMMIR_EL1 register, >> add two entries in caps for bus_slots and bus_width under sysfs. It >> will return the true slots and width if the information is available, >> otherwise it will return 0. >> >> Cc: Will Deacon <will@kernel.org> >> Cc: Mark Rutland <mark.rutland@arm.com> >> Cc: Robin Murphy <robin.murphy@arm.com> >> Signed-off-by: Shaokun Zhang <zhangshaokun@hisilicon.com> >> --- >> ChangeLog: >> v1-->v2: >> 1. Address Robin's comment on bus_width calculation. >> 2. Add the comment on calculation formula. >> >> Will & Robin, >> >> I don't change any about visible, if have more comments, >> please let me know. >> >> arch/arm64/include/asm/perf_event.h | 5 +++++ >> arch/arm64/kernel/perf_event.c | 35 +++++++++++++++++++++++++++++++++++ >> 2 files changed, 40 insertions(+) >> >> diff --git a/arch/arm64/include/asm/perf_event.h b/arch/arm64/include/asm/perf_event.h >> index 60731f602d3e..4ef6f19331f9 100644 >> --- a/arch/arm64/include/asm/perf_event.h >> +++ b/arch/arm64/include/asm/perf_event.h >> @@ -239,6 +239,11 @@ >> /* PMMIR_EL1.SLOTS mask */ >> #define ARMV8_PMU_SLOTS_MASK 0xff >> >> +#define ARMV8_PMU_BUS_SLOTS_SHIFT 8 >> +#define ARMV8_PMU_BUS_SLOTS_MASK 0xff >> +#define ARMV8_PMU_BUS_WIDTH_SHIFT 16 >> +#define ARMV8_PMU_BUS_WIDTH_MASK 0xf >> + >> #ifdef CONFIG_PERF_EVENTS >> struct pt_regs; >> extern unsigned long perf_instruction_pointer(struct pt_regs *regs); >> diff --git a/arch/arm64/kernel/perf_event.c b/arch/arm64/kernel/perf_event.c >> index f594957e29bd..453e0d8a442e 100644 >> --- a/arch/arm64/kernel/perf_event.c >> +++ b/arch/arm64/kernel/perf_event.c >> @@ -317,8 +317,43 @@ static ssize_t slots_show(struct device *dev, struct device_attribute *attr, >> >> static DEVICE_ATTR_RO(slots); >> >> +static ssize_t bus_slots_show(struct device *dev, struct device_attribute *attr, >> + char *page) >> +{ >> + struct pmu *pmu = dev_get_drvdata(dev); >> + struct arm_pmu *cpu_pmu = container_of(pmu, struct arm_pmu, pmu); >> + u32 bus_slots = (cpu_pmu->reg_pmmir >> ARMV8_PMU_BUS_SLOTS_SHIFT) >> + & ARMV8_PMU_BUS_SLOTS_MASK; >> + >> + return snprintf(page, PAGE_SIZE, "0x%08x\n", bus_slots); > > Can you use sysfs_emit() instead? > Ok, >> +} >> + >> +static DEVICE_ATTR_RO(bus_slots); >> + >> +static ssize_t bus_width_show(struct device *dev, struct device_attribute *attr, >> + char *page) >> +{ >> + struct pmu *pmu = dev_get_drvdata(dev); >> + struct arm_pmu *cpu_pmu = container_of(pmu, struct arm_pmu, pmu); >> + u32 bus_width = (cpu_pmu->reg_pmmir >> ARMV8_PMU_BUS_WIDTH_SHIFT) >> + & ARMV8_PMU_BUS_WIDTH_MASK; >> + u32 val; > > Just initialise val to 0 here and drop the 'else' below. > Sure, >> + /* Encoded as Log2(number of bytes), plus one */ >> + if (bus_width > 2 && bus_width < 13) >> + val = 1 << (bus_width - 1); >> + else >> + val = 0; >> + >> + return snprintf(page, PAGE_SIZE, "0x%08x\n", val); > > Again, sysfs_emit? Got it and will fix these in next version. Thanks, Shaokun > > Will > . >
diff --git a/arch/arm64/include/asm/perf_event.h b/arch/arm64/include/asm/perf_event.h index 60731f602d3e..4ef6f19331f9 100644 --- a/arch/arm64/include/asm/perf_event.h +++ b/arch/arm64/include/asm/perf_event.h @@ -239,6 +239,11 @@ /* PMMIR_EL1.SLOTS mask */ #define ARMV8_PMU_SLOTS_MASK 0xff +#define ARMV8_PMU_BUS_SLOTS_SHIFT 8 +#define ARMV8_PMU_BUS_SLOTS_MASK 0xff +#define ARMV8_PMU_BUS_WIDTH_SHIFT 16 +#define ARMV8_PMU_BUS_WIDTH_MASK 0xf + #ifdef CONFIG_PERF_EVENTS struct pt_regs; extern unsigned long perf_instruction_pointer(struct pt_regs *regs); diff --git a/arch/arm64/kernel/perf_event.c b/arch/arm64/kernel/perf_event.c index f594957e29bd..453e0d8a442e 100644 --- a/arch/arm64/kernel/perf_event.c +++ b/arch/arm64/kernel/perf_event.c @@ -317,8 +317,43 @@ static ssize_t slots_show(struct device *dev, struct device_attribute *attr, static DEVICE_ATTR_RO(slots); +static ssize_t bus_slots_show(struct device *dev, struct device_attribute *attr, + char *page) +{ + struct pmu *pmu = dev_get_drvdata(dev); + struct arm_pmu *cpu_pmu = container_of(pmu, struct arm_pmu, pmu); + u32 bus_slots = (cpu_pmu->reg_pmmir >> ARMV8_PMU_BUS_SLOTS_SHIFT) + & ARMV8_PMU_BUS_SLOTS_MASK; + + return snprintf(page, PAGE_SIZE, "0x%08x\n", bus_slots); +} + +static DEVICE_ATTR_RO(bus_slots); + +static ssize_t bus_width_show(struct device *dev, struct device_attribute *attr, + char *page) +{ + struct pmu *pmu = dev_get_drvdata(dev); + struct arm_pmu *cpu_pmu = container_of(pmu, struct arm_pmu, pmu); + u32 bus_width = (cpu_pmu->reg_pmmir >> ARMV8_PMU_BUS_WIDTH_SHIFT) + & ARMV8_PMU_BUS_WIDTH_MASK; + u32 val; + + /* Encoded as Log2(number of bytes), plus one */ + if (bus_width > 2 && bus_width < 13) + val = 1 << (bus_width - 1); + else + val = 0; + + return snprintf(page, PAGE_SIZE, "0x%08x\n", val); +} + +static DEVICE_ATTR_RO(bus_width); + static struct attribute *armv8_pmuv3_caps_attrs[] = { &dev_attr_slots.attr, + &dev_attr_bus_slots.attr, + &dev_attr_bus_width.attr, NULL, };
Armv8.7 has introduced BUS_SLOTS and BUS_WIDTH in PMMIR_EL1 register, add two entries in caps for bus_slots and bus_width under sysfs. It will return the true slots and width if the information is available, otherwise it will return 0. Cc: Will Deacon <will@kernel.org> Cc: Mark Rutland <mark.rutland@arm.com> Cc: Robin Murphy <robin.murphy@arm.com> Signed-off-by: Shaokun Zhang <zhangshaokun@hisilicon.com> --- ChangeLog: v1-->v2: 1. Address Robin's comment on bus_width calculation. 2. Add the comment on calculation formula. Will & Robin, I don't change any about visible, if have more comments, please let me know. arch/arm64/include/asm/perf_event.h | 5 +++++ arch/arm64/kernel/perf_event.c | 35 +++++++++++++++++++++++++++++++++++ 2 files changed, 40 insertions(+)