2022-02-20 07:09:09

by Atish Kumar Patra

[permalink] [raw]
Subject: [v6 0/9] Improve RISC-V Perf support using SBI PMU and sscofpmf extension

This series adds improved perf support for RISC-V based system using
SBI PMU extension[1] and Sscofpmf extension[2]. The SBI PMU extension allows
the kernel to program the counters for different events and start/stop counters
while the sscofpmf extension allows the counter overflow interrupt and privilege
mode filtering. An hardware platform can leverage SBI PMU extension without
the sscofpmf extension if it supports mcounteren at least. Perf stat will work
but record won't work as sscofpmf & mcountinhibit is required to support that.
A platform can support both features event counting and sampling using perf
tool only if sscofpmf is supported.

This series introduces a platform perf driver instead of a existing arch
specific implementation. The new perf implementation has adopted a modular
approach where most of the generic event handling is done in the core library
while individual PMUs need to only implement necessary features specific to
the PMU. This is easily extensible and any future RISC-V PMU implementation
can leverage this. Currently, SBI PMU driver & legacy PMU driver are implemented
as a part of this series.

The legacy driver tries to reimplement the existing minimal perf under a new
config to maintain backward compatibility. This implementation only allows
monitoring of always running cycle/instruction counters. Moreover, they can
not be started or stopped. In general, this is very limited and not very useful.
That's why, I am not very keen to carry the support into the new driver.
However, I don't want to break perf for any existing hardware platforms.
If everybody agrees that we don't need legacy perf implementation for older
implementation, I will be happy to drop PATCH 4.

This series has been tested in Qemu (RV64 & RV32) and HiFive Unmatched.
Qemu patches[4] and OpenSBI v1.0 is required to test it on Qemu and a dt patch
required in U-Boot[5] for HiFive Unmatched. Qemu changes are not
backward compatible. That means, you can not use perf anymore on older Qemu
versions with latest OpenSBI and/or Kernel. However, newer kernel will
just use legacy pmu driver if old OpenSBI is detected.

The U-Boot patch is just an example that encodes few of the events defined
in fu740 documentation [6] in the DT. We can update the DT to include all the
events defined if required.

This series depends on the ISA extension parsing series[7].

Here is an output of perf stat/report while running perf benchmark with OpenSBI,
Linux kernel and U-Boot patches applied.

HiFive Unmatched:
=================
perf stat -e cycles -e instructions -e L1-icache-load-misses -e branches -e branch-misses \
-e r0000000000000200 -e r0000000000000400 \
-e r0000000000000800 perf bench sched messaging -g 25 -l 15

# Running 'sched/messaging' benchmark:
# 20 sender and receiver processes per group
# 25 groups == 1000 processes run

Total time: 0.826 [sec]

Performance counter stats for 'perf bench sched messaging -g 25 -l 15':

3426710073 cycles (65.92%)
1348772808 instructions #0.39 insn per cycle (75.44%)
0 L1-icache-load-misses (72.28%)
201133996 branches (67.88%)
44663584 branch-misses #22.21% of all branches (35.01%)
248194747 r0000000000000200 (41.94%) --> Integer load instruction retired
156879950 r0000000000000400 (43.58%) --> Integer store instruction retired
6988678 r0000000000000800 (47.91%) --> Atomic memory operation retired

1.931335000 seconds time elapsed

1.100415000 seconds user
3.755176000 seconds sys


QEMU:
=========
Perf stat:
=========

[root@fedora-riscv riscv]# perf stat -e r8000000000000005 -e r8000000000000007 \
-e r8000000000000006 -e r0000000000020002 -e r0000000000020004 -e branch-misses \
-e cache-misses -e dTLB-load-misses -e dTLB-store-misses -e iTLB-load-misses \
-e cycles -e instructions perf bench sched messaging -g 15 -l 10 \
Running with 15*40 (== 600) tasks.
Time: 6.578

Performance counter stats for './hackbench -pipe 15 process':

1,794 r8000000000000005 (52.59%) --> SBI_PMU_FW_SET_TIMER
2,859 r8000000000000007 (60.74%) --> SBI_PMU_FW_IPI_RECVD
4,205 r8000000000000006 (68.71%) --> SBI_PMU_FW_IPI_SENT
0 r0000000000020002 (81.69%)
<not counted> r0000000000020004 (0.00%)
<not counted> branch-misses (0.00%)
<not counted> cache-misses (0.00%)
7,878,328 dTLB-load-misses (15.60%)
680,270 dTLB-store-misses (28.45%)
8,287,931 iTLB-load-misses (39.24%)
20,008,506,675 cycles (48.60%)
21,484,427,932 instructions # 1.07 insn per cycle (56.60%)

1.681344735 seconds time elapsed

0.614460000 seconds user
8.313254000 seconds sys


[root@fedora-riscv ~]# perf stat -e cycles -e instructions -e dTLB-load-misses -e dTLB-store-misses -e iTLB-load-misses \
> perf bench sched messaging -g 1 -l 10
# Running 'sched/messaging' benchmark:
# 20 sender and receiver processes per group
# 1 groups == 40 processes run

Total time: 0.218 [sec]

Performance counter stats for 'perf bench sched messaging -g 1 -l 10':

3,685,401,394 cycles
3,684,529,388 instructions # 1.00 insn per cycle
3,006,042 dTLB-load-misses
258,144 dTLB-store-misses
1,992,860 iTLB-load-misses

0.588717389 seconds time elapsed

0.324009000 seconds user
0.937087000 seconds sys

[root@fedora-riscv ~]# perf record -e cycles -e instructions -e dTLB-load-misses -e dTLB-store-misses \
-e iTLB-load-misses -c 10000 perf bench sched messaging -g 1 -l 10
# Running 'sched/messaging' benchmark:
# 20 sender and receiver processes per group
# 1 groups == 40 processes run

Total time: 2.160 [sec]
[ perf record: Woken up 11 times to write data ]
Warning:
Processed 291769 events and lost 1 chunks!

[root@fedora-riscv ~]# perf report

Available samples
146K cycles ◆
146K instructions ▒
298 dTLB-load-misses ▒
8 dTLB-store-misses ▒
211 iTLB-load-misses

[1] https://github.com/riscv-non-isa/riscv-sbi-doc/blob/master/riscv-sbi.adoc
[2] https://drive.google.com/file/d/171j4jFjIkKdj5LWcExphq4xG_2sihbfd/edit
[3] https://github.com/atishp04/linux/tree/riscv_pmu_v6
[4] https://github.com/atishp04/qemu/tree/riscv_pmu_v5
[5] https://github.com/atishp04/u-boot/tree/hifive_unmatched_dt_pmu
[6] https://sifive.cdn.prismic.io/sifive/de1491e5-077c-461d-9605-e8a0ce57337d_fu740-c000-manual-v1p3.pdf
[7] https://lkml.org/lkml/2022/2/15/1604

Changes from v5->v6:
1. Split the used counters bitmap to firmware and hardware so that we don't
have to generate a hardware only used counter mask during overflow handling.
2. Stopped all the counters during cpu hotplug to restore correct behavior.
3. Addressed all the comments during the v5 review.
4. Rebased on top of the isa extension framework series and 5.17-rc4.

