Skip to content

Commit b994cdf

Browse files
atishp04avpatel
authored andcommitted
drivers/perf: riscv: Fix counter mask iteration for RV32
For RV32, used_hw_ctrs can have more than 1 word if the firmware chooses to interleave firmware/hardware counters indicies. Even though it's a unlikely scenario, handle that case by iterating over all the words instead of just using the first word. Reviewed-by: Andrew Jones <ajones@ventanamicro.com> Acked-by: Palmer Dabbelt <palmer@rivosinc.com> Signed-off-by: Atish Patra <atishp@rivosinc.com> Link: https://lore.kernel.org/r/20240420151741.962500-9-atishp@rivosinc.com Signed-off-by: Anup Patel <anup@brainfault.org>
1 parent b737fc2 commit b994cdf

1 file changed

Lines changed: 12 additions & 9 deletions

File tree

drivers/perf/riscv_pmu_sbi.c

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -652,10 +652,12 @@ static inline void pmu_sbi_stop_all(struct riscv_pmu *pmu)
652652
static inline void pmu_sbi_stop_hw_ctrs(struct riscv_pmu *pmu)
653653
{
654654
struct cpu_hw_events *cpu_hw_evt = this_cpu_ptr(pmu->hw_events);
655+
int i;
655656

656-
/* No need to check the error here as we can't do anything about the error */
657-
sbi_ecall(SBI_EXT_PMU, SBI_EXT_PMU_COUNTER_STOP, 0,
658-
cpu_hw_evt->used_hw_ctrs[0], 0, 0, 0, 0);
657+
for (i = 0; i < BITS_TO_LONGS(RISCV_MAX_COUNTERS); i++)
658+
/* No need to check the error here as we can't do anything about the error */
659+
sbi_ecall(SBI_EXT_PMU, SBI_EXT_PMU_COUNTER_STOP, i * BITS_PER_LONG,
660+
cpu_hw_evt->used_hw_ctrs[i], 0, 0, 0, 0);
659661
}
660662

661663
/*
@@ -667,7 +669,7 @@ static inline void pmu_sbi_stop_hw_ctrs(struct riscv_pmu *pmu)
667669
static inline void pmu_sbi_start_overflow_mask(struct riscv_pmu *pmu,
668670
unsigned long ctr_ovf_mask)
669671
{
670-
int idx = 0;
672+
int idx = 0, i;
671673
struct cpu_hw_events *cpu_hw_evt = this_cpu_ptr(pmu->hw_events);
672674
struct perf_event *event;
673675
unsigned long flag = SBI_PMU_START_FLAG_SET_INIT_VALUE;
@@ -676,11 +678,12 @@ static inline void pmu_sbi_start_overflow_mask(struct riscv_pmu *pmu,
676678
struct hw_perf_event *hwc;
677679
u64 init_val = 0;
678680

679-
ctr_start_mask = cpu_hw_evt->used_hw_ctrs[0] & ~ctr_ovf_mask;
680-
681-
/* Start all the counters that did not overflow in a single shot */
682-
sbi_ecall(SBI_EXT_PMU, SBI_EXT_PMU_COUNTER_START, 0, ctr_start_mask,
683-
0, 0, 0, 0);
681+
for (i = 0; i < BITS_TO_LONGS(RISCV_MAX_COUNTERS); i++) {
682+
ctr_start_mask = cpu_hw_evt->used_hw_ctrs[i] & ~ctr_ovf_mask;
683+
/* Start all the counters that did not overflow in a single shot */
684+
sbi_ecall(SBI_EXT_PMU, SBI_EXT_PMU_COUNTER_START, i * BITS_PER_LONG, ctr_start_mask,
685+
0, 0, 0, 0);
686+
}
684687

685688
/* Reinitialize and start all the counter that overflowed */
686689
while (ctr_ovf_mask) {

0 commit comments

Comments
 (0)