summaryrefslogtreecommitdiff
path: root/drivers/perf
diff options
context:
space:
mode:
authorAtish Patra <atishp@rivosinc.com>2024-06-28 10:51:41 +0300
committerPalmer Dabbelt <palmer@rivosinc.com>2024-07-03 22:56:15 +0300
commita3f24e83d11d7ceb4743416c803332e9c5749298 (patch)
tree444d4bbe6d512e85cff79e23437bdd2f1e520706 /drivers/perf
parent1613e604df0cd359cf2a7fbd9be7a0bcfacfabd0 (diff)
downloadlinux-a3f24e83d11d7ceb4743416c803332e9c5749298.tar.xz
drivers/perf: riscv: Do not update the event data if uptodate
In case of an counter overflow, the event data may get corrupted if called from an external overflow handler. This happens because we can't update the counter without starting it when SBI PMU extension is in use. However, the prev_count has been already updated at the first pass while the counter value is still the old one. The solution is simple where we don't need to update it again if it is already updated which can be detected using hwc state. The event state in the overflow handler is updated in the following patch. Thus, this fix can't be backported to kernel version where overflow support was added. Fixes: a8625217a054 ("drivers/perf: riscv: Implement SBI PMU snapshot function") Closes:https://lore.kernel.org/all/CC51D53B-846C-4D81-86FC-FBF969D0A0D6@pku.edu.cn/ Reported-by: garthlei@pku.edu.cn Signed-off-by: Atish Patra <atishp@rivosinc.com> Link: https://lore.kernel.org/r/20240628-misc_perf_fixes-v4-1-e01cfddcf035@rivosinc.com Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>
Diffstat (limited to 'drivers/perf')
-rw-r--r--drivers/perf/riscv_pmu.c2
1 files changed, 1 insertions, 1 deletions
diff --git a/drivers/perf/riscv_pmu.c b/drivers/perf/riscv_pmu.c
index 78c490e0505a..0a02e85a8951 100644
--- a/drivers/perf/riscv_pmu.c
+++ b/drivers/perf/riscv_pmu.c
@@ -167,7 +167,7 @@ u64 riscv_pmu_event_update(struct perf_event *event)
unsigned long cmask;
u64 oldval, delta;
- if (!rvpmu->ctr_read)
+ if (!rvpmu->ctr_read || (hwc->state & PERF_HES_UPTODATE))
return 0;
cmask = riscv_pmu_ctr_get_width_mask(event);