Changes from v4->v5:
1. Fixed few corner case issues in perf interrupt handling.
2. Changed the set_period API so that the caller can compute the initialize
value.
3. Fixed the per cpu interrupt enablement issue.
4. Fixed a bug for the privilege mode filtering.
5. Modified the sbi driver independent of the DT.
6. Removed any DT related modifications.

Changes from v3->v4:
1. Do not proceed overflow handler if event doesn't set for sampling.
2. overflow status register is only read after counters are stopped.
3. Added the PMU DT node for HiFive Unmatched.

Changes from v2->v3:
1. Added interrupt overflow support.
2. Cleaned up legacy driver initialization.
3. Supports perf record now.
4. Added the DT binding and maintainers file.
5. Changed cpu hotplug notifier to be multi-state.
6. OpenSBI doesn't disable cycle/instret counter during boot. Update the
perf code to disable all the counter during the boot.

Changes from v1->v2
1. Implemented the latest SBI PMU extension specification.
2. The core platform driver was changed to operate as a library while only
sbi based PMU is built as a driver. The legacy one is just a fallback if
SBI PMU extension is not available.

Atish Patra (9):
RISC-V: Remove the current perf implementation
RISC-V: Add CSR encodings for all HPMCOUNTERS
RISC-V: Add a perf core library for pmu drivers
RISC-V: Add a simple platform driver for RISC-V legacy perf
RISC-V: Add RISC-V SBI PMU extension definitions
RISC-V: Add perf platform driver based on SBI PMU extension
RISC-V: Add sscofpmf extension support
Documentation: riscv: Remove the old documentation
MAINTAINERS: Add entry for RISC-V PMU drivers

Documentation/riscv/pmu.rst | 255 ---------
MAINTAINERS | 9 +
arch/riscv/Kconfig | 13 -
arch/riscv/include/asm/csr.h | 66 ++-
arch/riscv/include/asm/hwcap.h | 1 +
arch/riscv/include/asm/perf_event.h | 72 ---
arch/riscv/include/asm/sbi.h | 95 ++++
arch/riscv/kernel/Makefile | 1 -
arch/riscv/kernel/cpu.c | 1 +
arch/riscv/kernel/cpufeature.c | 2 +
arch/riscv/kernel/perf_event.c | 485 -----------------
drivers/perf/Kconfig | 30 ++
drivers/perf/Makefile | 3 +
drivers/perf/riscv_pmu.c | 324 ++++++++++++
drivers/perf/riscv_pmu_legacy.c | 142 +++++
drivers/perf/riscv_pmu_sbi.c | 790 ++++++++++++++++++++++++++++
include/linux/cpuhotplug.h | 1 +
include/linux/perf/riscv_pmu.h | 75 +++
18 files changed, 1538 insertions(+), 827 deletions(-)
delete mode 100644 Documentation/riscv/pmu.rst
delete mode 100644 arch/riscv/kernel/perf_event.c
create mode 100644 drivers/perf/riscv_pmu.c
create mode 100644 drivers/perf/riscv_pmu_legacy.c
create mode 100644 drivers/perf/riscv_pmu_sbi.c
create mode 100644 include/linux/perf/riscv_pmu.h

--
2.30.2


2022-02-20 10:02:56

by Atish Kumar Patra

[permalink] [raw]
Subject: [v6 4/9] RISC-V: Add a simple platform driver for RISC-V legacy perf

From: Atish Patra <[email protected]>

The old RISC-V perf implementation allowed counting of only
cycle/instruction counters using perf. Restore that feature by implementing
a simple platform driver under a separate config to provide backward
compatibility. Any existing software stack will continue to work as it is.
However, it provides an easy way out in future where we can remove the
legacy driver.

Reviewed-by: Anup Patel <[email protected]>
Signed-off-by: Atish Patra <[email protected]>
Signed-off-by: Atish Patra <[email protected]>
---
drivers/perf/Kconfig | 10 +++
drivers/perf/Makefile | 1 +
drivers/perf/riscv_pmu_legacy.c | 142 ++++++++++++++++++++++++++++++++
include/linux/perf/riscv_pmu.h | 6 ++
4 files changed, 159 insertions(+)
create mode 100644 drivers/perf/riscv_pmu_legacy.c

diff --git a/drivers/perf/Kconfig b/drivers/perf/Kconfig
index dbc0e3f98be9..386162ad858a 100644
--- a/drivers/perf/Kconfig
+++ b/drivers/perf/Kconfig
@@ -66,6 +66,16 @@ config RISCV_PMU
PMU functionalities in a core library so that different PMU drivers
can reuse it.

