From: Jonas Svennebring <jonas.svennebr...@gmail.com> AXXIA uncore perf fix that allows multiple reads per event add/delete pair. Generally perf events are added, read and then removed, but it is also possible to read continusly. This was not supported until now, which is related to how perf handles platform events. By using single core access, i.e. "-C 0" in perf cli or similar for other tools, it will be possible to use read multiple times with this fix.
Signed-off-by: Jonas Svennebring <jonas.svennebr...@gmail.com> --- arch/arm/mach-axxia/perf_event_memc.c | 37 ++++++++++++++++++++++--------- arch/arm/mach-axxia/perf_event_pcx.c | 7 ++++++ arch/arm/mach-axxia/perf_event_platform.c | 6 ++--- arch/arm/mach-axxia/perf_event_vp.c | 7 ++++++ 4 files changed, 43 insertions(+), 14 deletions(-) diff --git a/arch/arm/mach-axxia/perf_event_memc.c b/arch/arm/mach-axxia/perf_event_memc.c index 2abd47a..7da5926 100644 --- a/arch/arm/mach-axxia/perf_event_memc.c +++ b/arch/arm/mach-axxia/perf_event_memc.c @@ -97,6 +97,29 @@ static uint32_t memc_pmu_event_add(uint32_t ev, struct perf_event *pevent) } /* + * Return counter update. + */ +static uint32_t memc_pmu_event_read(uint32_t ev, struct perf_event *pevent, + int flags) +{ + uint32_t count = 0; + + if (ev >= DDRC0_OFFSET && ev <= DDRC0_SMON_MAX) + count = smon_read(&ddrc0_smon, ev - DDRC0_OFFSET); + else if (ev >= DDRC1_OFFSET && ev <= DDRC1_SMON_MAX) + count = smon_read(&ddrc1_smon, ev - DDRC1_OFFSET); + else if (ev >= ELM0_OFFSET && ev <= ELM0_SMON_MAX) + count = smon_read(&elm0_smon, ev - ELM0_OFFSET); + else if (ev >= ELM1_OFFSET && ev <= ELM1_SMON_MAX) + count = smon_read(&elm1_smon, ev - ELM1_OFFSET); + + if (count == -ENOEVENT) + count = 0; + + return count; +} + +/* * Remove event and return counter update. */ static uint32_t memc_pmu_event_del(uint32_t ev, struct perf_event *pevent, @@ -105,33 +128,25 @@ static uint32_t memc_pmu_event_del(uint32_t ev, struct perf_event *pevent, uint32_t count = 0; if (ev >= DDRC0_OFFSET && ev <= DDRC0_SMON_MAX) { - count = smon_read(&ddrc0_smon, ev - DDRC0_OFFSET); - if (count == -ENOEVENT) - count = 0; smon_deallocate(&ddrc0_smon, ev - DDRC0_OFFSET); } else if (ev >= DDRC1_OFFSET && ev <= DDRC1_SMON_MAX) { - count = smon_read(&ddrc1_smon, ev - DDRC1_OFFSET); - if (count == -ENOEVENT) - count = 0; smon_deallocate(&ddrc1_smon, ev - DDRC1_OFFSET); } else if (ev >= ELM0_OFFSET && ev <= ELM0_SMON_MAX) { count = smon_read(&elm0_smon, ev - ELM0_OFFSET); - if (count == -ENOEVENT) - count = 0; smon_deallocate(&elm0_smon, ev - ELM0_OFFSET); } else if (ev >= ELM1_OFFSET && ev <= ELM1_SMON_MAX) { - count = smon_read(&elm1_smon, ev - ELM1_OFFSET); - if (count == -ENOEVENT) - count = 0; smon_deallocate(&elm1_smon, ev - ELM1_OFFSET); } + if (count == -ENOEVENT) + count = 0; + return count; } diff --git a/arch/arm/mach-axxia/perf_event_pcx.c b/arch/arm/mach-axxia/perf_event_pcx.c index a419c67..690f01c 100644 --- a/arch/arm/mach-axxia/perf_event_pcx.c +++ b/arch/arm/mach-axxia/perf_event_pcx.c @@ -39,8 +39,15 @@ static uint32_t pcx_pmu_event_add(uint32_t ev, struct perf_event *event) return 0; } +static uint32_t pcx_pmu_event_read(uint32_t ev, struct perf_event *event, + int flags) +{ + return 0; +} + static uint32_t pcx_pmu_event_del(uint32_t ev, struct perf_event *event, int flags) { return 0; } + diff --git a/arch/arm/mach-axxia/perf_event_platform.c b/arch/arm/mach-axxia/perf_event_platform.c index 83a221d..903dbe6 100644 --- a/arch/arm/mach-axxia/perf_event_platform.c +++ b/arch/arm/mach-axxia/perf_event_platform.c @@ -165,13 +165,13 @@ static void platform_pmu_event_read(struct perf_event *event) uint32_t n; if (ev >= AXM_55XX_VP_BASE && ev <= AXM_55XX_VP_MAX) { - n = vp_pmu_event_del(ev - AXM_55XX_VP_BASE, event, 0); + n = vp_pmu_event_read(ev - AXM_55XX_VP_BASE, event, 0); local64_add(n, &event->count); } else if (ev >= AXM_55XX_PCX_BASE && ev <= AXM_55XX_PCX_MAX) { - n = pcx_pmu_event_del(ev - AXM_55XX_PCX_BASE, event, 0); + n = pcx_pmu_event_read(ev - AXM_55XX_PCX_BASE, event, 0); local64_add(n, &event->count); } else if (ev >= AXM_55XX_MEMC_BASE && ev <= AXM_55XX_MEMC_MAX) { - n = memc_pmu_event_del(ev - AXM_55XX_MEMC_BASE, event, 0); + n = memc_pmu_event_read(ev - AXM_55XX_MEMC_BASE, event, 0); local64_add(n, &event->count); } } diff --git a/arch/arm/mach-axxia/perf_event_vp.c b/arch/arm/mach-axxia/perf_event_vp.c index e20f2db..a101390 100644 --- a/arch/arm/mach-axxia/perf_event_vp.c +++ b/arch/arm/mach-axxia/perf_event_vp.c @@ -40,8 +40,15 @@ static uint32_t vp_pmu_event_add(uint32_t event, struct perf_event *pevent) return 0; } +static uint32_t vp_pmu_event_read(uint32_t event, struct perf_event *pevent, + int flags) +{ + return 0; +} + static uint32_t vp_pmu_event_del(uint32_t event, struct perf_event *pevent, int flags) { return 0; } + -- 1.8.1.4 -- _______________________________________________ linux-yocto mailing list linux-yocto@yoctoproject.org https://lists.yoctoproject.org/listinfo/linux-yocto