Skip to content

Commit 210ac17

Browse files
Merge patch series "Assorted fixes in RISC-V PMU driver"
Atish Patra <[email protected]> says: This series contains 3 fixes out of which the first one is a new fix for invalid event data reported in lkml[2]. The last two are v3 of Samuel's patch[1]. I added the RB/TB/Fixes tag and moved 1 unrelated change to its own patch. I also changed an error message in kvm vcpu_pmu from pr_err to pr_debug to avoid redundant failure error messages generated due to the boot time quering of events implemented in the patch[1] Here is the original cover letter for the patch[1] Before this patch: $ perf list hw List of pre-defined events (to be used in -e or -M): branch-instructions OR branches [Hardware event] branch-misses [Hardware event] bus-cycles [Hardware event] cache-misses [Hardware event] cache-references [Hardware event] cpu-cycles OR cycles [Hardware event] instructions [Hardware event] ref-cycles [Hardware event] stalled-cycles-backend OR idle-cycles-backend [Hardware event] stalled-cycles-frontend OR idle-cycles-frontend [Hardware event] $ perf stat -ddd true Performance counter stats for 'true': 4.36 msec task-clock # 0.744 CPUs utilized 1 context-switches # 229.325 /sec 0 cpu-migrations # 0.000 /sec 38 page-faults # 8.714 K/sec 4,375,694 cycles # 1.003 GHz (60.64%) 728,945 instructions # 0.17 insn per cycle 79,199 branches # 18.162 M/sec 17,709 branch-misses # 22.36% of all branches 181,734 L1-dcache-loads # 41.676 M/sec 5,547 L1-dcache-load-misses # 3.05% of all L1-dcache accesses <not counted> LLC-loads (0.00%) <not counted> LLC-load-misses (0.00%) <not counted> L1-icache-loads (0.00%) <not counted> L1-icache-load-misses (0.00%) <not counted> dTLB-loads (0.00%) <not counted> dTLB-load-misses (0.00%) <not counted> iTLB-loads (0.00%) <not counted> iTLB-load-misses (0.00%) <not counted> L1-dcache-prefetches (0.00%) <not counted> L1-dcache-prefetch-misses (0.00%) 0.005860375 seconds time elapsed 0.000000000 seconds user 0.010383000 seconds sys After this patch: $ perf list hw List of pre-defined events (to be used in -e or -M): branch-instructions OR branches [Hardware event] branch-misses [Hardware event] cache-misses [Hardware event] cache-references [Hardware event] cpu-cycles OR cycles [Hardware event] instructions [Hardware event] $ perf stat -ddd true Performance counter stats for 'true': 5.16 msec task-clock # 0.848 CPUs utilized 1 context-switches # 193.817 /sec 0 cpu-migrations # 0.000 /sec 37 page-faults # 7.171 K/sec 5,183,625 cycles # 1.005 GHz 961,696 instructions # 0.19 insn per cycle 85,853 branches # 16.640 M/sec 20,462 branch-misses # 23.83% of all branches 243,545 L1-dcache-loads # 47.203 M/sec 5,974 L1-dcache-load-misses # 2.45% of all L1-dcache accesses <not supported> LLC-loads <not supported> LLC-load-misses <not supported> L1-icache-loads <not supported> L1-icache-load-misses <not supported> dTLB-loads 19,619 dTLB-load-misses <not supported> iTLB-loads 6,831 iTLB-load-misses <not supported> L1-dcache-prefetches <not supported> L1-dcache-prefetch-misses 0.006085625 seconds time elapsed 0.000000000 seconds user 0.013022000 seconds sys [1] https://lore.kernel.org/linux-riscv/[email protected]/ [2] https://lore.kernel.org/all/[email protected]/ * b4-shazam-merge: perf: RISC-V: Check standard event availability drivers/perf: riscv: Reset the counter to hpmevent mapping while starting cpus drivers/perf: riscv: Do not update the event data if uptodate Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Palmer Dabbelt <[email protected]>
2 parents 7c5d838 + 16d3b1a commit 210ac17

File tree

3 files changed

+43
-5
lines changed

3 files changed

+43
-5
lines changed

arch/riscv/kvm/vcpu_pmu.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -327,7 +327,7 @@ static long kvm_pmu_create_perf_event(struct kvm_pmc *pmc, struct perf_event_att
327327

328328
event = perf_event_create_kernel_counter(attr, -1, current, kvm_riscv_pmu_overflow, pmc);
329329
if (IS_ERR(event)) {
330-
pr_err("kvm pmu event creation failed for eidx %lx: %ld\n", eidx, PTR_ERR(event));
330+
pr_debug("kvm pmu event creation failed for eidx %lx: %ld\n", eidx, PTR_ERR(event));
331331
return PTR_ERR(event);
332332
}
333333

drivers/perf/riscv_pmu.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,7 @@ u64 riscv_pmu_event_update(struct perf_event *event)
167167
unsigned long cmask;
168168
u64 oldval, delta;
169169

170-
if (!rvpmu->ctr_read)
170+
if (!rvpmu->ctr_read || (hwc->state & PERF_HES_UPTODATE))
171171
return 0;
172172

173173
cmask = riscv_pmu_ctr_get_width_mask(event);

drivers/perf/riscv_pmu_sbi.c

Lines changed: 41 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include <linux/cpu_pm.h>
2121
#include <linux/sched/clock.h>
2222
#include <linux/soc/andes/irq.h>
23+
#include <linux/workqueue.h>
2324

2425
#include <asm/errata_list.h>
2526
#include <asm/sbi.h>
@@ -114,7 +115,7 @@ struct sbi_pmu_event_data {
114115
};
115116
};
116117

