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

Reply via email to