+config RISCV_PMU_LEGACY
+ depends on RISCV_PMU
+ bool "RISC-V legacy PMU implementation"
+ default y
+ help
+ Say y if you want to use the legacy CPU performance monitor
+ implementation on RISC-V based systems. This only allows counting
+ of cycle/instruction counter and doesn't support counter overflow,
+ or programmable counters. It will be removed in future.
+
config ARM_PMU_ACPI
depends on ARM_PMU && ACPI
def_bool y
diff --git a/drivers/perf/Makefile b/drivers/perf/Makefile
index 09082dea154b..c3d3268d495b 100644
--- a/drivers/perf/Makefile
+++ b/drivers/perf/Makefile
@@ -11,6 +11,7 @@ obj-$(CONFIG_HISI_PMU) += hisilicon/
obj-$(CONFIG_QCOM_L2_PMU) += qcom_l2_pmu.o
obj-$(CONFIG_QCOM_L3_PMU) += qcom_l3_pmu.o
obj-$(CONFIG_RISCV_PMU) += riscv_pmu.o
+obj-$(CONFIG_RISCV_PMU_LEGACY) += riscv_pmu_legacy.o
obj-$(CONFIG_THUNDERX2_PMU) += thunderx2_pmu.o
obj-$(CONFIG_XGENE_PMU) += xgene_pmu.o
obj-$(CONFIG_ARM_SPE_PMU) += arm_spe_pmu.o
diff --git a/drivers/perf/riscv_pmu_legacy.c b/drivers/perf/riscv_pmu_legacy.c
new file mode 100644
index 000000000000..342778782359
--- /dev/null
+++ b/drivers/perf/riscv_pmu_legacy.c
@@ -0,0 +1,142 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * RISC-V performance counter support.
+ *
+ * Copyright (C) 2021 Western Digital Corporation or its affiliates.
+ *
+ * This implementation is based on old RISC-V perf and ARM perf event code
+ * which are in turn based on sparc64 and x86 code.
+ */
+
+#include <linux/mod_devicetable.h>
+#include <linux/perf/riscv_pmu.h>
+#include <linux/platform_device.h>
+
+#define RISCV_PMU_LEGACY_CYCLE 0
+#define RISCV_PMU_LEGACY_INSTRET 1
+#define RISCV_PMU_LEGACY_NUM_CTR 2
+
+static bool pmu_init_done;
+
+static int pmu_legacy_ctr_get_idx(struct perf_event *event)
+{
+ struct perf_event_attr *attr = &event->attr;
+
+ if (event->attr.type != PERF_TYPE_HARDWARE)
+ return -EOPNOTSUPP;
+ if (attr->config == PERF_COUNT_HW_CPU_CYCLES)
+ return RISCV_PMU_LEGACY_CYCLE;
+ else if (attr->config == PERF_COUNT_HW_INSTRUCTIONS)
+ return RISCV_PMU_LEGACY_INSTRET;
+ else
+ return -EOPNOTSUPP;
+}
+
+/* For legacy config & counter index are same */
+static int pmu_legacy_event_map(struct perf_event *event, u64 *config)
+{
+ return pmu_legacy_ctr_get_idx(event);
+}
+
+static u64 pmu_legacy_read_ctr(struct perf_event *event)
+{
+ struct hw_perf_event *hwc = &event->hw;
+ int idx = hwc->idx;
+ u64 val;
+
+ if (idx == RISCV_PMU_LEGACY_CYCLE) {
+ val = riscv_pmu_ctr_read_csr(CSR_CYCLE);
+ if (IS_ENABLED(CONFIG_32BIT))
+ val = (u64)riscv_pmu_ctr_read_csr(CSR_CYCLEH) << 32 | val;
+ } else if (idx == RISCV_PMU_LEGACY_INSTRET) {
+ val = riscv_pmu_ctr_read_csr(CSR_INSTRET);
+ if (IS_ENABLED(CONFIG_32BIT))
+ val = ((u64)riscv_pmu_ctr_read_csr(CSR_INSTRETH)) << 32 | val;
+ } else
+ return 0;
+
+ return val;
+}
+
+static void pmu_legacy_ctr_start(struct perf_event *event, u64 ival)
+{
+ struct hw_perf_event *hwc = &event->hw;
+ u64 initial_val = pmu_legacy_read_ctr(event);
+
+ /**
+ * The legacy method doesn't really have a start/stop method.
+ * It also can not update the counter with a initial value.
+ * But we still need to set the prev_count so that read() can compute
+ * the delta. Just use the current counter value to set the prev_count.
+ */
+ local64_set(&hwc->prev_count, initial_val);
+}
+
+/**
+ * This is just a simple implementation to allow legacy implementations
+ * compatible with new RISC-V PMU driver framework.
+ * This driver only allows reading two counters i.e CYCLE & INSTRET.
+ * However, it can not start or stop the counter. Thus, it is not very useful
+ * will be removed in future.
+ */
+static void pmu_legacy_init(struct riscv_pmu *pmu)
+{
+ pr_info("Legacy PMU implementation is available\n");
+
+ pmu->num_counters = RISCV_PMU_LEGACY_NUM_CTR;
+ pmu->ctr_start = pmu_legacy_ctr_start;
+ pmu->ctr_stop = NULL;
+ pmu->event_map = pmu_legacy_event_map;
+ pmu->ctr_get_idx = pmu_legacy_ctr_get_idx;
+ pmu->ctr_get_width = NULL;
+ pmu->ctr_clear_idx = NULL;
+ pmu->ctr_read = pmu_legacy_read_ctr;
+
+ perf_pmu_register(&pmu->pmu, "cpu", PERF_TYPE_RAW);
+}
+
+static int pmu_legacy_device_probe(struct platform_device *pdev)
+{
+ struct riscv_pmu *pmu = NULL;
+
+ pmu = riscv_pmu_alloc();
+ if (!pmu)
+ return -ENOMEM;
+ pmu_legacy_init(pmu);
+
+ return 0;
+}
+
+static struct platform_driver pmu_legacy_driver = {
+ .probe = pmu_legacy_device_probe,
+ .driver = {
+ .name = RISCV_PMU_LEGACY_PDEV_NAME,
+ },
+};
+
+static int __init riscv_pmu_legacy_devinit(void)
+{
+ int ret;
+ struct platform_device *pdev;
+
+ if (likely(pmu_init_done))
+ return 0;
+
+ ret = platform_driver_register(&pmu_legacy_driver);
+ if (ret)
+ return ret;
+
+ pdev = platform_device_register_simple(RISCV_PMU_LEGACY_PDEV_NAME, -1, NULL, 0);
+ if (IS_ERR(pdev)) {
+ platform_driver_unregister(&pmu_legacy_driver);
+ return PTR_ERR(pdev);
+ }
+
+ return ret;
+}
+late_initcall(riscv_pmu_legacy_devinit);
+
+void riscv_pmu_legacy_skip_init(void)
+{
+ pmu_init_done = true;
+}
diff --git a/include/linux/perf/riscv_pmu.h b/include/linux/perf/riscv_pmu.h
index 0d8979765d79..9140c491fc54 100644
--- a/include/linux/perf/riscv_pmu.h
+++ b/include/linux/perf/riscv_pmu.h
@@ -22,6 +22,7 @@
#define RISCV_MAX_COUNTERS 64
#define RISCV_OP_UNSUPP (-EOPNOTSUPP)
#define RISCV_PMU_PDEV_NAME "riscv-pmu"
+#define RISCV_PMU_LEGACY_PDEV_NAME "riscv-pmu-legacy"

#define RISCV_PMU_STOP_FLAG_RESET 1

@@ -58,6 +59,11 @@ unsigned long riscv_pmu_ctr_read_csr(unsigned long csr);
int riscv_pmu_event_set_period(struct perf_event *event);
uint64_t riscv_pmu_ctr_get_width_mask(struct perf_event *event);
u64 riscv_pmu_event_update(struct perf_event *event);
+#ifdef CONFIG_RISCV_PMU_LEGACY
+void riscv_pmu_legacy_skip_init(void);
+#else
+static inline void riscv_pmu_legacy_skip_init(void) {};
+#endif
struct riscv_pmu *riscv_pmu_alloc(void);

#endif /* CONFIG_RISCV_PMU */
--
2.30.2

2022-02-20 14:24:02

by Atish Kumar Patra

[permalink] [raw]
Subject: [v6 5/9] RISC-V: Add RISC-V SBI PMU extension definitions

From: Atish Patra <[email protected]>

This patch adds all the definitions defined by the SBI PMU extension.

Reviewed-by: Anup Patel <[email protected]>
Signed-off-by: Atish Patra <[email protected]>
Signed-off-by: Atish Patra <[email protected]>
---
arch/riscv/include/asm/sbi.h | 95 ++++++++++++++++++++++++++++++++++++
1 file changed, 95 insertions(+)