117-
static const struct sbi_pmu_event_data pmu_hw_event_map[] = {
118+
static struct sbi_pmu_event_data pmu_hw_event_map[] = {
118119
[PERF_COUNT_HW_CPU_CYCLES] = {.hw_gen_event = {
119120
SBI_PMU_HW_CPU_CYCLES,
120121
SBI_PMU_EVENT_TYPE_HW, 0}},
@@ -148,7 +149,7 @@ static const struct sbi_pmu_event_data pmu_hw_event_map[] = {
148149
};
149150

150151
#define C(x) PERF_COUNT_HW_CACHE_##x
151-
static const struct sbi_pmu_event_data pmu_cache_event_map[PERF_COUNT_HW_CACHE_MAX]
152+
static struct sbi_pmu_event_data pmu_cache_event_map[PERF_COUNT_HW_CACHE_MAX]
152153
[PERF_COUNT_HW_CACHE_OP_MAX]
153154
[PERF_COUNT_HW_CACHE_RESULT_MAX] = {
154155
[C(L1D)] = {
@@ -293,6 +294,34 @@ static const struct sbi_pmu_event_data pmu_cache_event_map[PERF_COUNT_HW_CACHE_M
293294
},
294295
};
295296

297+
static void pmu_sbi_check_event(struct sbi_pmu_event_data *edata)
298+
{
299+
struct sbiret ret;
300+
301+
ret = sbi_ecall(SBI_EXT_PMU, SBI_EXT_PMU_COUNTER_CFG_MATCH,
302+
0, cmask, 0, edata->event_idx, 0, 0);
303+
if (!ret.error) {
304+
sbi_ecall(SBI_EXT_PMU, SBI_EXT_PMU_COUNTER_STOP,
305+
ret.value, 0x1, SBI_PMU_STOP_FLAG_RESET, 0, 0, 0);
306+
} else if (ret.error == SBI_ERR_NOT_SUPPORTED) {
307+
/* This event cannot be monitored by any counter */
308+
edata->event_idx = -EINVAL;
309+
}
310+
}
311+
312+
static void pmu_sbi_check_std_events(struct work_struct *work)
313+
{
314+
for (int i = 0; i < ARRAY_SIZE(pmu_hw_event_map); i++)
315+
pmu_sbi_check_event(&pmu_hw_event_map[i]);
316+
317+
for (int i = 0; i < ARRAY_SIZE(pmu_cache_event_map); i++)
318+
for (int j = 0; j < ARRAY_SIZE(pmu_cache_event_map[i]); j++)
319+
for (int k = 0; k < ARRAY_SIZE(pmu_cache_event_map[i][j]); k++)
320+
pmu_sbi_check_event(&pmu_cache_event_map[i][j][k]);
321+
}
322+
323+
static DECLARE_WORK(check_std_events_work, pmu_sbi_check_std_events);
324+
296325
static int pmu_sbi_ctr_get_width(int idx)
297326
{
298327
return pmu_ctr_list[idx].width;
@@ -478,6 +507,12 @@ static int pmu_sbi_event_map(struct perf_event *event, u64 *econfig)
478507
u64 raw_config_val;
479508
int ret;
480509

510+
/*
511+
* Ensure we are finished checking standard hardware events for
512+
* validity before allowing userspace to configure any events.
513+
*/
514+
flush_work(&check_std_events_work);
515+
481516
switch (type) {
482517
case PERF_TYPE_HARDWARE:
483518
if (config >= PERF_COUNT_HW_MAX)
@@ -762,7 +797,7 @@ static inline void pmu_sbi_stop_all(struct riscv_pmu *pmu)
762797
* which may include counters that are not enabled yet.
763798
*/
764799
sbi_ecall(SBI_EXT_PMU, SBI_EXT_PMU_COUNTER_STOP,
765-
0, pmu->cmask, 0, 0, 0, 0);
800+
0, pmu->cmask, SBI_PMU_STOP_FLAG_RESET, 0, 0, 0);
766801
}
767802

768803
static inline void pmu_sbi_stop_hw_ctrs(struct riscv_pmu *pmu)
@@ -1359,6 +1394,9 @@ static int pmu_sbi_device_probe(struct platform_device *pdev)
13591394
if (ret)
13601395
goto out_unregister;
13611396

1397+
/* Asynchronously check which standard events are available */
1398+
schedule_work(&check_std_events_work);
1399+
13621400
return 0;
13631401

13641402
out_unregister:

0 commit comments

Comments
 (0)