From cbcfe29a9dc6fb4371b98c01633151ca52338e64 Mon Sep 17 00:00:00 2001 From: Santosh Mardi Date: Fri, 16 Oct 2020 00:21:14 +0530 Subject: [PATCH] drivers: soc: qcom: use hw counter values for PMU snapshot to RIMPS RIMPS memlat driver reads the current PMU counter value using perf_event_read_local() API at the time of core going offline or entering LPM and saves the current snapshot to a shared memory for access by RIMPS. RIMPS reads these values from the shared memory when core is offline or in LPM state, and reads directly from PMU hardware when core is online. The value read from hardware and the one read from shared memory are going out of sync because perf event driver limits the counting range of PMU counter to half of the total range supported by hardware, and it configures the counter to start counting from midpoint at the time of counter reset and upon overflow. It keeps adding the delta read from hardware counters to software maintained counters and it returns the same through perf_event_read API. As this is not the exact same value as what is read from hardware counters, the values read by RIMPS from shared memory are going out of sync. To address this get the current snapshot of hardware counter value from prev_count member of hw_perf_event structure which is part of perf_event structure, and store that to shared memory. Change-Id: I71f416270a02f7925b16e576f637cf3579fec6ce Signed-off-by: Santosh Mardi --- drivers/soc/qcom/rimps_memlat.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/soc/qcom/rimps_memlat.c b/drivers/soc/qcom/rimps_memlat.c index fed91f3edcb7..c394dd2baa67 100644 --- a/drivers/soc/qcom/rimps_memlat.c +++ b/drivers/soc/qcom/rimps_memlat.c @@ -630,8 +630,8 @@ static void save_cpugrp_pmu_events(struct memlat_cpu_grp *cpu_grp, u8 cpu) if ((hw_id == INVALID_PMU_HW_IDX) || !cpus_data->common_evs[i]) continue; - perf_event_read_local(cpus_data->common_evs[i], - &ev_count, NULL, NULL); + + ev_count = local64_read(&cpus_data->common_evs[i]->hw.prev_count); store_event_val(ev_count, hw_id, cpu); } } @@ -650,8 +650,7 @@ static void save_mon_pmu_events(struct memlat_mon *mon, u8 cpu) if (hw_id == INVALID_PMU_HW_IDX || !ev_data->mon_evs[i]) continue; - perf_event_read_local(ev_data->mon_evs[i], - &ev_count, NULL, NULL); + ev_count = local64_read(&ev_data->mon_evs[i]->hw.prev_count); store_event_val(ev_count, hw_id, cpu); } }