diff --git a/arch/riscv/include/asm/sbi.h b/arch/riscv/include/asm/sbi.h
index d1c37479d828..4a430ae60eaa 100644
--- a/arch/riscv/include/asm/sbi.h
+++ b/arch/riscv/include/asm/sbi.h
@@ -29,6 +29,7 @@ enum sbi_ext_id {
SBI_EXT_RFENCE = 0x52464E43,
SBI_EXT_HSM = 0x48534D,
SBI_EXT_SRST = 0x53525354,
+ SBI_EXT_PMU = 0x504D55,

/* Experimentals extensions must lie within this range */
SBI_EXT_EXPERIMENTAL_START = 0x08000000,
@@ -95,6 +96,98 @@ enum sbi_srst_reset_reason {
SBI_SRST_RESET_REASON_SYS_FAILURE,
};

+enum sbi_ext_pmu_fid {
+ SBI_EXT_PMU_NUM_COUNTERS = 0,
+ SBI_EXT_PMU_COUNTER_GET_INFO,
+ SBI_EXT_PMU_COUNTER_CFG_MATCH,
+ SBI_EXT_PMU_COUNTER_START,
+ SBI_EXT_PMU_COUNTER_STOP,
+ SBI_EXT_PMU_COUNTER_FW_READ,
+};
+
+#define RISCV_PMU_RAW_EVENT_MASK GENMASK_ULL(55, 0)
+#define RISCV_PMU_RAW_EVENT_IDX 0x20000
+
+/** General pmu event codes specified in SBI PMU extension */
+enum sbi_pmu_hw_generic_events_t {
+ SBI_PMU_HW_NO_EVENT = 0,
+ SBI_PMU_HW_CPU_CYCLES = 1,
+ SBI_PMU_HW_INSTRUCTIONS = 2,
+ SBI_PMU_HW_CACHE_REFERENCES = 3,
+ SBI_PMU_HW_CACHE_MISSES = 4,
+ SBI_PMU_HW_BRANCH_INSTRUCTIONS = 5,
+ SBI_PMU_HW_BRANCH_MISSES = 6,
+ SBI_PMU_HW_BUS_CYCLES = 7,
+ SBI_PMU_HW_STALLED_CYCLES_FRONTEND = 8,
+ SBI_PMU_HW_STALLED_CYCLES_BACKEND = 9,
+ SBI_PMU_HW_REF_CPU_CYCLES = 10,
+
+ SBI_PMU_HW_GENERAL_MAX,
+};
+
+/**
+ * Special "firmware" events provided by the firmware, even if the hardware
+ * does not support performance events. These events are encoded as a raw
+ * event type in Linux kernel perf framework.
+ */
+enum sbi_pmu_fw_generic_events_t {
+ SBI_PMU_FW_MISALIGNED_LOAD = 0,
+ SBI_PMU_FW_MISALIGNED_STORE = 1,
+ SBI_PMU_FW_ACCESS_LOAD = 2,
+ SBI_PMU_FW_ACCESS_STORE = 3,
+ SBI_PMU_FW_ILLEGAL_INSN = 4,
+ SBI_PMU_FW_SET_TIMER = 5,
+ SBI_PMU_FW_IPI_SENT = 6,
+ SBI_PMU_FW_IPI_RECVD = 7,
+ SBI_PMU_FW_FENCE_I_SENT = 8,
+ SBI_PMU_FW_FENCE_I_RECVD = 9,
+ SBI_PMU_FW_SFENCE_VMA_SENT = 10,
+ SBI_PMU_FW_SFENCE_VMA_RCVD = 11,
+ SBI_PMU_FW_SFENCE_VMA_ASID_SENT = 12,
+ SBI_PMU_FW_SFENCE_VMA_ASID_RCVD = 13,
+
+ SBI_PMU_FW_HFENCE_GVMA_SENT = 14,
+ SBI_PMU_FW_HFENCE_GVMA_RCVD = 15,
+ SBI_PMU_FW_HFENCE_GVMA_VMID_SENT = 16,
+ SBI_PMU_FW_HFENCE_GVMA_VMID_RCVD = 17,
+
+ SBI_PMU_FW_HFENCE_VVMA_SENT = 18,
+ SBI_PMU_FW_HFENCE_VVMA_RCVD = 19,
+ SBI_PMU_FW_HFENCE_VVMA_ASID_SENT = 20,
+ SBI_PMU_FW_HFENCE_VVMA_ASID_RCVD = 21,
+ SBI_PMU_FW_MAX,
+};
+
+/* SBI PMU event types */
+enum sbi_pmu_event_type {
+ SBI_PMU_EVENT_TYPE_HW = 0x0,
+ SBI_PMU_EVENT_TYPE_CACHE = 0x1,
+ SBI_PMU_EVENT_TYPE_RAW = 0x2,
+ SBI_PMU_EVENT_TYPE_FW = 0xf,
+};
+
+/* SBI PMU event types */
+enum sbi_pmu_ctr_type {
+ SBI_PMU_CTR_TYPE_HW = 0x0,
+ SBI_PMU_CTR_TYPE_FW,
+};
+
+/* Flags defined for config matching function */
+#define SBI_PMU_CFG_FLAG_SKIP_MATCH (1 << 0)
+#define SBI_PMU_CFG_FLAG_CLEAR_VALUE (1 << 1)
+#define SBI_PMU_CFG_FLAG_AUTO_START (1 << 2)
+#define SBI_PMU_CFG_FLAG_SET_VUINH (1 << 3)
+#define SBI_PMU_CFG_FLAG_SET_VSNH (1 << 4)
+#define SBI_PMU_CFG_FLAG_SET_UINH (1 << 5)
+#define SBI_PMU_CFG_FLAG_SET_SINH (1 << 6)
+#define SBI_PMU_CFG_FLAG_SET_MINH (1 << 7)
+
+/* Flags defined for counter start function */
+#define SBI_PMU_START_FLAG_SET_INIT_VALUE (1 << 0)
+
+/* Flags defined for counter stop function */
+#define SBI_PMU_STOP_FLAG_RESET (1 << 0)
+
#define SBI_SPEC_VERSION_DEFAULT 0x1
#define SBI_SPEC_VERSION_MAJOR_SHIFT 24
#define SBI_SPEC_VERSION_MAJOR_MASK 0x7f
@@ -108,6 +201,8 @@ enum sbi_srst_reset_reason {
#define SBI_ERR_DENIED -4
#define SBI_ERR_INVALID_ADDRESS -5
#define SBI_ERR_ALREADY_AVAILABLE -6
+#define SBI_ERR_ALREADY_STARTED -7
+#define SBI_ERR_ALREADY_STOPPED -8

extern unsigned long sbi_spec_version;
struct sbiret {
--
2.30.2

2022-02-20 19:53:30

by Atish Kumar Patra

[permalink] [raw]
Subject: [v6 2/9] RISC-V: Add CSR encodings for all HPMCOUNTERS

From: Atish Patra <[email protected]>

Linux kernel can directly read these counters as the HPMCOUNTERS CSRs are
accessible in S-mode.

Reviewed-by: Anup Patel <[email protected]>
Signed-off-by: Atish Patra <[email protected]>
Signed-off-by: Atish Patra <[email protected]>
---
arch/riscv/include/asm/csr.h | 58 ++++++++++++++++++++++++++++++++++++
1 file changed, 58 insertions(+)

diff --git a/arch/riscv/include/asm/csr.h b/arch/riscv/include/asm/csr.h
index ae711692eec9..ce493df11177 100644
--- a/arch/riscv/include/asm/csr.h
+++ b/arch/riscv/include/asm/csr.h
@@ -150,9 +150,67 @@
#define CSR_CYCLE 0xc00
#define CSR_TIME 0xc01
#define CSR_INSTRET 0xc02
+#define CSR_HPMCOUNTER3 0xc03
+#define CSR_HPMCOUNTER4 0xc04
+#define CSR_HPMCOUNTER5 0xc05
+#define CSR_HPMCOUNTER6 0xc06
+#define CSR_HPMCOUNTER7 0xc07
+#define CSR_HPMCOUNTER8 0xc08
+#define CSR_HPMCOUNTER9 0xc09
+#define CSR_HPMCOUNTER10 0xc0a
+#define CSR_HPMCOUNTER11 0xc0b
+#define CSR_HPMCOUNTER12 0xc0c
+#define CSR_HPMCOUNTER13 0xc0d
+#define CSR_HPMCOUNTER14 0xc0e
+#define CSR_HPMCOUNTER15 0xc0f
+#define CSR_HPMCOUNTER16 0xc10
+#define CSR_HPMCOUNTER17 0xc11
+#define CSR_HPMCOUNTER18 0xc12
+#define CSR_HPMCOUNTER19 0xc13
+#define CSR_HPMCOUNTER20 0xc14
+#define CSR_HPMCOUNTER21 0xc15
+#define CSR_HPMCOUNTER22 0xc16
+#define CSR_HPMCOUNTER23 0xc17
+#define CSR_HPMCOUNTER24 0xc18
+#define CSR_HPMCOUNTER25 0xc19
+#define CSR_HPMCOUNTER26 0xc1a
+#define CSR_HPMCOUNTER27 0xc1b
+#define CSR_HPMCOUNTER28 0xc1c
+#define CSR_HPMCOUNTER29 0xc1d
+#define CSR_HPMCOUNTER30 0xc1e
+#define CSR_HPMCOUNTER31 0xc1f
#define CSR_CYCLEH 0xc80
#define CSR_TIMEH 0xc81
#define CSR_INSTRETH 0xc82
+#define CSR_HPMCOUNTER3H 0xc83
+#define CSR_HPMCOUNTER4H 0xc84
+#define CSR_HPMCOUNTER5H 0xc85
+#define CSR_HPMCOUNTER6H 0xc86
+#define CSR_HPMCOUNTER7H 0xc87
+#define CSR_HPMCOUNTER8H 0xc88
+#define CSR_HPMCOUNTER9H 0xc89
+#define CSR_HPMCOUNTER10H 0xc8a
+#define CSR_HPMCOUNTER11H 0xc8b
+#define CSR_HPMCOUNTER12H 0xc8c
+#define CSR_HPMCOUNTER13H 0xc8d
+#define CSR_HPMCOUNTER14H 0xc8e
+#define CSR_HPMCOUNTER15H 0xc8f
+#define CSR_HPMCOUNTER16H 0xc90
+#define CSR_HPMCOUNTER17H 0xc91
+#define CSR_HPMCOUNTER18H 0xc92
+#define CSR_HPMCOUNTER19H 0xc93
+#define CSR_HPMCOUNTER20H 0xc94
+#define CSR_HPMCOUNTER21H 0xc95
+#define CSR_HPMCOUNTER22H 0xc96
+#define CSR_HPMCOUNTER23H 0xc97
+#define CSR_HPMCOUNTER24H 0xc98
+#define CSR_HPMCOUNTER25H 0xc99
+#define CSR_HPMCOUNTER26H 0xc9a
+#define CSR_HPMCOUNTER27H 0xc9b
+#define CSR_HPMCOUNTER28H 0xc9c
+#define CSR_HPMCOUNTER29H 0xc9d
+#define CSR_HPMCOUNTER30H 0xc9e
+#define CSR_HPMCOUNTER31H 0xc9f

#define CSR_SSTATUS 0x100
#define CSR_SIE 0x104
--
2.30.2

2022-03-12 13:31:24

by Nikita Shubin

[permalink] [raw]
Subject: Re: [v6 0/9] Improve RISC-V Perf support using SBI PMU and sscofpmf extension

Hello Atish, thank you for your patches.

Tested you series on the top of v5.17-rc7, both on Qemu and HiFive
Unmatched.

Got similar results, everything is working fine.

HiFive Unmatched:
=================

perf stat -e cycles -e instructions -e L1-icache-load-misses -e
branches -e branch-misses \ -e r0000000000000200 -e r0000000000000400 \
-e r0000000000000800 perf bench sched messaging -g 25 -l 15

# Running 'sched/messaging' benchmark:
# 20 sender and receiver processes per group
# 25 groups == 1000 processes run

Total time: 0.780 [sec]

Performance counter stats for 'perf bench sched messaging -g 25 -l 15':

3046119040 cycles
(68.35%) 1117366934 instructions
# 0.37 insn per cycle (77.53%) 0
L1-icache-load-misses
(72.86%) 149748628 branches
(69.44%) 40937064 branch-misses
# 27.34% of all branches (35.17%) 175959749
r0000000000000200
(43.85%) 117885368 r0000000000000400
(45.45%) 6396494 r0000000000000800
(49.92%)

1.714602000 seconds time elapsed

1.091126000 seconds user
3.391938000 seconds sys

Series was tested on the top of Provide a fraemework for RISC-V ISA
extensions:

https://patchwork.kernel.org/project/linux-riscv/list/?series=616887

with Mario "Introduce pmu-events support for HiFive Unmatched" series
applied:

https://patchwork.kernel.org/project/linux-riscv/list/?series=581071

With "riscv: Fix fill_callchain return value" patch - i was even able
to produce some flame graphs with "perf record".

"perf list pmu" gives exact u740 mapped events, so

Tested-by: Nikita Shubin <[email protected]>

To all mentioned series.

Yours,
Nikita Shubin

> This series adds improved perf support for RISC-V based system using
> SBI PMU extension[1] and Sscofpmf extension[2]. The SBI PMU extension
> allows the kernel to program the counters for different events and
> start/stop counters while the sscofpmf extension allows the counter
> overflow interrupt and privilege mode filtering. An hardware platform
> can leverage SBI PMU extension without the sscofpmf extension if it
> supports mcounteren at least. Perf stat will work but record won't
> work as sscofpmf & mcountinhibit is required to support that. A
> platform can support both features event counting and sampling using
> perf tool only if sscofpmf is supported.
>
> This series introduces a platform perf driver instead of a existing
> arch specific implementation. The new perf implementation has adopted
> a modular approach where most of the generic event handling is done
> in the core library while individual PMUs need to only implement
> necessary features specific to the PMU. This is easily extensible and
> any future RISC-V PMU implementation can leverage this. Currently,
> SBI PMU driver & legacy PMU driver are implemented as a part of this
> series.
>
> The legacy driver tries to reimplement the existing minimal perf
> under a new config to maintain backward compatibility. This
> implementation only allows monitoring of always running
> cycle/instruction counters. Moreover, they can not be started or
> stopped. In general, this is very limited and not very useful. That's
> why, I am not very keen to carry the support into the new driver.
> However, I don't want to break perf for any existing hardware
> platforms. If everybody agrees that we don't need legacy perf
> implementation for older implementation, I will be happy to drop
> PATCH 4.
>
> This series has been tested in Qemu (RV64 & RV32) and HiFive
> Unmatched. Qemu patches[4] and OpenSBI v1.0 is required to test it on
> Qemu and a dt patch required in U-Boot[5] for HiFive Unmatched. Qemu
> changes are not backward compatible. That means, you can not use perf
> anymore on older Qemu versions with latest OpenSBI and/or Kernel.
> However, newer kernel will just use legacy pmu driver if old OpenSBI
> is detected.
>
> The U-Boot patch is just an example that encodes few of the events
> defined in fu740 documentation [6] in the DT. We can update the DT to
> include all the events defined if required.
>
> This series depends on the ISA extension parsing series[7].
>
> Here is an output of perf stat/report while running perf benchmark
> with OpenSBI, Linux kernel and U-Boot patches applied.
>
> HiFive Unmatched:
> =================
> perf stat -e cycles -e instructions -e L1-icache-load-misses -e
> branches -e branch-misses \ -e r0000000000000200 -e r0000000000000400
> \ -e r0000000000000800 perf bench sched messaging -g 25 -l 15
>
> # Running 'sched/messaging' benchmark:
> # 20 sender and receiver processes per group
> # 25 groups == 1000 processes run
>
> Total time: 0.826 [sec]
>
> Performance counter stats for 'perf bench sched messaging -g 25 -l
> 15':
>
> 3426710073 cycles (65.92%)
> 1348772808 instructions #0.39 insn per cycle
> (75.44%) 0 L1-icache-load-misses (72.28%)
> 201133996 branches (67.88%)
> 44663584 branch-misses #22.21% of all branches
> (35.01%) 248194747 r0000000000000200 (41.94%) --> Integer
> load instruction retired 156879950 r0000000000000400
> (43.58%) --> Integer store instruction retired 6988678
> r0000000000000800 (47.91%) --> Atomic memory operation retired
>
> 1.931335000 seconds time elapsed
>
> 1.100415000 seconds user
> 3.755176000 seconds sys
>
>
> QEMU:
> =========
> Perf stat:
> =========
>
> [root@fedora-riscv riscv]# perf stat -e r8000000000000005 -e
> r8000000000000007 \ -e r8000000000000006 -e r0000000000020002 -e
> r0000000000020004 -e branch-misses \ -e cache-misses -e
> dTLB-load-misses -e dTLB-store-misses -e iTLB-load-misses \ -e cycles
> -e instructions perf bench sched messaging -g 15 -l 10 \ Running with
> 15*40 (== 600) tasks. Time: 6.578
>
> Performance counter stats for './hackbench -pipe 15 process':
>
> 1,794 r8000000000000005 (52.59%) -->
> SBI_PMU_FW_SET_TIMER 2,859 r8000000000000007 (60.74%) -->
> SBI_PMU_FW_IPI_RECVD 4,205 r8000000000000006 (68.71%) -->
> SBI_PMU_FW_IPI_SENT 0 r0000000000020002 (81.69%)
> <not counted> r0000000000020004 (0.00%)
> <not counted> branch-misses (0.00%)
> <not counted> cache-misses (0.00%)
> 7,878,328 dTLB-load-misses (15.60%)
> 680,270 dTLB-store-misses (28.45%)
> 8,287,931 iTLB-load-misses (39.24%)
> 20,008,506,675 cycles (48.60%)
> 21,484,427,932 instructions # 1.07 insn per cycle (56.60%)
>
> 1.681344735 seconds time elapsed
>
> 0.614460000 seconds user
> 8.313254000 seconds sys
>
>
> [root@fedora-riscv ~]# perf stat -e cycles -e instructions -e
> dTLB-load-misses -e dTLB-store-misses -e iTLB-load-misses \
> > perf bench sched messaging -g 1 -l 10
> # Running 'sched/messaging' benchmark:
> # 20 sender and receiver processes per group
> # 1 groups == 40 processes run
>
> Total time: 0.218 [sec]
>
> Performance counter stats for 'perf bench sched messaging -g 1 -l
> 10':
>
> 3,685,401,394 cycles
> 3,684,529,388 instructions # 1.00 insn per
> cycle 3,006,042 dTLB-load-misses
> 258,144 dTLB-store-misses
> 1,992,860 iTLB-load-misses
>
>
> 0.588717389 seconds time elapsed
>
> 0.324009000 seconds user
> 0.937087000 seconds sys
>
> [root@fedora-riscv ~]# perf record -e cycles -e instructions -e
> dTLB-load-misses -e dTLB-store-misses \ -e iTLB-load-misses -c 10000
> perf bench sched messaging -g 1 -l 10 # Running 'sched/messaging'
> benchmark: # 20 sender and receiver processes per group
> # 1 groups == 40 processes run
>
> Total time: 2.160 [sec]
> [ perf record: Woken up 11 times to write data ]
> Warning:
> Processed 291769 events and lost 1 chunks!
>
> [root@fedora-riscv ~]# perf report
>
> Available samples
> 146K cycles
> ◆ 146K instructions
> ▒ 298 dTLB-load-misses
> ▒ 8 dTLB-store-misses
> ▒ 211 iTLB-load-misses
>
> [1]
> https://github.com/riscv-non-isa/riscv-sbi-doc/blob/master/riscv-sbi.adoc
> [2]
> https://drive.google.com/file/d/171j4jFjIkKdj5LWcExphq4xG_2sihbfd/edit
> [3] https://github.com/atishp04/linux/tree/riscv_pmu_v6 [4]
> https://github.com/atishp04/qemu/tree/riscv_pmu_v5 [5]
> https://github.com/atishp04/u-boot/tree/hifive_unmatched_dt_pmu [6]
> https://sifive.cdn.prismic.io/sifive/de1491e5-077c-461d-9605-e8a0ce57337d_fu740-c000-manual-v1p3.pdf
> [7] https://lkml.org/lkml/2022/2/15/1604
>
> Changes from v5->v6:
> 1. Split the used counters bitmap to firmware and hardware so that we
> don't have to generate a hardware only used counter mask during
> overflow handling. 2. Stopped all the counters during cpu hotplug to
> restore correct behavior. 3. Addressed all the comments during the v5
> review. 4. Rebased on top of the isa extension framework series and
> 5.17-rc4.
>
> Changes from v4->v5:
> 1. Fixed few corner case issues in perf interrupt handling.
> 2. Changed the set_period API so that the caller can compute the
> initialize value.
> 3. Fixed the per cpu interrupt enablement issue.
> 4. Fixed a bug for the privilege mode filtering.
> 5. Modified the sbi driver independent of the DT.
> 6. Removed any DT related modifications.
>
> Changes from v3->v4:
> 1. Do not proceed overflow handler if event doesn't set for sampling.
> 2. overflow status register is only read after counters are stopped.
> 3. Added the PMU DT node for HiFive Unmatched.
>
> Changes from v2->v3:
> 1. Added interrupt overflow support.
> 2. Cleaned up legacy driver initialization.
> 3. Supports perf record now.
> 4. Added the DT binding and maintainers file.
> 5. Changed cpu hotplug notifier to be multi-state.
> 6. OpenSBI doesn't disable cycle/instret counter during boot. Update
> the perf code to disable all the counter during the boot.
>
> Changes from v1->v2
> 1. Implemented the latest SBI PMU extension specification.
> 2. The core platform driver was changed to operate as a library while
> only sbi based PMU is built as a driver. The legacy one is just a
> fallback if SBI PMU extension is not available.
>
> Atish Patra (9):
> RISC-V: Remove the current perf implementation
> RISC-V: Add CSR encodings for all HPMCOUNTERS
> RISC-V: Add a perf core library for pmu drivers
> RISC-V: Add a simple platform driver for RISC-V legacy perf
> RISC-V: Add RISC-V SBI PMU extension definitions
> RISC-V: Add perf platform driver based on SBI PMU extension
> RISC-V: Add sscofpmf extension support
> Documentation: riscv: Remove the old documentation
> MAINTAINERS: Add entry for RISC-V PMU drivers
>
> Documentation/riscv/pmu.rst | 255 ---------
> MAINTAINERS | 9 +
> arch/riscv/Kconfig | 13 -
> arch/riscv/include/asm/csr.h | 66 ++-
> arch/riscv/include/asm/hwcap.h | 1 +
> arch/riscv/include/asm/perf_event.h | 72 ---
> arch/riscv/include/asm/sbi.h | 95 ++++
> arch/riscv/kernel/Makefile | 1 -
> arch/riscv/kernel/cpu.c | 1 +
> arch/riscv/kernel/cpufeature.c | 2 +
> arch/riscv/kernel/perf_event.c | 485 -----------------
> drivers/perf/Kconfig | 30 ++
> drivers/perf/Makefile | 3 +
> drivers/perf/riscv_pmu.c | 324 ++++++++++++
> drivers/perf/riscv_pmu_legacy.c | 142 +++++
> drivers/perf/riscv_pmu_sbi.c | 790 ++++++++++++++++++++++++++++
> include/linux/cpuhotplug.h | 1 +
> include/linux/perf/riscv_pmu.h | 75 +++
> 18 files changed, 1538 insertions(+), 827 deletions(-)
> delete mode 100644 Documentation/riscv/pmu.rst
> delete mode 100644 arch/riscv/kernel/perf_event.c
> create mode 100644 drivers/perf/riscv_pmu.c
> create mode 100644 drivers/perf/riscv_pmu_legacy.c
> create mode 100644 drivers/perf/riscv_pmu_sbi.c
> create mode 100644 include/linux/perf/riscv_pmu.h
>
> --
> 2.30.2
>
>
> _______________________________________________
> linux-riscv mailing list
> [email protected]
> http://lists.infradead.org/mailman/listinfo/linux-riscv

2022-03-22 00:34:17

by Palmer Dabbelt

[permalink] [raw]
Subject: Re: [v6 0/9] Improve RISC-V Perf support using SBI PMU and sscofpmf extension

On Fri, 18 Feb 2022 16:46:51 PST (-0800), Atish Patra wrote:
> This series adds improved perf support for RISC-V based system using
> SBI PMU extension[1] and Sscofpmf extension[2]. The SBI PMU extension allows
> the kernel to program the counters for different events and start/stop counters
> while the sscofpmf extension allows the counter overflow interrupt and privilege
> mode filtering. An hardware platform can leverage SBI PMU extension without
> the sscofpmf extension if it supports mcounteren at least. Perf stat will work
> but record won't work as sscofpmf & mcountinhibit is required to support that.
> A platform can support both features event counting and sampling using perf
> tool only if sscofpmf is supported.
>
> This series introduces a platform perf driver instead of a existing arch
> specific implementation. The new perf implementation has adopted a modular
> approach where most of the generic event handling is done in the core library
> while individual PMUs need to only implement necessary features specific to
> the PMU. This is easily extensible and any future RISC-V PMU implementation
> can leverage this. Currently, SBI PMU driver & legacy PMU driver are implemented
> as a part of this series.
>
> The legacy driver tries to reimplement the existing minimal perf under a new
> config to maintain backward compatibility. This implementation only allows
> monitoring of always running cycle/instruction counters. Moreover, they can
> not be started or stopped. In general, this is very limited and not very useful.
> That's why, I am not very keen to carry the support into the new driver.
> However, I don't want to break perf for any existing hardware platforms.
> If everybody agrees that we don't need legacy perf implementation for older
> implementation, I will be happy to drop PATCH 4.
>
> This series has been tested in Qemu (RV64 & RV32) and HiFive Unmatched.
> Qemu patches[4] and OpenSBI v1.0 is required to test it on Qemu and a dt patch
> required in U-Boot[5] for HiFive Unmatched. Qemu changes are not
> backward compatible. That means, you can not use perf anymore on older Qemu
> versions with latest OpenSBI and/or Kernel. However, newer kernel will
> just use legacy pmu driver if old OpenSBI is detected.
>
> The U-Boot patch is just an example that encodes few of the events defined
> in fu740 documentation [6] in the DT. We can update the DT to include all the
> events defined if required.
>
> This series depends on the ISA extension parsing series[7].
>
> Here is an output of perf stat/report while running perf benchmark with OpenSBI,
> Linux kernel and U-Boot patches applied.
>
> HiFive Unmatched:
> =================
> perf stat -e cycles -e instructions -e L1-icache-load-misses -e branches -e branch-misses \
> -e r0000000000000200 -e r0000000000000400 \
> -e r0000000000000800 perf bench sched messaging -g 25 -l 15
>
> # Running 'sched/messaging' benchmark:
> # 20 sender and receiver processes per group
> # 25 groups == 1000 processes run
>
> Total time: 0.826 [sec]
>
> Performance counter stats for 'perf bench sched messaging -g 25 -l 15':
>
> 3426710073 cycles (65.92%)
> 1348772808 instructions #0.39 insn per cycle (75.44%)
> 0 L1-icache-load-misses (72.28%)
> 201133996 branches (67.88%)
> 44663584 branch-misses #22.21% of all branches (35.01%)
> 248194747 r0000000000000200 (41.94%) --> Integer load instruction retired
> 156879950 r0000000000000400 (43.58%) --> Integer store instruction retired
> 6988678 r0000000000000800 (47.91%) --> Atomic memory operation retired
>
> 1.931335000 seconds time elapsed
>
> 1.100415000 seconds user
> 3.755176000 seconds sys
>
>
> QEMU:
> =========
> Perf stat:
> =========
>
> [root@fedora-riscv riscv]# perf stat -e r8000000000000005 -e r8000000000000007 \
> -e r8000000000000006 -e r0000000000020002 -e r0000000000020004 -e branch-misses \
> -e cache-misses -e dTLB-load-misses -e dTLB-store-misses -e iTLB-load-misses \
> -e cycles -e instructions perf bench sched messaging -g 15 -l 10 \
> Running with 15*40 (== 600) tasks.
> Time: 6.578
>
> Performance counter stats for './hackbench -pipe 15 process':
>
> 1,794 r8000000000000005 (52.59%) --> SBI_PMU_FW_SET_TIMER
> 2,859 r8000000000000007 (60.74%) --> SBI_PMU_FW_IPI_RECVD
> 4,205 r8000000000000006 (68.71%) --> SBI_PMU_FW_IPI_SENT
> 0 r0000000000020002 (81.69%)
> <not counted> r0000000000020004 (0.00%)
> <not counted> branch-misses (0.00%)
> <not counted> cache-misses (0.00%)
> 7,878,328 dTLB-load-misses (15.60%)
> 680,270 dTLB-store-misses (28.45%)
> 8,287,931 iTLB-load-misses (39.24%)
> 20,008,506,675 cycles (48.60%)
> 21,484,427,932 instructions # 1.07 insn per cycle (56.60%)
>
> 1.681344735 seconds time elapsed
>
> 0.614460000 seconds user
> 8.313254000 seconds sys
>
>
> [root@fedora-riscv ~]# perf stat -e cycles -e instructions -e dTLB-load-misses -e dTLB-store-misses -e iTLB-load-misses \
>> perf bench sched messaging -g 1 -l 10
> # Running 'sched/messaging' benchmark:
> # 20 sender and receiver processes per group
> # 1 groups == 40 processes run
>
> Total time: 0.218 [sec]
>
> Performance counter stats for 'perf bench sched messaging -g 1 -l 10':
>
> 3,685,401,394 cycles
> 3,684,529,388 instructions # 1.00 insn per cycle
> 3,006,042 dTLB-load-misses
> 258,144 dTLB-store-misses
> 1,992,860 iTLB-load-misses
>
> 0.588717389 seconds time elapsed
>
> 0.324009000 seconds user
> 0.937087000 seconds sys
>
> [root@fedora-riscv ~]# perf record -e cycles -e instructions -e dTLB-load-misses -e dTLB-store-misses \
> -e iTLB-load-misses -c 10000 perf bench sched messaging -g 1 -l 10
> # Running 'sched/messaging' benchmark:
> # 20 sender and receiver processes per group
> # 1 groups == 40 processes run
>
> Total time: 2.160 [sec]
> [ perf record: Woken up 11 times to write data ]
> Warning:
> Processed 291769 events and lost 1 chunks!
>
> [root@fedora-riscv ~]# perf report
>
> Available samples
> 146K cycles ◆
> 146K instructions ▒
> 298 dTLB-load-misses ▒
> 8 dTLB-store-misses ▒
> 211 iTLB-load-misses
>
> [1] https://github.com/riscv-non-isa/riscv-sbi-doc/blob/master/riscv-sbi.adoc
> [2] https://drive.google.com/file/d/171j4jFjIkKdj5LWcExphq4xG_2sihbfd/edit
> [3] https://github.com/atishp04/linux/tree/riscv_pmu_v6
> [4] https://github.com/atishp04/qemu/tree/riscv_pmu_v5
> [5] https://github.com/atishp04/u-boot/tree/hifive_unmatched_dt_pmu
> [6] https://sifive.cdn.prismic.io/sifive/de1491e5-077c-461d-9605-e8a0ce57337d_fu740-c000-manual-v1p3.pdf
> [7] https://lkml.org/lkml/2022/2/15/1604
>
> Changes from v5->v6:
> 1. Split the used counters bitmap to firmware and hardware so that we don't
> have to generate a hardware only used counter mask during overflow handling.
> 2. Stopped all the counters during cpu hotplug to restore correct behavior.
> 3. Addressed all the comments during the v5 review.
> 4. Rebased on top of the isa extension framework series and 5.17-rc4.
>
> Changes from v4->v5:
> 1. Fixed few corner case issues in perf interrupt handling.
> 2. Changed the set_period API so that the caller can compute the initialize
> value.
> 3. Fixed the per cpu interrupt enablement issue.
> 4. Fixed a bug for the privilege mode filtering.
> 5. Modified the sbi driver independent of the DT.
> 6. Removed any DT related modifications.
>
> Changes from v3->v4:
> 1. Do not proceed overflow handler if event doesn't set for sampling.
> 2. overflow status register is only read after counters are stopped.
> 3. Added the PMU DT node for HiFive Unmatched.
>
> Changes from v2->v3:
> 1. Added interrupt overflow support.
> 2. Cleaned up legacy driver initialization.
> 3. Supports perf record now.
> 4. Added the DT binding and maintainers file.
> 5. Changed cpu hotplug notifier to be multi-state.
> 6. OpenSBI doesn't disable cycle/instret counter during boot. Update the
> perf code to disable all the counter during the boot.
>
> Changes from v1->v2
> 1. Implemented the latest SBI PMU extension specification.
> 2. The core platform driver was changed to operate as a library while only
> sbi based PMU is built as a driver. The legacy one is just a fallback if
> SBI PMU extension is not available.
>
> Atish Patra (9):
> RISC-V: Remove the current perf implementation
> RISC-V: Add CSR encodings for all HPMCOUNTERS
> RISC-V: Add a perf core library for pmu drivers
> RISC-V: Add a simple platform driver for RISC-V legacy perf
> RISC-V: Add RISC-V SBI PMU extension definitions
> RISC-V: Add perf platform driver based on SBI PMU extension
> RISC-V: Add sscofpmf extension support
> Documentation: riscv: Remove the old documentation
> MAINTAINERS: Add entry for RISC-V PMU drivers
>
> Documentation/riscv/pmu.rst | 255 ---------
> MAINTAINERS | 9 +
> arch/riscv/Kconfig | 13 -
> arch/riscv/include/asm/csr.h | 66 ++-
> arch/riscv/include/asm/hwcap.h | 1 +
> arch/riscv/include/asm/perf_event.h | 72 ---
> arch/riscv/include/asm/sbi.h | 95 ++++
> arch/riscv/kernel/Makefile | 1 -
> arch/riscv/kernel/cpu.c | 1 +
> arch/riscv/kernel/cpufeature.c | 2 +
> arch/riscv/kernel/perf_event.c | 485 -----------------
> drivers/perf/Kconfig | 30 ++
> drivers/perf/Makefile | 3 +
> drivers/perf/riscv_pmu.c | 324 ++++++++++++
> drivers/perf/riscv_pmu_legacy.c | 142 +++++
> drivers/perf/riscv_pmu_sbi.c | 790 ++++++++++++++++++++++++++++
> include/linux/cpuhotplug.h | 1 +
> include/linux/perf/riscv_pmu.h | 75 +++
> 18 files changed, 1538 insertions(+), 827 deletions(-)
> delete mode 100644 Documentation/riscv/pmu.rst
> delete mode 100644 arch/riscv/kernel/perf_event.c
> create mode 100644 drivers/perf/riscv_pmu.c
> create mode 100644 drivers/perf/riscv_pmu_legacy.c
> create mode 100644 drivers/perf/riscv_pmu_sbi.c
> create mode 100644 include/linux/perf/riscv_pmu.h

Thanks, this is on for-next.