Skip to content

Commit 3f66465

Browse files
geomatsiavpatel
authored andcommitted
lib: pmu: allow to use the highest available counter
OpenSBI explicitly assumes that there is no pmu hardware counter with index 1: hardware uses that bit for TM control. So OpenSBI filters out that index in sanity checks. However OpenSBI also excludes that counter when reports total amount of hardware counters to Linux. As a result, Linux uses incomplete counters mask excluding the highest available counter. Return accurate number of counters, update the firmware counter starting index, fix range checks that include num_hw_ctrs. The simple test is to make sure that there is no counter multiplexing in the following command: $ perf stat -e \ r8000000000000000,r8000000000000001,r8000000000000002,r8000000000000003, \ r8000000000000004,r8000000000000005,r8000000000000006,r8000000000000007, \ r8000000000000008,r8000000000000009,r800000000000000a,r800000000000000b, \ r800000000000000c,r800000000000000d,r800000000000000e,r800000000000000f \ ls Note that 16 firmware events with 16 counters won't require multiplexing. Signed-off-by: Sergey Matyukevich <[email protected]> Signed-off-by: Atish Patra <[email protected]> Reviewed-by: Atish Patra <[email protected]>
1 parent c6fdbcf commit 3f66465

File tree

1 file changed

+7
-7
lines changed

1 file changed

+7
-7
lines changed

lib/sbi/sbi_pmu.c

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -297,7 +297,7 @@ static int pmu_ctr_start_hw(uint32_t cidx, uint64_t ival, bool ival_update)
297297
unsigned long mctr_inhbt;
298298

299299
/* Make sure the counter index lies within the range and is not TM bit */
300-
if (cidx > num_hw_ctrs || cidx == 1)
300+
if (cidx >= num_hw_ctrs || cidx == 1)
301301
return SBI_EINVAL;
302302

303303
if (sbi_hart_priv_version(scratch) < SBI_HART_PRIV_VER_1_11)
@@ -378,7 +378,7 @@ static int pmu_ctr_stop_hw(uint32_t cidx)
378378
mctr_inhbt = csr_read(CSR_MCOUNTINHIBIT);
379379

380380
/* Make sure the counter index lies within the range and is not TM bit */
381-
if (cidx > num_hw_ctrs || cidx == 1)
381+
if (cidx >= num_hw_ctrs || cidx == 1)
382382
return SBI_EINVAL;
383383

384384
if (!__test_bit(cidx, &mctr_inhbt)) {
@@ -516,7 +516,7 @@ static int pmu_ctr_find_hw(unsigned long cbase, unsigned long cmask, unsigned lo
516516
u32 hartid = current_hartid();
517517
struct sbi_scratch *scratch = sbi_scratch_thishart_ptr();
518518

519-
if (cbase > num_hw_ctrs)
519+
if (cbase >= num_hw_ctrs)
520520
return SBI_EINVAL;
521521

522522
/**
@@ -593,8 +593,8 @@ static int pmu_ctr_find_fw(unsigned long cbase, unsigned long cmask, u32 hartid)
593593
int fw_base;
594594
unsigned long ctr_mask = cmask << cbase;
595595

596-
if (cbase <= num_hw_ctrs)
597-
fw_base = num_hw_ctrs + 1;
596+
if (cbase < num_hw_ctrs)
597+
fw_base = num_hw_ctrs;
598598
else
599599
fw_base = cbase;
600600

@@ -694,7 +694,7 @@ int sbi_pmu_ctr_get_info(uint32_t cidx, unsigned long *ctr_info)
694694
return SBI_EINVAL;
695695

696696
/* We have 31 HW counters with 31 being the last index(MHPMCOUNTER31) */
697-
if (cidx <= num_hw_ctrs) {
697+
if (cidx < num_hw_ctrs) {
698698
cinfo.type = SBI_PMU_CTR_TYPE_HW;
699699
cinfo.csr = CSR_CYCLE + cidx;
700700
/* mcycle & minstret are always 64 bit */
@@ -749,7 +749,7 @@ int sbi_pmu_init(struct sbi_scratch *scratch, bool cold_boot)
749749
sbi_platform_pmu_init(plat);
750750

751751
/* mcycle & minstret is available always */
752-
num_hw_ctrs = sbi_hart_mhpm_count(scratch) + 2;
752+
num_hw_ctrs = sbi_hart_mhpm_count(scratch) + 3;
753753
total_ctrs = num_hw_ctrs + SBI_PMU_FW_CTR_MAX;
754754
}
755755

0 commit comments

Comments
 (0)