History

drivers/perf: riscv: Export PMU event info function

The event mapping function can be used in event info function to find out the corresponding SBI PMU event encoding during the get_event_info function as well. Refactor and export it so that it can be invoked from kvm and internal driver.

Atish Patra committed 1 year ago

Commit 880fcc31 parent adffbd02 files · +68 −55Browse files

Unified · Split

2 files
  1. drivers/perf/riscv_pmu_sbi.c +67 −55
  2. include/linux/perf/riscv_pmu.h +1 −0
drivers/perf/riscv_pmu_sbi.c+67−55
@@ -100,6 +100,7 @@ static unsigned int riscv_pmu_irq; · 99 unmodified lines
100100 /* Cache the available counters in a bitmask */
101101 static unsigned long cmask;
102102
103+static int pmu_event_find_cache(u64 config);
103104 struct sbi_pmu_event_data {
104105 union {
105106 union {
@@ -412,6 +413,71 @@ static bool pmu_sbi_ctr_is_fw(int cidx) · 306 unmodified lines
412413 return (info->type == SBI_PMU_CTR_TYPE_FW) ? true : false;
413414 }
414415
416+int riscv_pmu_get_event_info(u32 type, u64 config, u64 *econfig)
417+{
418+ int ret = -ENOENT;
419+
420+ switch (type) {
421+ case PERF_TYPE_HARDWARE:
422+ if (config >= PERF_COUNT_HW_MAX)
423+ return -EINVAL;
424+ ret = pmu_hw_event_map[config].event_idx;
425+ break;
426+ case PERF_TYPE_HW_CACHE:
427+ ret = pmu_event_find_cache(config);
428+ break;
429+ case PERF_TYPE_RAW:
430+ /*
431+ * As per SBI v0.3 specification,
432+ * -- the upper 16 bits must be unused for a hardware raw event.
433+ * As per SBI v2.0 specification,
434+ * -- the upper 8 bits must be unused for a hardware raw event.
435+ * Bits 63:62 are used to distinguish between raw events
436+ * 00 - Hardware raw event
437+ * 10 - SBI firmware events
438+ * 11 - Risc-V platform specific firmware event
439+ */
440+ switch (config >> 62) {
441+ case 0:
442+ if (sbi_v3_available) {
443+ /* Return error any bits [56-63] is set as it is not allowed by the spec */
444+ if (!(config & ~RISCV_PMU_RAW_EVENT_V2_MASK)) {
445+ if (econfig)
446+ *econfig = config & RISCV_PMU_RAW_EVENT_V2_MASK;
447+ ret = RISCV_PMU_RAW_EVENT_V2_IDX;
448+ }
449+ /* Return error any bits [48-63] is set as it is not allowed by the spec */
450+ } else if (!(config & ~RISCV_PMU_RAW_EVENT_MASK)) {
451+ if (econfig)
452+ *econfig = config & RISCV_PMU_RAW_EVENT_MASK;
453+ ret = RISCV_PMU_RAW_EVENT_IDX;
454+ }
455+ break;
456+ case 2:
457+ ret = (config & 0xFFFF) | (SBI_PMU_EVENT_TYPE_FW << 16);
458+ break;
459+ case 3:
460+ /*
461+ * For Risc-V platform specific firmware events
462+ * Event code - 0xFFFF
463+ * Event data - raw event encoding
464+ */
465+ ret = SBI_PMU_EVENT_TYPE_FW << 16 | RISCV_PLAT_FW_EVENT;
466+ if (econfig)
467+ *econfig = config & RISCV_PMU_PLAT_FW_EVENT_MASK;
468+ break;
469+ default:
470+ break;
471+ }
472+ break;
473+ default:
474+ break;
475+ }
476+
477+ return ret;
478+}
479+EXPORT_SYMBOL_GPL(riscv_pmu_get_event_info);
480+
415481 /*
416482 * Returns the counter width of a programmable counter and number of hardware
417483 * counters. As we don't support heterogeneous CPUs yet, it is okay to just
@@ -577,7 +643,6 @@ static int pmu_sbi_event_map(struct perf_event *event, u64 *econfig) · 159 unmodified lines
577643 {
578644 u32 type = event->attr.type;
579645 u64 config = event->attr.config;
580− int ret = -ENOENT;
581646
582647 /*
583648 * Ensure we are finished checking standard hardware events for
@@ -585,60 +650,7 @@ static int pmu_sbi_event_map(struct perf_event *event, u64 *econfig) · 1 unmodified line
585650 */
586651 flush_work(&check_std_events_work);
587652
588− switch (type) {
589− case PERF_TYPE_HARDWARE:
590− if (config >= PERF_COUNT_HW_MAX)
591− return -EINVAL;
592− ret = pmu_hw_event_map[event->attr.config].event_idx;
593− break;
594− case PERF_TYPE_HW_CACHE:
595− ret = pmu_event_find_cache(config);
596− break;
597− case PERF_TYPE_RAW:
598− /*
599− * As per SBI v0.3 specification,
600− * -- the upper 16 bits must be unused for a hardware raw event.
601− * As per SBI v2.0 specification,
602− * -- the upper 8 bits must be unused for a hardware raw event.
603− * Bits 63:62 are used to distinguish between raw events
604− * 00 - Hardware raw event
605− * 10 - SBI firmware events
606− * 11 - Risc-V platform specific firmware event
607− */
608−
609− switch (config >> 62) {
610− case 0:
611− if (sbi_v3_available) {
612− if (!(config & ~RISCV_PMU_RAW_EVENT_V2_MASK)) {
613− *econfig = config & RISCV_PMU_RAW_EVENT_V2_MASK;
614− ret = RISCV_PMU_RAW_EVENT_V2_IDX;
615− }
616− } else if (!(config & ~RISCV_PMU_RAW_EVENT_MASK)) {
617− *econfig = config & RISCV_PMU_RAW_EVENT_MASK;
618− ret = RISCV_PMU_RAW_EVENT_IDX;
619− }
620− break;
621− case 2:
622− ret = (config & 0xFFFF) | (SBI_PMU_EVENT_TYPE_FW << 16);
623− break;
624− case 3:
625− /*
626− * For Risc-V platform specific firmware events
627− * Event code - 0xFFFF
628− * Event data - raw event encoding
629− */
630− ret = SBI_PMU_EVENT_TYPE_FW << 16 | RISCV_PLAT_FW_EVENT;
631− *econfig = config & RISCV_PMU_PLAT_FW_EVENT_MASK;
632− break;
633− default:
634− break;
635− }
636− break;
637− default:
638− break;
639− }
640−
641− return ret;
653+ return riscv_pmu_get_event_info(type, config, econfig);
642654 }
643655
644656 static void pmu_sbi_snapshot_free(struct riscv_pmu *pmu)
include/linux/perf/riscv_pmu.h+1−0
@@ -89,6 +89,7 @@ static inline void riscv_pmu_legacy_skip_init(void) {}; · 88 unmodified lines
8989 struct riscv_pmu *riscv_pmu_alloc(void);
9090 #ifdef CONFIG_RISCV_PMU_SBI
9191 int riscv_pmu_get_hpm_info(u32 *hw_ctr_width, u32 *num_hw_ctr);
92+int riscv_pmu_get_event_info(u32 type, u64 config, u64 *econfig);
9293 #endif
9394
9495 #endif /* CONFIG_RISCV_PMU */

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t