* [RFC PATCH 0/6] Support raw event and DT for perf on RISC-V @ 2020-06-29 3:19 Zong Li 2020-06-29 3:19 ` [RFC PATCH 1/6] dt-bindings: riscv: Add YAML documentation for PMU Zong Li ` (7 more replies) 0 siblings, 8 replies; 38+ messages in thread From: Zong Li @ 2020-06-29 3:19 UTC (permalink / raw) To: palmer, paul.walmsley, linux-riscv, linux-kernel; +Cc: Zong Li This patch set adds raw event support on RISC-V. In addition, we introduce the DT mechanism to make our perf more generic and common. Currently, we set the hardware events by writing the mhpmeventN CSRs, it would raise an illegal instruction exception and trap into m-mode to emulate event selector CSRs access. It doesn't make sense because we shouldn't write the m-mode CSRs in s-mode. Ideally, we should set event selector through standard SBI call or the shadow CSRs of s-mode. We have prepared a proposal of a new SBI extension, called "PMU SBI extension", but we also discussing the feasibility of accessing these PMU CSRs on s-mode at the same time, such as delegation mechanism, so I was wondering if we could use SBI calls first and make the PMU SBI extension as legacy when s-mode access mechanism is accepted by Foundation? or keep the current situation to see what would happen in the future. This patch set also introduces the DT mechanism, we don't want to add too much platform-dependency code in perf like other architectures, so we put the mapping of generic hardware events to DT, then we can easy to transfer generic hardware events to vendor's own hardware events without any platfrom-dependency stuff in our perf. Zong Li (6): dt-bindings: riscv: Add YAML documentation for PMU riscv: dts: sifive: Add DT support for PMU riscv: add definition of hpmcounter CSRs riscv: perf: Add raw event support riscv: perf: introduce DT mechanism riscv: remove PMU menu of Kconfig .../devicetree/bindings/riscv/pmu.yaml | 59 +++ arch/riscv/Kconfig | 13 - arch/riscv/boot/dts/sifive/fu540-c000.dtsi | 13 + arch/riscv/include/asm/csr.h | 58 +++ arch/riscv/include/asm/perf_event.h | 100 ++-- arch/riscv/kernel/Makefile | 2 +- arch/riscv/kernel/perf_event.c | 471 +++++++++++------- 7 files changed, 471 insertions(+), 245 deletions(-) create mode 100644 Documentation/devicetree/bindings/riscv/pmu.yaml -- 2.27.0 _______________________________________________ linux-riscv mailing list linux-riscv@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-riscv ^ permalink raw reply [flat|nested] 38+ messages in thread
* [RFC PATCH 1/6] dt-bindings: riscv: Add YAML documentation for PMU 2020-06-29 3:19 [RFC PATCH 0/6] Support raw event and DT for perf on RISC-V Zong Li @ 2020-06-29 3:19 ` Zong Li 2020-06-29 4:09 ` Anup Patel 2020-06-29 3:19 ` [RFC PATCH 2/6] riscv: dts: sifive: Add DT support " Zong Li ` (6 subsequent siblings) 7 siblings, 1 reply; 38+ messages in thread From: Zong Li @ 2020-06-29 3:19 UTC (permalink / raw) To: palmer, paul.walmsley, linux-riscv, linux-kernel; +Cc: Zong Li Add device tree bindings for performance monitor unit. And it passes the dt_binding_check verification. Signed-off-by: Zong Li <zong.li@sifive.com> --- .../devicetree/bindings/riscv/pmu.yaml | 59 +++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 Documentation/devicetree/bindings/riscv/pmu.yaml diff --git a/Documentation/devicetree/bindings/riscv/pmu.yaml b/Documentation/devicetree/bindings/riscv/pmu.yaml new file mode 100644 index 000000000000..f55ccbc6c685 --- /dev/null +++ b/Documentation/devicetree/bindings/riscv/pmu.yaml @@ -0,0 +1,59 @@ +# SPDX-License-Identifier: GPL-2.0 +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/riscv/pmu.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: RISC-V Performance Monitor Units + +maintainers: + - Zong Li <zong.li@sifive.com> + - Paul Walmsley <paul.walmsley@sifive.com> + - Palmer Dabbelt <palmer@dabbelt.com> + +properties: + compatible: + items: + - const: riscv,pmu + + riscv,width-base-cntr: + description: The width of cycle and instret CSRs. + $ref: /schemas/types.yaml#/definitions/uint32 + + riscv,width-event-cntr: + description: The width of hpmcounter CSRs. + $ref: /schemas/types.yaml#/definitions/uint32 + + riscv,n-event-cntr: + description: The number of hpmcounter CSRs. + $ref: /schemas/types.yaml#/definitions/uint32 + + riscv,hw-event-map: + description: The mapping of generic hardware events. Default is no mapping. + $ref: /schemas/types.yaml#/definitions/uint32-array + + riscv,hw-cache-event-map: + description: The mapping of generic hardware cache events. + Default is no mapping. + $ref: /schemas/types.yaml#/definitions/uint32-array + +required: + - compatible + - riscv,width-base-cntr + - riscv,width-event-cntr + - riscv,n-event-cntr + +additionalProperties: false + +examples: + - | + pmu { + compatible = "riscv,pmu"; + riscv,width-base-cntr = <64>; + riscv,width-event-cntr = <40>; + riscv,n-event-cntr = <2>; + riscv,hw-event-map = <0x0 0x0 0x1 0x1 0x3 0x0202 0x4 0x4000>; + riscv,hw-cache-event-map = <0x010201 0x0102 0x010204 0x0802>; + }; + +... -- 2.27.0 _______________________________________________ linux-riscv mailing list linux-riscv@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-riscv ^ permalink raw reply related [flat|nested] 38+ messages in thread
* Re: [RFC PATCH 1/6] dt-bindings: riscv: Add YAML documentation for PMU 2020-06-29 3:19 ` [RFC PATCH 1/6] dt-bindings: riscv: Add YAML documentation for PMU Zong Li @ 2020-06-29 4:09 ` Anup Patel 2020-06-29 4:28 ` Zong Li 0 siblings, 1 reply; 38+ messages in thread From: Anup Patel @ 2020-06-29 4:09 UTC (permalink / raw) To: Zong Li Cc: linux-riscv, Palmer Dabbelt, linux-kernel@vger.kernel.org List, Paul Walmsley On Mon, Jun 29, 2020 at 8:49 AM Zong Li <zong.li@sifive.com> wrote: > > Add device tree bindings for performance monitor unit. And it passes the > dt_binding_check verification. > > Signed-off-by: Zong Li <zong.li@sifive.com> > --- > .../devicetree/bindings/riscv/pmu.yaml | 59 +++++++++++++++++++ > 1 file changed, 59 insertions(+) > create mode 100644 Documentation/devicetree/bindings/riscv/pmu.yaml > > diff --git a/Documentation/devicetree/bindings/riscv/pmu.yaml b/Documentation/devicetree/bindings/riscv/pmu.yaml > new file mode 100644 > index 000000000000..f55ccbc6c685 > --- /dev/null > +++ b/Documentation/devicetree/bindings/riscv/pmu.yaml > @@ -0,0 +1,59 @@ > +# SPDX-License-Identifier: GPL-2.0 > +%YAML 1.2 > +--- > +$id: http://devicetree.org/schemas/riscv/pmu.yaml# > +$schema: http://devicetree.org/meta-schemas/core.yaml# > + > +title: RISC-V Performance Monitor Units > + > +maintainers: > + - Zong Li <zong.li@sifive.com> > + - Paul Walmsley <paul.walmsley@sifive.com> > + - Palmer Dabbelt <palmer@dabbelt.com> > + > +properties: > + compatible: > + items: > + - const: riscv,pmu > + > + riscv,width-base-cntr: > + description: The width of cycle and instret CSRs. > + $ref: /schemas/types.yaml#/definitions/uint32 > + > + riscv,width-event-cntr: > + description: The width of hpmcounter CSRs. > + $ref: /schemas/types.yaml#/definitions/uint32 The terms "base" and "event" is confusing because we only have counters with no interrupt associated with it. The RISC-V spec defines 3 counters and rest are all implementation specific counters. I suggest using the terms "spec counters" and "impl counters" instead of "base counters" and "event counters". Further, "riscv,width" properties are redundant because RISC-V spec clearly tells that counters are 64bit for both RV32 and RV64. > + > + riscv,n-event-cntr: > + description: The number of hpmcounter CSRs. > + $ref: /schemas/types.yaml#/definitions/uint32 > + > + riscv,hw-event-map: > + description: The mapping of generic hardware events. Default is no mapping. > + $ref: /schemas/types.yaml#/definitions/uint32-array > + > + riscv,hw-cache-event-map: > + description: The mapping of generic hardware cache events. > + Default is no mapping. > + $ref: /schemas/types.yaml#/definitions/uint32-array > + > +required: > + - compatible > + - riscv,width-base-cntr > + - riscv,width-event-cntr > + - riscv,n-event-cntr > + > +additionalProperties: false > + > +examples: > + - | > + pmu { > + compatible = "riscv,pmu"; > + riscv,width-base-cntr = <64>; > + riscv,width-event-cntr = <40>; > + riscv,n-event-cntr = <2>; > + riscv,hw-event-map = <0x0 0x0 0x1 0x1 0x3 0x0202 0x4 0x4000>; > + riscv,hw-cache-event-map = <0x010201 0x0102 0x010204 0x0802>; > + }; > + > +... > -- > 2.27.0 > Regards, Anup _______________________________________________ linux-riscv mailing list linux-riscv@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-riscv ^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: [RFC PATCH 1/6] dt-bindings: riscv: Add YAML documentation for PMU 2020-06-29 4:09 ` Anup Patel @ 2020-06-29 4:28 ` Zong Li 2020-06-29 4:37 ` Anup Patel 0 siblings, 1 reply; 38+ messages in thread From: Zong Li @ 2020-06-29 4:28 UTC (permalink / raw) To: Anup Patel Cc: linux-riscv, Palmer Dabbelt, linux-kernel@vger.kernel.org List, Paul Walmsley On Mon, Jun 29, 2020 at 12:09 PM Anup Patel <anup@brainfault.org> wrote: > > On Mon, Jun 29, 2020 at 8:49 AM Zong Li <zong.li@sifive.com> wrote: > > > > Add device tree bindings for performance monitor unit. And it passes the > > dt_binding_check verification. > > > > Signed-off-by: Zong Li <zong.li@sifive.com> > > --- > > .../devicetree/bindings/riscv/pmu.yaml | 59 +++++++++++++++++++ > > 1 file changed, 59 insertions(+) > > create mode 100644 Documentation/devicetree/bindings/riscv/pmu.yaml > > > > diff --git a/Documentation/devicetree/bindings/riscv/pmu.yaml b/Documentation/devicetree/bindings/riscv/pmu.yaml > > new file mode 100644 > > index 000000000000..f55ccbc6c685 > > --- /dev/null > > +++ b/Documentation/devicetree/bindings/riscv/pmu.yaml > > @@ -0,0 +1,59 @@ > > +# SPDX-License-Identifier: GPL-2.0 > > +%YAML 1.2 > > +--- > > +$id: http://devicetree.org/schemas/riscv/pmu.yaml# > > +$schema: http://devicetree.org/meta-schemas/core.yaml# > > + > > +title: RISC-V Performance Monitor Units > > + > > +maintainers: > > + - Zong Li <zong.li@sifive.com> > > + - Paul Walmsley <paul.walmsley@sifive.com> > > + - Palmer Dabbelt <palmer@dabbelt.com> > > + > > +properties: > > + compatible: > > + items: > > + - const: riscv,pmu > > + > > + riscv,width-base-cntr: > > + description: The width of cycle and instret CSRs. > > + $ref: /schemas/types.yaml#/definitions/uint32 > > + > > + riscv,width-event-cntr: > > + description: The width of hpmcounter CSRs. > > + $ref: /schemas/types.yaml#/definitions/uint32 > > The terms "base" and "event" is confusing because > we only have counters with no interrupt associated with it. > > The RISC-V spec defines 3 counters and rest are all > implementation specific counters. As I know, there are 2 counters of spec definition: cycle and instret. What is the 3rd counter you mentioned? > > I suggest using the terms "spec counters" and "impl counters" > instead of "base counters" and "event counters". OK, they are good to me. Let me change it. > > Further, "riscv,width" properties are redundant because > RISC-V spec clearly tells that counters are 64bit for both > RV32 and RV64. > > > + > > + riscv,n-event-cntr: > > + description: The number of hpmcounter CSRs. > > + $ref: /schemas/types.yaml#/definitions/uint32 > > + > > + riscv,hw-event-map: > > + description: The mapping of generic hardware events. Default is no mapping. > > + $ref: /schemas/types.yaml#/definitions/uint32-array > > + > > + riscv,hw-cache-event-map: > > + description: The mapping of generic hardware cache events. > > + Default is no mapping. > > + $ref: /schemas/types.yaml#/definitions/uint32-array > > + > > +required: > > + - compatible > > + - riscv,width-base-cntr > > + - riscv,width-event-cntr > > + - riscv,n-event-cntr > > + > > +additionalProperties: false > > + > > +examples: > > + - | > > + pmu { > > + compatible = "riscv,pmu"; > > + riscv,width-base-cntr = <64>; > > + riscv,width-event-cntr = <40>; > > + riscv,n-event-cntr = <2>; > > + riscv,hw-event-map = <0x0 0x0 0x1 0x1 0x3 0x0202 0x4 0x4000>; > > + riscv,hw-cache-event-map = <0x010201 0x0102 0x010204 0x0802>; > > + }; > > + > > +... > > -- > > 2.27.0 > > > > Regards, > Anup _______________________________________________ linux-riscv mailing list linux-riscv@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-riscv ^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: [RFC PATCH 1/6] dt-bindings: riscv: Add YAML documentation for PMU 2020-06-29 4:28 ` Zong Li @ 2020-06-29 4:37 ` Anup Patel 2020-06-29 6:35 ` Zong Li 0 siblings, 1 reply; 38+ messages in thread From: Anup Patel @ 2020-06-29 4:37 UTC (permalink / raw) To: Zong Li Cc: linux-riscv, Palmer Dabbelt, linux-kernel@vger.kernel.org List, Paul Walmsley On Mon, Jun 29, 2020 at 9:58 AM Zong Li <zong.li@sifive.com> wrote: > > On Mon, Jun 29, 2020 at 12:09 PM Anup Patel <anup@brainfault.org> wrote: > > > > On Mon, Jun 29, 2020 at 8:49 AM Zong Li <zong.li@sifive.com> wrote: > > > > > > Add device tree bindings for performance monitor unit. And it passes the > > > dt_binding_check verification. > > > > > > Signed-off-by: Zong Li <zong.li@sifive.com> > > > --- > > > .../devicetree/bindings/riscv/pmu.yaml | 59 +++++++++++++++++++ > > > 1 file changed, 59 insertions(+) > > > create mode 100644 Documentation/devicetree/bindings/riscv/pmu.yaml > > > > > > diff --git a/Documentation/devicetree/bindings/riscv/pmu.yaml b/Documentation/devicetree/bindings/riscv/pmu.yaml > > > new file mode 100644 > > > index 000000000000..f55ccbc6c685 > > > --- /dev/null > > > +++ b/Documentation/devicetree/bindings/riscv/pmu.yaml > > > @@ -0,0 +1,59 @@ > > > +# SPDX-License-Identifier: GPL-2.0 > > > +%YAML 1.2 > > > +--- > > > +$id: http://devicetree.org/schemas/riscv/pmu.yaml# > > > +$schema: http://devicetree.org/meta-schemas/core.yaml# > > > + > > > +title: RISC-V Performance Monitor Units > > > + > > > +maintainers: > > > + - Zong Li <zong.li@sifive.com> > > > + - Paul Walmsley <paul.walmsley@sifive.com> > > > + - Palmer Dabbelt <palmer@dabbelt.com> > > > + > > > +properties: > > > + compatible: > > > + items: > > > + - const: riscv,pmu > > > + > > > + riscv,width-base-cntr: > > > + description: The width of cycle and instret CSRs. > > > + $ref: /schemas/types.yaml#/definitions/uint32 > > > + > > > + riscv,width-event-cntr: > > > + description: The width of hpmcounter CSRs. > > > + $ref: /schemas/types.yaml#/definitions/uint32 > > > > The terms "base" and "event" is confusing because > > we only have counters with no interrupt associated with it. > > > > The RISC-V spec defines 3 counters and rest are all > > implementation specific counters. > > As I know, there are 2 counters of spec definition: cycle and instret. > What is the 3rd counter you mentioned? TIME is a counter CSR. > > > > > I suggest using the terms "spec counters" and "impl counters" > > instead of "base counters" and "event counters". > > OK, they are good to me. Let me change it. > > > > > > Further, "riscv,width" properties are redundant because > > RISC-V spec clearly tells that counters are 64bit for both > > RV32 and RV64. > > > > > + > > > + riscv,n-event-cntr: > > > + description: The number of hpmcounter CSRs. > > > + $ref: /schemas/types.yaml#/definitions/uint32 > > > + > > > + riscv,hw-event-map: > > > + description: The mapping of generic hardware events. Default is no mapping. > > > + $ref: /schemas/types.yaml#/definitions/uint32-array > > > + > > > + riscv,hw-cache-event-map: > > > + description: The mapping of generic hardware cache events. > > > + Default is no mapping. > > > + $ref: /schemas/types.yaml#/definitions/uint32-array > > > + > > > +required: > > > + - compatible > > > + - riscv,width-base-cntr > > > + - riscv,width-event-cntr > > > + - riscv,n-event-cntr > > > + > > > +additionalProperties: false > > > + > > > +examples: > > > + - | > > > + pmu { > > > + compatible = "riscv,pmu"; > > > + riscv,width-base-cntr = <64>; > > > + riscv,width-event-cntr = <40>; > > > + riscv,n-event-cntr = <2>; > > > + riscv,hw-event-map = <0x0 0x0 0x1 0x1 0x3 0x0202 0x4 0x4000>; > > > + riscv,hw-cache-event-map = <0x010201 0x0102 0x010204 0x0802>; > > > + }; > > > + > > > +... > > > -- > > > 2.27.0 > > > > > > > Regards, > > Anup _______________________________________________ linux-riscv mailing list linux-riscv@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-riscv ^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: [RFC PATCH 1/6] dt-bindings: riscv: Add YAML documentation for PMU 2020-06-29 4:37 ` Anup Patel @ 2020-06-29 6:35 ` Zong Li 2020-06-29 8:31 ` Anup Patel 0 siblings, 1 reply; 38+ messages in thread From: Zong Li @ 2020-06-29 6:35 UTC (permalink / raw) To: Anup Patel Cc: linux-riscv, Palmer Dabbelt, linux-kernel@vger.kernel.org List, Paul Walmsley On Mon, Jun 29, 2020 at 12:38 PM Anup Patel <anup@brainfault.org> wrote: > > On Mon, Jun 29, 2020 at 9:58 AM Zong Li <zong.li@sifive.com> wrote: > > > > On Mon, Jun 29, 2020 at 12:09 PM Anup Patel <anup@brainfault.org> wrote: > > > > > > On Mon, Jun 29, 2020 at 8:49 AM Zong Li <zong.li@sifive.com> wrote: > > > > > > > > Add device tree bindings for performance monitor unit. And it passes the > > > > dt_binding_check verification. > > > > > > > > Signed-off-by: Zong Li <zong.li@sifive.com> > > > > --- > > > > .../devicetree/bindings/riscv/pmu.yaml | 59 +++++++++++++++++++ > > > > 1 file changed, 59 insertions(+) > > > > create mode 100644 Documentation/devicetree/bindings/riscv/pmu.yaml > > > > > > > > diff --git a/Documentation/devicetree/bindings/riscv/pmu.yaml b/Documentation/devicetree/bindings/riscv/pmu.yaml > > > > new file mode 100644 > > > > index 000000000000..f55ccbc6c685 > > > > --- /dev/null > > > > +++ b/Documentation/devicetree/bindings/riscv/pmu.yaml > > > > @@ -0,0 +1,59 @@ > > > > +# SPDX-License-Identifier: GPL-2.0 > > > > +%YAML 1.2 > > > > +--- > > > > +$id: http://devicetree.org/schemas/riscv/pmu.yaml# > > > > +$schema: http://devicetree.org/meta-schemas/core.yaml# > > > > + > > > > +title: RISC-V Performance Monitor Units > > > > + > > > > +maintainers: > > > > + - Zong Li <zong.li@sifive.com> > > > > + - Paul Walmsley <paul.walmsley@sifive.com> > > > > + - Palmer Dabbelt <palmer@dabbelt.com> > > > > + > > > > +properties: > > > > + compatible: > > > > + items: > > > > + - const: riscv,pmu > > > > + > > > > + riscv,width-base-cntr: > > > > + description: The width of cycle and instret CSRs. > > > > + $ref: /schemas/types.yaml#/definitions/uint32 > > > > + > > > > + riscv,width-event-cntr: > > > > + description: The width of hpmcounter CSRs. > > > > + $ref: /schemas/types.yaml#/definitions/uint32 > > > > > > The terms "base" and "event" is confusing because > > > we only have counters with no interrupt associated with it. > > > > > > The RISC-V spec defines 3 counters and rest are all > > > implementation specific counters. > > > > As I know, there are 2 counters of spec definition: cycle and instret. > > What is the 3rd counter you mentioned? > > TIME is a counter CSR. > > > > > > > > > I suggest using the terms "spec counters" and "impl counters" > > > instead of "base counters" and "event counters". > > > > OK, they are good to me. Let me change it. > > > > > > > > > > Further, "riscv,width" properties are redundant because > > > RISC-V spec clearly tells that counters are 64bit for both > > > RV32 and RV64. > > > Sorry for the lost replying. The maximum length of counters is 64, but it doesn't require to implement all bits. A real case is that unleashed board only implements 40 bit for mhpmcounters. > > > > + > > > > + riscv,n-event-cntr: > > > > + description: The number of hpmcounter CSRs. > > > > + $ref: /schemas/types.yaml#/definitions/uint32 > > > > + > > > > + riscv,hw-event-map: > > > > + description: The mapping of generic hardware events. Default is no mapping. > > > > + $ref: /schemas/types.yaml#/definitions/uint32-array > > > > + > > > > + riscv,hw-cache-event-map: > > > > + description: The mapping of generic hardware cache events. > > > > + Default is no mapping. > > > > + $ref: /schemas/types.yaml#/definitions/uint32-array > > > > + > > > > +required: > > > > + - compatible > > > > + - riscv,width-base-cntr > > > > + - riscv,width-event-cntr > > > > + - riscv,n-event-cntr > > > > + > > > > +additionalProperties: false > > > > + > > > > +examples: > > > > + - | > > > > + pmu { > > > > + compatible = "riscv,pmu"; > > > > + riscv,width-base-cntr = <64>; > > > > + riscv,width-event-cntr = <40>; > > > > + riscv,n-event-cntr = <2>; > > > > + riscv,hw-event-map = <0x0 0x0 0x1 0x1 0x3 0x0202 0x4 0x4000>; > > > > + riscv,hw-cache-event-map = <0x010201 0x0102 0x010204 0x0802>; > > > > + }; > > > > + > > > > +... > > > > -- > > > > 2.27.0 > > > > > > > > > > Regards, > > > Anup _______________________________________________ linux-riscv mailing list linux-riscv@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-riscv ^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: [RFC PATCH 1/6] dt-bindings: riscv: Add YAML documentation for PMU 2020-06-29 6:35 ` Zong Li @ 2020-06-29 8:31 ` Anup Patel 2020-07-01 3:22 ` Zong Li 0 siblings, 1 reply; 38+ messages in thread From: Anup Patel @ 2020-06-29 8:31 UTC (permalink / raw) To: Zong Li Cc: linux-riscv, Palmer Dabbelt, linux-kernel@vger.kernel.org List, Paul Walmsley On Mon, Jun 29, 2020 at 12:06 PM Zong Li <zong.li@sifive.com> wrote: > > On Mon, Jun 29, 2020 at 12:38 PM Anup Patel <anup@brainfault.org> wrote: > > > > On Mon, Jun 29, 2020 at 9:58 AM Zong Li <zong.li@sifive.com> wrote: > > > > > > On Mon, Jun 29, 2020 at 12:09 PM Anup Patel <anup@brainfault.org> wrote: > > > > > > > > On Mon, Jun 29, 2020 at 8:49 AM Zong Li <zong.li@sifive.com> wrote: > > > > > > > > > > Add device tree bindings for performance monitor unit. And it passes the > > > > > dt_binding_check verification. > > > > > > > > > > Signed-off-by: Zong Li <zong.li@sifive.com> > > > > > --- > > > > > .../devicetree/bindings/riscv/pmu.yaml | 59 +++++++++++++++++++ > > > > > 1 file changed, 59 insertions(+) > > > > > create mode 100644 Documentation/devicetree/bindings/riscv/pmu.yaml > > > > > > > > > > diff --git a/Documentation/devicetree/bindings/riscv/pmu.yaml b/Documentation/devicetree/bindings/riscv/pmu.yaml > > > > > new file mode 100644 > > > > > index 000000000000..f55ccbc6c685 > > > > > --- /dev/null > > > > > +++ b/Documentation/devicetree/bindings/riscv/pmu.yaml > > > > > @@ -0,0 +1,59 @@ > > > > > +# SPDX-License-Identifier: GPL-2.0 > > > > > +%YAML 1.2 > > > > > +--- > > > > > +$id: http://devicetree.org/schemas/riscv/pmu.yaml# > > > > > +$schema: http://devicetree.org/meta-schemas/core.yaml# > > > > > + > > > > > +title: RISC-V Performance Monitor Units > > > > > + > > > > > +maintainers: > > > > > + - Zong Li <zong.li@sifive.com> > > > > > + - Paul Walmsley <paul.walmsley@sifive.com> > > > > > + - Palmer Dabbelt <palmer@dabbelt.com> > > > > > + > > > > > +properties: > > > > > + compatible: > > > > > + items: > > > > > + - const: riscv,pmu > > > > > + > > > > > + riscv,width-base-cntr: > > > > > + description: The width of cycle and instret CSRs. > > > > > + $ref: /schemas/types.yaml#/definitions/uint32 > > > > > + > > > > > + riscv,width-event-cntr: > > > > > + description: The width of hpmcounter CSRs. > > > > > + $ref: /schemas/types.yaml#/definitions/uint32 > > > > > > > > The terms "base" and "event" is confusing because > > > > we only have counters with no interrupt associated with it. > > > > > > > > The RISC-V spec defines 3 counters and rest are all > > > > implementation specific counters. > > > > > > As I know, there are 2 counters of spec definition: cycle and instret. > > > What is the 3rd counter you mentioned? > > > > TIME is a counter CSR. > > > > > > > > > > > > > I suggest using the terms "spec counters" and "impl counters" > > > > instead of "base counters" and "event counters". > > > > > > OK, they are good to me. Let me change it. > > > > > > > > > > > > > > Further, "riscv,width" properties are redundant because > > > > RISC-V spec clearly tells that counters are 64bit for both > > > > RV32 and RV64. > > > > > > Sorry for the lost replying. The maximum length of counters is 64, but > it doesn't require to implement all bits. A real case is that > unleashed board only implements 40 bit for mhpmcounters. The "3.1.11 Hardware Performance Monitor" clearly states that all counters are 64bit To take care of the unleashed board, the "riscv,width-xyz" DT properties should be optional. Whenever these properties are not present, we should assume 64bit counter width. > > > > > > + > > > > > + riscv,n-event-cntr: > > > > > + description: The number of hpmcounter CSRs. > > > > > + $ref: /schemas/types.yaml#/definitions/uint32 > > > > > + > > > > > + riscv,hw-event-map: > > > > > + description: The mapping of generic hardware events. Default is no mapping. > > > > > + $ref: /schemas/types.yaml#/definitions/uint32-array > > > > > + > > > > > + riscv,hw-cache-event-map: > > > > > + description: The mapping of generic hardware cache events. > > > > > + Default is no mapping. > > > > > + $ref: /schemas/types.yaml#/definitions/uint32-array > > > > > + > > > > > +required: > > > > > + - compatible > > > > > + - riscv,width-base-cntr > > > > > + - riscv,width-event-cntr > > > > > + - riscv,n-event-cntr > > > > > + > > > > > +additionalProperties: false > > > > > + > > > > > +examples: > > > > > + - | > > > > > + pmu { > > > > > + compatible = "riscv,pmu"; > > > > > + riscv,width-base-cntr = <64>; > > > > > + riscv,width-event-cntr = <40>; > > > > > + riscv,n-event-cntr = <2>; > > > > > + riscv,hw-event-map = <0x0 0x0 0x1 0x1 0x3 0x0202 0x4 0x4000>; > > > > > + riscv,hw-cache-event-map = <0x010201 0x0102 0x010204 0x0802>; > > > > > + }; > > > > > + > > > > > +... > > > > > -- > > > > > 2.27.0 > > > > > > > > > > > > > Regards, > > > > Anup Regards, Anup _______________________________________________ linux-riscv mailing list linux-riscv@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-riscv ^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: [RFC PATCH 1/6] dt-bindings: riscv: Add YAML documentation for PMU 2020-06-29 8:31 ` Anup Patel @ 2020-07-01 3:22 ` Zong Li 0 siblings, 0 replies; 38+ messages in thread From: Zong Li @ 2020-07-01 3:22 UTC (permalink / raw) To: Anup Patel Cc: linux-riscv, Palmer Dabbelt, linux-kernel@vger.kernel.org List, Paul Walmsley On Mon, Jun 29, 2020 at 4:31 PM Anup Patel <anup@brainfault.org> wrote: > > On Mon, Jun 29, 2020 at 12:06 PM Zong Li <zong.li@sifive.com> wrote: > > > > On Mon, Jun 29, 2020 at 12:38 PM Anup Patel <anup@brainfault.org> wrote: > > > > > > On Mon, Jun 29, 2020 at 9:58 AM Zong Li <zong.li@sifive.com> wrote: > > > > > > > > On Mon, Jun 29, 2020 at 12:09 PM Anup Patel <anup@brainfault.org> wrote: > > > > > > > > > > On Mon, Jun 29, 2020 at 8:49 AM Zong Li <zong.li@sifive.com> wrote: > > > > > > > > > > > > Add device tree bindings for performance monitor unit. And it passes the > > > > > > dt_binding_check verification. > > > > > > > > > > > > Signed-off-by: Zong Li <zong.li@sifive.com> > > > > > > --- > > > > > > .../devicetree/bindings/riscv/pmu.yaml | 59 +++++++++++++++++++ > > > > > > 1 file changed, 59 insertions(+) > > > > > > create mode 100644 Documentation/devicetree/bindings/riscv/pmu.yaml > > > > > > > > > > > > diff --git a/Documentation/devicetree/bindings/riscv/pmu.yaml b/Documentation/devicetree/bindings/riscv/pmu.yaml > > > > > > new file mode 100644 > > > > > > index 000000000000..f55ccbc6c685 > > > > > > --- /dev/null > > > > > > +++ b/Documentation/devicetree/bindings/riscv/pmu.yaml > > > > > > @@ -0,0 +1,59 @@ > > > > > > +# SPDX-License-Identifier: GPL-2.0 > > > > > > +%YAML 1.2 > > > > > > +--- > > > > > > +$id: http://devicetree.org/schemas/riscv/pmu.yaml# > > > > > > +$schema: http://devicetree.org/meta-schemas/core.yaml# > > > > > > + > > > > > > +title: RISC-V Performance Monitor Units > > > > > > + > > > > > > +maintainers: > > > > > > + - Zong Li <zong.li@sifive.com> > > > > > > + - Paul Walmsley <paul.walmsley@sifive.com> > > > > > > + - Palmer Dabbelt <palmer@dabbelt.com> > > > > > > + > > > > > > +properties: > > > > > > + compatible: > > > > > > + items: > > > > > > + - const: riscv,pmu > > > > > > + > > > > > > + riscv,width-base-cntr: > > > > > > + description: The width of cycle and instret CSRs. > > > > > > + $ref: /schemas/types.yaml#/definitions/uint32 > > > > > > + > > > > > > + riscv,width-event-cntr: > > > > > > + description: The width of hpmcounter CSRs. > > > > > > + $ref: /schemas/types.yaml#/definitions/uint32 > > > > > > > > > > The terms "base" and "event" is confusing because > > > > > we only have counters with no interrupt associated with it. > > > > > > > > > > The RISC-V spec defines 3 counters and rest are all > > > > > implementation specific counters. > > > > > > > > As I know, there are 2 counters of spec definition: cycle and instret. > > > > What is the 3rd counter you mentioned? > > > > > > TIME is a counter CSR. > > > > > > > > > > > > > > > > > I suggest using the terms "spec counters" and "impl counters" > > > > > instead of "base counters" and "event counters". > > > > > > > > OK, they are good to me. Let me change it. > > > > > > > > > > > > > > > > > > Further, "riscv,width" properties are redundant because > > > > > RISC-V spec clearly tells that counters are 64bit for both > > > > > RV32 and RV64. > > > > > > > > > Sorry for the lost replying. The maximum length of counters is 64, but > > it doesn't require to implement all bits. A real case is that > > unleashed board only implements 40 bit for mhpmcounters. > > The "3.1.11 Hardware Performance Monitor" clearly states that > all counters are 64bit > In the privileged spec, 3.1.11 section said, "The mhpmcounters are WARL registers that support up to 64 bits of precision on RV32 and RV64". It seems to me that WARL implies the size of registers could be variable, and support up to 64 bits as maximum size. > To take care of the unleashed board, the "riscv,width-xyz" DT properties > should be optional. Whenever these properties are not present, we > should assume 64bit counter width. > > > > > > > > > + > > > > > > + riscv,n-event-cntr: > > > > > > + description: The number of hpmcounter CSRs. > > > > > > + $ref: /schemas/types.yaml#/definitions/uint32 > > > > > > + > > > > > > + riscv,hw-event-map: > > > > > > + description: The mapping of generic hardware events. Default is no mapping. > > > > > > + $ref: /schemas/types.yaml#/definitions/uint32-array > > > > > > + > > > > > > + riscv,hw-cache-event-map: > > > > > > + description: The mapping of generic hardware cache events. > > > > > > + Default is no mapping. > > > > > > + $ref: /schemas/types.yaml#/definitions/uint32-array > > > > > > + > > > > > > +required: > > > > > > + - compatible > > > > > > + - riscv,width-base-cntr > > > > > > + - riscv,width-event-cntr > > > > > > + - riscv,n-event-cntr > > > > > > + > > > > > > +additionalProperties: false > > > > > > + > > > > > > +examples: > > > > > > + - | > > > > > > + pmu { > > > > > > + compatible = "riscv,pmu"; > > > > > > + riscv,width-base-cntr = <64>; > > > > > > + riscv,width-event-cntr = <40>; > > > > > > + riscv,n-event-cntr = <2>; > > > > > > + riscv,hw-event-map = <0x0 0x0 0x1 0x1 0x3 0x0202 0x4 0x4000>; > > > > > > + riscv,hw-cache-event-map = <0x010201 0x0102 0x010204 0x0802>; > > > > > > + }; > > > > > > + > > > > > > +... > > > > > > -- > > > > > > 2.27.0 > > > > > > > > > > > > > > > > Regards, > > > > > Anup > > Regards, > Anup _______________________________________________ linux-riscv mailing list linux-riscv@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-riscv ^ permalink raw reply [flat|nested] 38+ messages in thread
* [RFC PATCH 2/6] riscv: dts: sifive: Add DT support for PMU 2020-06-29 3:19 [RFC PATCH 0/6] Support raw event and DT for perf on RISC-V Zong Li 2020-06-29 3:19 ` [RFC PATCH 1/6] dt-bindings: riscv: Add YAML documentation for PMU Zong Li @ 2020-06-29 3:19 ` Zong Li 2020-06-29 3:19 ` [RFC PATCH 3/6] riscv: add definition of hpmcounter CSRs Zong Li ` (5 subsequent siblings) 7 siblings, 0 replies; 38+ messages in thread From: Zong Li @ 2020-06-29 3:19 UTC (permalink / raw) To: palmer, paul.walmsley, linux-riscv, linux-kernel; +Cc: Zong Li Add performance monitor unit DT node in SiFive Fu540 soc-specific DT file. This pmu node passes the dtbs_check verification. Signed-off-by: Zong Li <zong.li@sifive.com> --- arch/riscv/boot/dts/sifive/fu540-c000.dtsi | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/arch/riscv/boot/dts/sifive/fu540-c000.dtsi b/arch/riscv/boot/dts/sifive/fu540-c000.dtsi index 7db861053483..824351fe2a57 100644 --- a/arch/riscv/boot/dts/sifive/fu540-c000.dtsi +++ b/arch/riscv/boot/dts/sifive/fu540-c000.dtsi @@ -283,4 +283,17 @@ gpio: gpio@10060000 { status = "disabled"; }; }; + pmu { + compatible = "riscv,pmu"; + riscv,width-base-cntr = <64>; + riscv,width-event-cntr = <40>; + riscv,n-event-cntr = <2>; + riscv,hw-event-map = <0x0 0x0 + 0x1 0x1 + 0x3 0x0202 + 0x4 0x4000 + 0x5 0x2001>; + riscv,hw-cache-event-map = <0x010201 0x0102 + 0x010204 0x0802>; + }; }; -- 2.27.0 _______________________________________________ linux-riscv mailing list linux-riscv@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-riscv ^ permalink raw reply related [flat|nested] 38+ messages in thread
* [RFC PATCH 3/6] riscv: add definition of hpmcounter CSRs 2020-06-29 3:19 [RFC PATCH 0/6] Support raw event and DT for perf on RISC-V Zong Li 2020-06-29 3:19 ` [RFC PATCH 1/6] dt-bindings: riscv: Add YAML documentation for PMU Zong Li 2020-06-29 3:19 ` [RFC PATCH 2/6] riscv: dts: sifive: Add DT support " Zong Li @ 2020-06-29 3:19 ` Zong Li 2020-06-29 3:19 ` [RFC PATCH 4/6] riscv: perf: Add raw event support Zong Li ` (4 subsequent siblings) 7 siblings, 0 replies; 38+ messages in thread From: Zong Li @ 2020-06-29 3:19 UTC (permalink / raw) To: palmer, paul.walmsley, linux-riscv, linux-kernel; +Cc: Zong Li The hpmcounter CSRs are used for perf to read the value of monitoring hardware events. Signed-off-by: Zong Li <zong.li@sifive.com> --- 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 cec462e198ce..3a18a0bbdc6d 100644 --- a/arch/riscv/include/asm/csr.h +++ b/arch/riscv/include/asm/csr.h @@ -83,9 +83,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.27.0 _______________________________________________ linux-riscv mailing list linux-riscv@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-riscv ^ permalink raw reply related [flat|nested] 38+ messages in thread
* [RFC PATCH 4/6] riscv: perf: Add raw event support 2020-06-29 3:19 [RFC PATCH 0/6] Support raw event and DT for perf on RISC-V Zong Li ` (2 preceding siblings ...) 2020-06-29 3:19 ` [RFC PATCH 3/6] riscv: add definition of hpmcounter CSRs Zong Li @ 2020-06-29 3:19 ` Zong Li 2020-06-29 4:17 ` Anup Patel 2020-06-29 3:19 ` [RFC PATCH 5/6] riscv: perf: introduce DT mechanism Zong Li ` (3 subsequent siblings) 7 siblings, 1 reply; 38+ messages in thread From: Zong Li @ 2020-06-29 3:19 UTC (permalink / raw) To: palmer, paul.walmsley, linux-riscv, linux-kernel; +Cc: Zong Li Add support for raw events and hardware cache events. Currently, we set the events by writing the mhpmeventN CSRs, it would raise an illegal instruction exception and trap into m-mode to emulate event selector CSRs access. It doesn't make sense because we shouldn't write the m-mode CSRs in s-mode, it would be better that set events through SBI call or the shadow CSRs of s-mode. We would change it later. Signed-off-by: Zong Li <zong.li@sifive.com> --- arch/riscv/include/asm/perf_event.h | 65 ++++++--- arch/riscv/kernel/perf_event.c | 204 +++++++++++++++++++++++----- 2 files changed, 215 insertions(+), 54 deletions(-) diff --git a/arch/riscv/include/asm/perf_event.h b/arch/riscv/include/asm/perf_event.h index 062efd3a1d5d..41d515a1f331 100644 --- a/arch/riscv/include/asm/perf_event.h +++ b/arch/riscv/include/asm/perf_event.h @@ -14,39 +14,64 @@ #ifdef CONFIG_RISCV_BASE_PMU #define RISCV_BASE_COUNTERS 2 +#define RISCV_EVENT_COUNTERS 29 +#define RISCV_TOTAL_COUNTERS (RISCV_BASE_COUNTERS + RISCV_EVENT_COUNTERS) /* - * The RISCV_MAX_COUNTERS parameter should be specified. - */ - -#define RISCV_MAX_COUNTERS 2 - -/* - * These are the indexes of bits in counteren register *minus* 1, - * except for cycle. It would be coherent if it can directly mapped - * to counteren bit definition, but there is a *time* register at - * counteren[1]. Per-cpu structure is scarce resource here. - * * According to the spec, an implementation can support counter up to * mhpmcounter31, but many high-end processors has at most 6 general * PMCs, we give the definition to MHPMCOUNTER8 here. */ -#define RISCV_PMU_CYCLE 0 -#define RISCV_PMU_INSTRET 1 -#define RISCV_PMU_MHPMCOUNTER3 2 -#define RISCV_PMU_MHPMCOUNTER4 3 -#define RISCV_PMU_MHPMCOUNTER5 4 -#define RISCV_PMU_MHPMCOUNTER6 5 -#define RISCV_PMU_MHPMCOUNTER7 6 -#define RISCV_PMU_MHPMCOUNTER8 7 +#define RISCV_PMU_CYCLE 0 +#define RISCV_PMU_INSTRET 2 +#define RISCV_PMU_HPMCOUNTER3 3 +#define RISCV_PMU_HPMCOUNTER4 4 +#define RISCV_PMU_HPMCOUNTER5 5 +#define RISCV_PMU_HPMCOUNTER6 6 +#define RISCV_PMU_HPMCOUNTER7 7 +#define RISCV_PMU_HPMCOUNTER8 8 + +#define RISCV_PMU_HPMCOUNTER_FIRST 3 +#define RISCV_PMU_HPMCOUNTER_LAST \ + (RISCV_PMU_HPMCOUNTER_FIRST + riscv_pmu->num_counters - 1) #define RISCV_OP_UNSUPP (-EOPNOTSUPP) +/* Hardware cache event encoding */ +#define PERF_HW_CACHE_TYPE 0 +#define PERF_HW_CACHE_OP 8 +#define PERF_HW_CACHE_RESULT 16 +#define PERF_HW_CACHE_MASK 0xff + +/* config_base encoding */ +#define RISCV_PMU_TYPE_MASK 0x3 +#define RISCV_PMU_TYPE_BASE 0x1 +#define RISCV_PMU_TYPE_EVENT 0x2 +#define RISCV_PMU_EXCLUDE_MASK 0xc +#define RISCV_PMU_EXCLUDE_USER 0x3 +#define RISCV_PMU_EXCLUDE_KERNEL 0x4 + +/* + * Currently, machine-mode supports emulation of mhpmeventN. Setting mhpmeventN + * to raise an illegal instruction exception to set event types in machine-mode. + * Eventually, we should set event types through standard SBI call or the shadow + * CSRs of supervisor-mode, because it is weird for writing CSR of machine-mode + * explicitly in supervisor-mode. These macro should be removed in the future. + */ +#define CSR_MHPMEVENT3 0x323 +#define CSR_MHPMEVENT4 0x324 +#define CSR_MHPMEVENT5 0x325 +#define CSR_MHPMEVENT6 0x326 +#define CSR_MHPMEVENT7 0x327 +#define CSR_MHPMEVENT8 0x328 + struct cpu_hw_events { /* # currently enabled events*/ int n_events; /* currently enabled events */ - struct perf_event *events[RISCV_MAX_COUNTERS]; + struct perf_event *events[RISCV_EVENT_COUNTERS]; + /* bitmap of used event counters */ + unsigned long used_cntr_mask; /* vendor-defined PMU data */ void *platform; }; diff --git a/arch/riscv/kernel/perf_event.c b/arch/riscv/kernel/perf_event.c index c835f0362d94..0cfcd6f1e57b 100644 --- a/arch/riscv/kernel/perf_event.c +++ b/arch/riscv/kernel/perf_event.c @@ -139,6 +139,53 @@ static const int riscv_cache_event_map[PERF_COUNT_HW_CACHE_MAX] }, }; +/* + * Methods for checking and getting PMU information + */ + +static inline int is_base_counter(int idx) +{ + return (idx == RISCV_PMU_CYCLE || idx == RISCV_PMU_INSTRET); +} + +static inline int is_event_counter(int idx) +{ + return (idx >= RISCV_PMU_HPMCOUNTER_FIRST && + idx <= RISCV_PMU_HPMCOUNTER_LAST); +} + +static inline int get_available_counter(struct perf_event *event) +{ + struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events); + struct hw_perf_event *hwc = &event->hw; + unsigned long config_base = hwc->config_base & RISCV_PMU_TYPE_MASK; + unsigned long mask; + int ret; + + switch (config_base) { + case RISCV_PMU_TYPE_BASE: + ret = hwc->config; + if (WARN_ON_ONCE(!is_base_counter(ret))) + return -ENOSPC; + break; + case RISCV_PMU_TYPE_EVENT: + mask = ~cpuc->used_cntr_mask; + ret = find_next_bit(&mask, RISCV_PMU_HPMCOUNTER_LAST, 3); + if (WARN_ON_ONCE(!is_event_counter(ret))) + return -ENOSPC; + break; + default: + return -ENOENT; + } + + __set_bit(ret, &cpuc->used_cntr_mask); + + return ret; +} + +/* + * Map generic hardware event + */ static int riscv_map_hw_event(u64 config) { if (config >= riscv_pmu->max_events) @@ -147,32 +194,28 @@ static int riscv_map_hw_event(u64 config) return riscv_pmu->hw_events[config]; } -static int riscv_map_cache_decode(u64 config, unsigned int *type, - unsigned int *op, unsigned int *result) -{ - return -ENOENT; -} - +/* + * Map generic hardware cache event + */ static int riscv_map_cache_event(u64 config) { unsigned int type, op, result; - int err = -ENOENT; - int code; + int ret; - err = riscv_map_cache_decode(config, &type, &op, &result); - if (!riscv_pmu->cache_events || err) - return err; + type = (config >> PERF_HW_CACHE_TYPE) & PERF_HW_CACHE_MASK; + op = (config >> PERF_HW_CACHE_OP) & PERF_HW_CACHE_MASK; + result = (config >> PERF_HW_CACHE_RESULT) & PERF_HW_CACHE_MASK; if (type >= PERF_COUNT_HW_CACHE_MAX || op >= PERF_COUNT_HW_CACHE_OP_MAX || result >= PERF_COUNT_HW_CACHE_RESULT_MAX) return -EINVAL; - code = (*riscv_pmu->cache_events)[type][op][result]; - if (code == RISCV_OP_UNSUPP) + ret = riscv_cache_event_map[type][op][result]; + if (ret == RISCV_OP_UNSUPP) return -EINVAL; - return code; + return ret == RISCV_OP_UNSUPP ? -ENOENT : ret; } /* @@ -190,8 +233,27 @@ static inline u64 read_counter(int idx) case RISCV_PMU_INSTRET: val = csr_read(CSR_INSTRET); break; + case RISCV_PMU_HPMCOUNTER3: + val = csr_read(CSR_HPMCOUNTER3); + break; + case RISCV_PMU_HPMCOUNTER4: + val = csr_read(CSR_HPMCOUNTER4); + break; + case RISCV_PMU_HPMCOUNTER5: + val = csr_read(CSR_HPMCOUNTER5); + break; + case RISCV_PMU_HPMCOUNTER6: + val = csr_read(CSR_HPMCOUNTER6); + break; + case RISCV_PMU_HPMCOUNTER7: + val = csr_read(CSR_HPMCOUNTER7); + break; + case RISCV_PMU_HPMCOUNTER8: + val = csr_read(CSR_HPMCOUNTER8); + break; default: - WARN_ON_ONCE(idx < 0 || idx > RISCV_MAX_COUNTERS); + WARN_ON_ONCE(idx < RISCV_PMU_CYCLE || + idx > RISCV_TOTAL_COUNTERS); return -EINVAL; } @@ -204,6 +266,68 @@ static inline void write_counter(int idx, u64 value) WARN_ON_ONCE(1); } +static inline void write_event(int idx, u64 value) +{ + /* TODO: We shouldn't write CSR of m-mode explicitly here. Ideally, + * it need to set the event selector by SBI call or the s-mode + * shadow CSRs of them. Exploit illegal instruction exception to + * emulate mhpmcounterN access in m-mode. + */ + switch (idx) { + case RISCV_PMU_HPMCOUNTER3: + csr_write(CSR_MHPMEVENT3, value); + break; + case RISCV_PMU_HPMCOUNTER4: + csr_write(CSR_MHPMEVENT4, value); + break; + case RISCV_PMU_HPMCOUNTER5: + csr_write(CSR_MHPMEVENT5, value); + break; + case RISCV_PMU_HPMCOUNTER6: + csr_write(CSR_MHPMEVENT6, value); + break; + case RISCV_PMU_HPMCOUNTER7: + csr_write(CSR_MHPMEVENT7, value); + break; + case RISCV_PMU_HPMCOUNTER8: + csr_write(CSR_MHPMEVENT8, value); + break; + default: + WARN_ON_ONCE(idx < RISCV_PMU_HPMCOUNTER3 || + idx > RISCV_TOTAL_COUNTERS); + return; + } +} + +/* + * Enable and disable event counters + */ + +static inline void riscv_pmu_enable_event(struct perf_event *event) +{ + struct hw_perf_event *hwc = &event->hw; + int idx = hwc->idx; + + if (is_event_counter(idx)) + write_event(idx, hwc->config); + + /* + * Since we cannot write to counters, this serves as an initialization + * to the delta-mechanism in pmu->read(); otherwise, the delta would be + * wrong when pmu->read is called for the first time. + */ + local64_set(&hwc->prev_count, read_counter(hwc->idx)); +} + +static inline void riscv_pmu_disable_event(struct perf_event *event) +{ + struct hw_perf_event *hwc = &event->hw; + int idx = hwc->idx; + + if (is_event_counter(idx)) + write_event(idx, 0); +} + /* * pmu->read: read and update the counter * @@ -232,6 +356,7 @@ static void riscv_pmu_read(struct perf_event *event) */ delta = (new_raw_count - prev_raw_count) & ((1ULL << riscv_pmu->counter_width) - 1); + local64_add(delta, &event->count); /* * Something like local64_sub(delta, &hwc->period_left) here is @@ -252,6 +377,11 @@ static void riscv_pmu_stop(struct perf_event *event, int flags) { struct hw_perf_event *hwc = &event->hw; + if (WARN_ON_ONCE(hwc->idx == -1)) + return; + + riscv_pmu_disable_event(event); + WARN_ON_ONCE(hwc->state & PERF_HES_STOPPED); hwc->state |= PERF_HES_STOPPED; @@ -271,6 +401,9 @@ static void riscv_pmu_start(struct perf_event *event, int flags) if (WARN_ON_ONCE(!(event->hw.state & PERF_HES_STOPPED))) return; + if (WARN_ON_ONCE(hwc->idx == -1)) + return; + if (flags & PERF_EF_RELOAD) { WARN_ON_ONCE(!(event->hw.state & PERF_HES_UPTODATE)); @@ -281,14 +414,10 @@ static void riscv_pmu_start(struct perf_event *event, int flags) } hwc->state = 0; - perf_event_update_userpage(event); - /* - * Since we cannot write to counters, this serves as an initialization - * to the delta-mechanism in pmu->read(); otherwise, the delta would be - * wrong when pmu->read is called for the first time. - */ - local64_set(&hwc->prev_count, read_counter(hwc->idx)); + riscv_pmu_enable_event(event); + + perf_event_update_userpage(event); } /* @@ -298,21 +427,18 @@ static int riscv_pmu_add(struct perf_event *event, int flags) { struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events); struct hw_perf_event *hwc = &event->hw; + int count_idx; if (cpuc->n_events == riscv_pmu->num_counters) return -ENOSPC; - /* - * We don't have general conunters, so no binding-event-to-counter - * process here. - * - * Indexing using hwc->config generally not works, since config may - * contain extra information, but here the only info we have in - * hwc->config is the event index. - */ - hwc->idx = hwc->config; - cpuc->events[hwc->idx] = event; + count_idx = get_available_counter(event); + if (count_idx < 0) + return -ENOSPC; + cpuc->n_events++; + hwc->idx = count_idx; + cpuc->events[hwc->idx] = event; hwc->state = PERF_HES_UPTODATE | PERF_HES_STOPPED; @@ -330,8 +456,10 @@ static void riscv_pmu_del(struct perf_event *event, int flags) struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events); struct hw_perf_event *hwc = &event->hw; - cpuc->events[hwc->idx] = NULL; cpuc->n_events--; + __clear_bit(hwc->idx, &cpuc->used_cntr_mask); + + cpuc->events[hwc->idx] = NULL; riscv_pmu->pmu->stop(event, PERF_EF_UPDATE); perf_event_update_userpage(event); } @@ -385,6 +513,7 @@ static int riscv_event_init(struct perf_event *event) { struct perf_event_attr *attr = &event->attr; struct hw_perf_event *hwc = &event->hw; + unsigned long config_base = 0; int err; int code; @@ -406,11 +535,17 @@ static int riscv_event_init(struct perf_event *event) code = riscv_pmu->map_cache_event(attr->config); break; case PERF_TYPE_RAW: - return -EOPNOTSUPP; + code = attr->config; + break; default: return -ENOENT; } + if (is_base_counter(code)) + config_base |= RISCV_PMU_TYPE_BASE; + else + config_base |= RISCV_PMU_TYPE_EVENT; + event->destroy = riscv_event_destroy; if (code < 0) { event->destroy(event); @@ -424,6 +559,7 @@ static int riscv_event_init(struct perf_event *event) * But since we don't have such support, later in pmu->add(), we just * use hwc->config as the index instead. */ + hwc->config_base = config_base; hwc->config = code; hwc->idx = -1; -- 2.27.0 _______________________________________________ linux-riscv mailing list linux-riscv@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-riscv ^ permalink raw reply related [flat|nested] 38+ messages in thread
* Re: [RFC PATCH 4/6] riscv: perf: Add raw event support 2020-06-29 3:19 ` [RFC PATCH 4/6] riscv: perf: Add raw event support Zong Li @ 2020-06-29 4:17 ` Anup Patel 2020-06-29 4:35 ` Zong Li 0 siblings, 1 reply; 38+ messages in thread From: Anup Patel @ 2020-06-29 4:17 UTC (permalink / raw) To: Zong Li Cc: linux-riscv, Palmer Dabbelt, linux-kernel@vger.kernel.org List, Paul Walmsley On Mon, Jun 29, 2020 at 8:49 AM Zong Li <zong.li@sifive.com> wrote: > > Add support for raw events and hardware cache events. Currently, we set > the events by writing the mhpmeventN CSRs, it would raise an illegal > instruction exception and trap into m-mode to emulate event selector > CSRs access. It doesn't make sense because we shouldn't write the > m-mode CSRs in s-mode, it would be better that set events through SBI > call or the shadow CSRs of s-mode. We would change it later. > > Signed-off-by: Zong Li <zong.li@sifive.com> > --- > arch/riscv/include/asm/perf_event.h | 65 ++++++--- > arch/riscv/kernel/perf_event.c | 204 +++++++++++++++++++++++----- > 2 files changed, 215 insertions(+), 54 deletions(-) > > diff --git a/arch/riscv/include/asm/perf_event.h b/arch/riscv/include/asm/perf_event.h > index 062efd3a1d5d..41d515a1f331 100644 > --- a/arch/riscv/include/asm/perf_event.h > +++ b/arch/riscv/include/asm/perf_event.h > @@ -14,39 +14,64 @@ > > #ifdef CONFIG_RISCV_BASE_PMU > #define RISCV_BASE_COUNTERS 2 > +#define RISCV_EVENT_COUNTERS 29 Same comment as DT documentation related to naming. Regards, Anup > +#define RISCV_TOTAL_COUNTERS (RISCV_BASE_COUNTERS + RISCV_EVENT_COUNTERS) > > /* > - * The RISCV_MAX_COUNTERS parameter should be specified. > - */ > - > -#define RISCV_MAX_COUNTERS 2 > - > -/* > - * These are the indexes of bits in counteren register *minus* 1, > - * except for cycle. It would be coherent if it can directly mapped > - * to counteren bit definition, but there is a *time* register at > - * counteren[1]. Per-cpu structure is scarce resource here. > - * > * According to the spec, an implementation can support counter up to > * mhpmcounter31, but many high-end processors has at most 6 general > * PMCs, we give the definition to MHPMCOUNTER8 here. > */ > -#define RISCV_PMU_CYCLE 0 > -#define RISCV_PMU_INSTRET 1 > -#define RISCV_PMU_MHPMCOUNTER3 2 > -#define RISCV_PMU_MHPMCOUNTER4 3 > -#define RISCV_PMU_MHPMCOUNTER5 4 > -#define RISCV_PMU_MHPMCOUNTER6 5 > -#define RISCV_PMU_MHPMCOUNTER7 6 > -#define RISCV_PMU_MHPMCOUNTER8 7 > +#define RISCV_PMU_CYCLE 0 > +#define RISCV_PMU_INSTRET 2 > +#define RISCV_PMU_HPMCOUNTER3 3 > +#define RISCV_PMU_HPMCOUNTER4 4 > +#define RISCV_PMU_HPMCOUNTER5 5 > +#define RISCV_PMU_HPMCOUNTER6 6 > +#define RISCV_PMU_HPMCOUNTER7 7 > +#define RISCV_PMU_HPMCOUNTER8 8 > + > +#define RISCV_PMU_HPMCOUNTER_FIRST 3 > +#define RISCV_PMU_HPMCOUNTER_LAST \ > + (RISCV_PMU_HPMCOUNTER_FIRST + riscv_pmu->num_counters - 1) > > #define RISCV_OP_UNSUPP (-EOPNOTSUPP) > > +/* Hardware cache event encoding */ > +#define PERF_HW_CACHE_TYPE 0 > +#define PERF_HW_CACHE_OP 8 > +#define PERF_HW_CACHE_RESULT 16 > +#define PERF_HW_CACHE_MASK 0xff > + > +/* config_base encoding */ > +#define RISCV_PMU_TYPE_MASK 0x3 > +#define RISCV_PMU_TYPE_BASE 0x1 > +#define RISCV_PMU_TYPE_EVENT 0x2 > +#define RISCV_PMU_EXCLUDE_MASK 0xc > +#define RISCV_PMU_EXCLUDE_USER 0x3 > +#define RISCV_PMU_EXCLUDE_KERNEL 0x4 > + > +/* > + * Currently, machine-mode supports emulation of mhpmeventN. Setting mhpmeventN > + * to raise an illegal instruction exception to set event types in machine-mode. > + * Eventually, we should set event types through standard SBI call or the shadow > + * CSRs of supervisor-mode, because it is weird for writing CSR of machine-mode > + * explicitly in supervisor-mode. These macro should be removed in the future. > + */ > +#define CSR_MHPMEVENT3 0x323 > +#define CSR_MHPMEVENT4 0x324 > +#define CSR_MHPMEVENT5 0x325 > +#define CSR_MHPMEVENT6 0x326 > +#define CSR_MHPMEVENT7 0x327 > +#define CSR_MHPMEVENT8 0x328 > + > struct cpu_hw_events { > /* # currently enabled events*/ > int n_events; > /* currently enabled events */ > - struct perf_event *events[RISCV_MAX_COUNTERS]; > + struct perf_event *events[RISCV_EVENT_COUNTERS]; > + /* bitmap of used event counters */ > + unsigned long used_cntr_mask; > /* vendor-defined PMU data */ > void *platform; > }; > diff --git a/arch/riscv/kernel/perf_event.c b/arch/riscv/kernel/perf_event.c > index c835f0362d94..0cfcd6f1e57b 100644 > --- a/arch/riscv/kernel/perf_event.c > +++ b/arch/riscv/kernel/perf_event.c > @@ -139,6 +139,53 @@ static const int riscv_cache_event_map[PERF_COUNT_HW_CACHE_MAX] > }, > }; > > +/* > + * Methods for checking and getting PMU information > + */ > + > +static inline int is_base_counter(int idx) > +{ > + return (idx == RISCV_PMU_CYCLE || idx == RISCV_PMU_INSTRET); > +} > + > +static inline int is_event_counter(int idx) > +{ > + return (idx >= RISCV_PMU_HPMCOUNTER_FIRST && > + idx <= RISCV_PMU_HPMCOUNTER_LAST); > +} > + > +static inline int get_available_counter(struct perf_event *event) > +{ > + struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events); > + struct hw_perf_event *hwc = &event->hw; > + unsigned long config_base = hwc->config_base & RISCV_PMU_TYPE_MASK; > + unsigned long mask; > + int ret; > + > + switch (config_base) { > + case RISCV_PMU_TYPE_BASE: > + ret = hwc->config; > + if (WARN_ON_ONCE(!is_base_counter(ret))) > + return -ENOSPC; > + break; > + case RISCV_PMU_TYPE_EVENT: > + mask = ~cpuc->used_cntr_mask; > + ret = find_next_bit(&mask, RISCV_PMU_HPMCOUNTER_LAST, 3); > + if (WARN_ON_ONCE(!is_event_counter(ret))) > + return -ENOSPC; > + break; > + default: > + return -ENOENT; > + } > + > + __set_bit(ret, &cpuc->used_cntr_mask); > + > + return ret; > +} > + > +/* > + * Map generic hardware event > + */ > static int riscv_map_hw_event(u64 config) > { > if (config >= riscv_pmu->max_events) > @@ -147,32 +194,28 @@ static int riscv_map_hw_event(u64 config) > return riscv_pmu->hw_events[config]; > } > > -static int riscv_map_cache_decode(u64 config, unsigned int *type, > - unsigned int *op, unsigned int *result) > -{ > - return -ENOENT; > -} > - > +/* > + * Map generic hardware cache event > + */ > static int riscv_map_cache_event(u64 config) > { > unsigned int type, op, result; > - int err = -ENOENT; > - int code; > + int ret; > > - err = riscv_map_cache_decode(config, &type, &op, &result); > - if (!riscv_pmu->cache_events || err) > - return err; > + type = (config >> PERF_HW_CACHE_TYPE) & PERF_HW_CACHE_MASK; > + op = (config >> PERF_HW_CACHE_OP) & PERF_HW_CACHE_MASK; > + result = (config >> PERF_HW_CACHE_RESULT) & PERF_HW_CACHE_MASK; > > if (type >= PERF_COUNT_HW_CACHE_MAX || > op >= PERF_COUNT_HW_CACHE_OP_MAX || > result >= PERF_COUNT_HW_CACHE_RESULT_MAX) > return -EINVAL; > > - code = (*riscv_pmu->cache_events)[type][op][result]; > - if (code == RISCV_OP_UNSUPP) > + ret = riscv_cache_event_map[type][op][result]; > + if (ret == RISCV_OP_UNSUPP) > return -EINVAL; > > - return code; > + return ret == RISCV_OP_UNSUPP ? -ENOENT : ret; > } > > /* > @@ -190,8 +233,27 @@ static inline u64 read_counter(int idx) > case RISCV_PMU_INSTRET: > val = csr_read(CSR_INSTRET); > break; > + case RISCV_PMU_HPMCOUNTER3: > + val = csr_read(CSR_HPMCOUNTER3); > + break; > + case RISCV_PMU_HPMCOUNTER4: > + val = csr_read(CSR_HPMCOUNTER4); > + break; > + case RISCV_PMU_HPMCOUNTER5: > + val = csr_read(CSR_HPMCOUNTER5); > + break; > + case RISCV_PMU_HPMCOUNTER6: > + val = csr_read(CSR_HPMCOUNTER6); > + break; > + case RISCV_PMU_HPMCOUNTER7: > + val = csr_read(CSR_HPMCOUNTER7); > + break; > + case RISCV_PMU_HPMCOUNTER8: > + val = csr_read(CSR_HPMCOUNTER8); This is broken for RV32 because for RV32 we have to read two CSRs to get a counter value. Also, for correctly reading a 64bit counter on RV32 we have to read just like get_cycles64() does for RV32. static inline u64 get_cycles64(void) { u32 hi, lo; do { hi = get_cycles_hi(); lo = get_cycles(); } while (hi != get_cycles_hi()); return ((u64)hi << 32) | lo; } Regards, Anup > + break; > default: > - WARN_ON_ONCE(idx < 0 || idx > RISCV_MAX_COUNTERS); > + WARN_ON_ONCE(idx < RISCV_PMU_CYCLE || > + idx > RISCV_TOTAL_COUNTERS); > return -EINVAL; > } > > @@ -204,6 +266,68 @@ static inline void write_counter(int idx, u64 value) > WARN_ON_ONCE(1); > } > > +static inline void write_event(int idx, u64 value) > +{ > + /* TODO: We shouldn't write CSR of m-mode explicitly here. Ideally, > + * it need to set the event selector by SBI call or the s-mode > + * shadow CSRs of them. Exploit illegal instruction exception to > + * emulate mhpmcounterN access in m-mode. > + */ > + switch (idx) { > + case RISCV_PMU_HPMCOUNTER3: > + csr_write(CSR_MHPMEVENT3, value); > + break; > + case RISCV_PMU_HPMCOUNTER4: > + csr_write(CSR_MHPMEVENT4, value); > + break; > + case RISCV_PMU_HPMCOUNTER5: > + csr_write(CSR_MHPMEVENT5, value); > + break; > + case RISCV_PMU_HPMCOUNTER6: > + csr_write(CSR_MHPMEVENT6, value); > + break; > + case RISCV_PMU_HPMCOUNTER7: > + csr_write(CSR_MHPMEVENT7, value); > + break; > + case RISCV_PMU_HPMCOUNTER8: > + csr_write(CSR_MHPMEVENT8, value); > + break; > + default: > + WARN_ON_ONCE(idx < RISCV_PMU_HPMCOUNTER3 || > + idx > RISCV_TOTAL_COUNTERS); > + return; > + } > +} > + > +/* > + * Enable and disable event counters > + */ > + > +static inline void riscv_pmu_enable_event(struct perf_event *event) > +{ > + struct hw_perf_event *hwc = &event->hw; > + int idx = hwc->idx; > + > + if (is_event_counter(idx)) > + write_event(idx, hwc->config); > + > + /* > + * Since we cannot write to counters, this serves as an initialization > + * to the delta-mechanism in pmu->read(); otherwise, the delta would be > + * wrong when pmu->read is called for the first time. > + */ > + local64_set(&hwc->prev_count, read_counter(hwc->idx)); > +} > + > +static inline void riscv_pmu_disable_event(struct perf_event *event) > +{ > + struct hw_perf_event *hwc = &event->hw; > + int idx = hwc->idx; > + > + if (is_event_counter(idx)) > + write_event(idx, 0); > +} > + > /* > * pmu->read: read and update the counter > * > @@ -232,6 +356,7 @@ static void riscv_pmu_read(struct perf_event *event) > */ > delta = (new_raw_count - prev_raw_count) & > ((1ULL << riscv_pmu->counter_width) - 1); > + > local64_add(delta, &event->count); > /* > * Something like local64_sub(delta, &hwc->period_left) here is > @@ -252,6 +377,11 @@ static void riscv_pmu_stop(struct perf_event *event, int flags) > { > struct hw_perf_event *hwc = &event->hw; > > + if (WARN_ON_ONCE(hwc->idx == -1)) > + return; > + > + riscv_pmu_disable_event(event); > + > WARN_ON_ONCE(hwc->state & PERF_HES_STOPPED); > hwc->state |= PERF_HES_STOPPED; > > @@ -271,6 +401,9 @@ static void riscv_pmu_start(struct perf_event *event, int flags) > if (WARN_ON_ONCE(!(event->hw.state & PERF_HES_STOPPED))) > return; > > + if (WARN_ON_ONCE(hwc->idx == -1)) > + return; > + > if (flags & PERF_EF_RELOAD) { > WARN_ON_ONCE(!(event->hw.state & PERF_HES_UPTODATE)); > > @@ -281,14 +414,10 @@ static void riscv_pmu_start(struct perf_event *event, int flags) > } > > hwc->state = 0; > - perf_event_update_userpage(event); > > - /* > - * Since we cannot write to counters, this serves as an initialization > - * to the delta-mechanism in pmu->read(); otherwise, the delta would be > - * wrong when pmu->read is called for the first time. > - */ > - local64_set(&hwc->prev_count, read_counter(hwc->idx)); > + riscv_pmu_enable_event(event); > + > + perf_event_update_userpage(event); > } > > /* > @@ -298,21 +427,18 @@ static int riscv_pmu_add(struct perf_event *event, int flags) > { > struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events); > struct hw_perf_event *hwc = &event->hw; > + int count_idx; > > if (cpuc->n_events == riscv_pmu->num_counters) > return -ENOSPC; > > - /* > - * We don't have general conunters, so no binding-event-to-counter > - * process here. > - * > - * Indexing using hwc->config generally not works, since config may > - * contain extra information, but here the only info we have in > - * hwc->config is the event index. > - */ > - hwc->idx = hwc->config; > - cpuc->events[hwc->idx] = event; > + count_idx = get_available_counter(event); > + if (count_idx < 0) > + return -ENOSPC; > + > cpuc->n_events++; > + hwc->idx = count_idx; > + cpuc->events[hwc->idx] = event; > > hwc->state = PERF_HES_UPTODATE | PERF_HES_STOPPED; > > @@ -330,8 +456,10 @@ static void riscv_pmu_del(struct perf_event *event, int flags) > struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events); > struct hw_perf_event *hwc = &event->hw; > > - cpuc->events[hwc->idx] = NULL; > cpuc->n_events--; > + __clear_bit(hwc->idx, &cpuc->used_cntr_mask); > + > + cpuc->events[hwc->idx] = NULL; > riscv_pmu->pmu->stop(event, PERF_EF_UPDATE); > perf_event_update_userpage(event); > } > @@ -385,6 +513,7 @@ static int riscv_event_init(struct perf_event *event) > { > struct perf_event_attr *attr = &event->attr; > struct hw_perf_event *hwc = &event->hw; > + unsigned long config_base = 0; > int err; > int code; > > @@ -406,11 +535,17 @@ static int riscv_event_init(struct perf_event *event) > code = riscv_pmu->map_cache_event(attr->config); > break; > case PERF_TYPE_RAW: > - return -EOPNOTSUPP; > + code = attr->config; > + break; > default: > return -ENOENT; > } > > + if (is_base_counter(code)) > + config_base |= RISCV_PMU_TYPE_BASE; > + else > + config_base |= RISCV_PMU_TYPE_EVENT; > + > event->destroy = riscv_event_destroy; > if (code < 0) { > event->destroy(event); > @@ -424,6 +559,7 @@ static int riscv_event_init(struct perf_event *event) > * But since we don't have such support, later in pmu->add(), we just > * use hwc->config as the index instead. > */ > + hwc->config_base = config_base; > hwc->config = code; > hwc->idx = -1; > > -- > 2.27.0 > _______________________________________________ linux-riscv mailing list linux-riscv@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-riscv ^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: [RFC PATCH 4/6] riscv: perf: Add raw event support 2020-06-29 4:17 ` Anup Patel @ 2020-06-29 4:35 ` Zong Li 2020-06-29 4:40 ` Anup Patel 0 siblings, 1 reply; 38+ messages in thread From: Zong Li @ 2020-06-29 4:35 UTC (permalink / raw) To: Anup Patel Cc: linux-riscv, Palmer Dabbelt, linux-kernel@vger.kernel.org List, Paul Walmsley On Mon, Jun 29, 2020 at 12:17 PM Anup Patel <anup@brainfault.org> wrote: > > On Mon, Jun 29, 2020 at 8:49 AM Zong Li <zong.li@sifive.com> wrote: > > > > Add support for raw events and hardware cache events. Currently, we set > > the events by writing the mhpmeventN CSRs, it would raise an illegal > > instruction exception and trap into m-mode to emulate event selector > > CSRs access. It doesn't make sense because we shouldn't write the > > m-mode CSRs in s-mode, it would be better that set events through SBI > > call or the shadow CSRs of s-mode. We would change it later. > > > > Signed-off-by: Zong Li <zong.li@sifive.com> > > --- > > arch/riscv/include/asm/perf_event.h | 65 ++++++--- > > arch/riscv/kernel/perf_event.c | 204 +++++++++++++++++++++++----- > > 2 files changed, 215 insertions(+), 54 deletions(-) > > > > diff --git a/arch/riscv/include/asm/perf_event.h b/arch/riscv/include/asm/perf_event.h > > index 062efd3a1d5d..41d515a1f331 100644 > > --- a/arch/riscv/include/asm/perf_event.h > > +++ b/arch/riscv/include/asm/perf_event.h > > @@ -14,39 +14,64 @@ > > > > #ifdef CONFIG_RISCV_BASE_PMU > > #define RISCV_BASE_COUNTERS 2 > > +#define RISCV_EVENT_COUNTERS 29 > > Same comment as DT documentation related to naming. Change it as well. Thanks. > > Regards, > Anup > > > > +#define RISCV_TOTAL_COUNTERS (RISCV_BASE_COUNTERS + RISCV_EVENT_COUNTERS) > > > > /* > > - * The RISCV_MAX_COUNTERS parameter should be specified. > > - */ > > - > > -#define RISCV_MAX_COUNTERS 2 > > - > > -/* > > - * These are the indexes of bits in counteren register *minus* 1, > > - * except for cycle. It would be coherent if it can directly mapped > > - * to counteren bit definition, but there is a *time* register at > > - * counteren[1]. Per-cpu structure is scarce resource here. > > - * > > * According to the spec, an implementation can support counter up to > > * mhpmcounter31, but many high-end processors has at most 6 general > > * PMCs, we give the definition to MHPMCOUNTER8 here. > > */ > > -#define RISCV_PMU_CYCLE 0 > > -#define RISCV_PMU_INSTRET 1 > > -#define RISCV_PMU_MHPMCOUNTER3 2 > > -#define RISCV_PMU_MHPMCOUNTER4 3 > > -#define RISCV_PMU_MHPMCOUNTER5 4 > > -#define RISCV_PMU_MHPMCOUNTER6 5 > > -#define RISCV_PMU_MHPMCOUNTER7 6 > > -#define RISCV_PMU_MHPMCOUNTER8 7 > > +#define RISCV_PMU_CYCLE 0 > > +#define RISCV_PMU_INSTRET 2 > > +#define RISCV_PMU_HPMCOUNTER3 3 > > +#define RISCV_PMU_HPMCOUNTER4 4 > > +#define RISCV_PMU_HPMCOUNTER5 5 > > +#define RISCV_PMU_HPMCOUNTER6 6 > > +#define RISCV_PMU_HPMCOUNTER7 7 > > +#define RISCV_PMU_HPMCOUNTER8 8 > > + > > +#define RISCV_PMU_HPMCOUNTER_FIRST 3 > > +#define RISCV_PMU_HPMCOUNTER_LAST \ > > + (RISCV_PMU_HPMCOUNTER_FIRST + riscv_pmu->num_counters - 1) > > > > #define RISCV_OP_UNSUPP (-EOPNOTSUPP) > > > > +/* Hardware cache event encoding */ > > +#define PERF_HW_CACHE_TYPE 0 > > +#define PERF_HW_CACHE_OP 8 > > +#define PERF_HW_CACHE_RESULT 16 > > +#define PERF_HW_CACHE_MASK 0xff > > + > > +/* config_base encoding */ > > +#define RISCV_PMU_TYPE_MASK 0x3 > > +#define RISCV_PMU_TYPE_BASE 0x1 > > +#define RISCV_PMU_TYPE_EVENT 0x2 > > +#define RISCV_PMU_EXCLUDE_MASK 0xc > > +#define RISCV_PMU_EXCLUDE_USER 0x3 > > +#define RISCV_PMU_EXCLUDE_KERNEL 0x4 > > + > > +/* > > + * Currently, machine-mode supports emulation of mhpmeventN. Setting mhpmeventN > > + * to raise an illegal instruction exception to set event types in machine-mode. > > + * Eventually, we should set event types through standard SBI call or the shadow > > + * CSRs of supervisor-mode, because it is weird for writing CSR of machine-mode > > + * explicitly in supervisor-mode. These macro should be removed in the future. > > + */ > > +#define CSR_MHPMEVENT3 0x323 > > +#define CSR_MHPMEVENT4 0x324 > > +#define CSR_MHPMEVENT5 0x325 > > +#define CSR_MHPMEVENT6 0x326 > > +#define CSR_MHPMEVENT7 0x327 > > +#define CSR_MHPMEVENT8 0x328 > > + > > struct cpu_hw_events { > > /* # currently enabled events*/ > > int n_events; > > /* currently enabled events */ > > - struct perf_event *events[RISCV_MAX_COUNTERS]; > > + struct perf_event *events[RISCV_EVENT_COUNTERS]; > > + /* bitmap of used event counters */ > > + unsigned long used_cntr_mask; > > /* vendor-defined PMU data */ > > void *platform; > > }; > > diff --git a/arch/riscv/kernel/perf_event.c b/arch/riscv/kernel/perf_event.c > > index c835f0362d94..0cfcd6f1e57b 100644 > > --- a/arch/riscv/kernel/perf_event.c > > +++ b/arch/riscv/kernel/perf_event.c > > @@ -139,6 +139,53 @@ static const int riscv_cache_event_map[PERF_COUNT_HW_CACHE_MAX] > > }, > > }; > > > > +/* > > + * Methods for checking and getting PMU information > > + */ > > + > > +static inline int is_base_counter(int idx) > > +{ > > + return (idx == RISCV_PMU_CYCLE || idx == RISCV_PMU_INSTRET); > > +} > > + > > +static inline int is_event_counter(int idx) > > +{ > > + return (idx >= RISCV_PMU_HPMCOUNTER_FIRST && > > + idx <= RISCV_PMU_HPMCOUNTER_LAST); > > +} > > + > > +static inline int get_available_counter(struct perf_event *event) > > +{ > > + struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events); > > + struct hw_perf_event *hwc = &event->hw; > > + unsigned long config_base = hwc->config_base & RISCV_PMU_TYPE_MASK; > > + unsigned long mask; > > + int ret; > > + > > + switch (config_base) { > > + case RISCV_PMU_TYPE_BASE: > > + ret = hwc->config; > > + if (WARN_ON_ONCE(!is_base_counter(ret))) > > + return -ENOSPC; > > + break; > > + case RISCV_PMU_TYPE_EVENT: > > + mask = ~cpuc->used_cntr_mask; > > + ret = find_next_bit(&mask, RISCV_PMU_HPMCOUNTER_LAST, 3); > > + if (WARN_ON_ONCE(!is_event_counter(ret))) > > + return -ENOSPC; > > + break; > > + default: > > + return -ENOENT; > > + } > > + > > + __set_bit(ret, &cpuc->used_cntr_mask); > > + > > + return ret; > > +} > > + > > +/* > > + * Map generic hardware event > > + */ > > static int riscv_map_hw_event(u64 config) > > { > > if (config >= riscv_pmu->max_events) > > @@ -147,32 +194,28 @@ static int riscv_map_hw_event(u64 config) > > return riscv_pmu->hw_events[config]; > > } > > > > -static int riscv_map_cache_decode(u64 config, unsigned int *type, > > - unsigned int *op, unsigned int *result) > > -{ > > - return -ENOENT; > > -} > > - > > +/* > > + * Map generic hardware cache event > > + */ > > static int riscv_map_cache_event(u64 config) > > { > > unsigned int type, op, result; > > - int err = -ENOENT; > > - int code; > > + int ret; > > > > - err = riscv_map_cache_decode(config, &type, &op, &result); > > - if (!riscv_pmu->cache_events || err) > > - return err; > > + type = (config >> PERF_HW_CACHE_TYPE) & PERF_HW_CACHE_MASK; > > + op = (config >> PERF_HW_CACHE_OP) & PERF_HW_CACHE_MASK; > > + result = (config >> PERF_HW_CACHE_RESULT) & PERF_HW_CACHE_MASK; > > > > if (type >= PERF_COUNT_HW_CACHE_MAX || > > op >= PERF_COUNT_HW_CACHE_OP_MAX || > > result >= PERF_COUNT_HW_CACHE_RESULT_MAX) > > return -EINVAL; > > > > - code = (*riscv_pmu->cache_events)[type][op][result]; > > - if (code == RISCV_OP_UNSUPP) > > + ret = riscv_cache_event_map[type][op][result]; > > + if (ret == RISCV_OP_UNSUPP) > > return -EINVAL; > > > > - return code; > > + return ret == RISCV_OP_UNSUPP ? -ENOENT : ret; > > } > > > > /* > > @@ -190,8 +233,27 @@ static inline u64 read_counter(int idx) > > case RISCV_PMU_INSTRET: > > val = csr_read(CSR_INSTRET); > > break; > > + case RISCV_PMU_HPMCOUNTER3: > > + val = csr_read(CSR_HPMCOUNTER3); > > + break; > > + case RISCV_PMU_HPMCOUNTER4: > > + val = csr_read(CSR_HPMCOUNTER4); > > + break; > > + case RISCV_PMU_HPMCOUNTER5: > > + val = csr_read(CSR_HPMCOUNTER5); > > + break; > > + case RISCV_PMU_HPMCOUNTER6: > > + val = csr_read(CSR_HPMCOUNTER6); > > + break; > > + case RISCV_PMU_HPMCOUNTER7: > > + val = csr_read(CSR_HPMCOUNTER7); > > + break; > > + case RISCV_PMU_HPMCOUNTER8: > > + val = csr_read(CSR_HPMCOUNTER8); > > This is broken for RV32 because for RV32 we have to read two > CSRs to get a counter value. Oh yes, thanks for your reminder. Add them in the next version. > > Also, for correctly reading a 64bit counter on RV32 we have > to read just like get_cycles64() does for RV32. > > static inline u64 get_cycles64(void) > { > u32 hi, lo; > > do { > hi = get_cycles_hi(); > lo = get_cycles(); > } while (hi != get_cycles_hi()); > > return ((u64)hi << 32) | lo; > } > > Regards, > Anup > > > > + break; > > default: > > - WARN_ON_ONCE(idx < 0 || idx > RISCV_MAX_COUNTERS); > > + WARN_ON_ONCE(idx < RISCV_PMU_CYCLE || > > + idx > RISCV_TOTAL_COUNTERS); > > return -EINVAL; > > } > > > > @@ -204,6 +266,68 @@ static inline void write_counter(int idx, u64 value) > > WARN_ON_ONCE(1); > > } > > > > +static inline void write_event(int idx, u64 value) > > +{ > > + /* TODO: We shouldn't write CSR of m-mode explicitly here. Ideally, > > + * it need to set the event selector by SBI call or the s-mode > > + * shadow CSRs of them. Exploit illegal instruction exception to > > + * emulate mhpmcounterN access in m-mode. > > + */ > > + switch (idx) { > > + case RISCV_PMU_HPMCOUNTER3: > > + csr_write(CSR_MHPMEVENT3, value); > > + break; > > + case RISCV_PMU_HPMCOUNTER4: > > + csr_write(CSR_MHPMEVENT4, value); > > + break; > > + case RISCV_PMU_HPMCOUNTER5: > > + csr_write(CSR_MHPMEVENT5, value); > > + break; > > + case RISCV_PMU_HPMCOUNTER6: > > + csr_write(CSR_MHPMEVENT6, value); > > + break; > > + case RISCV_PMU_HPMCOUNTER7: > > + csr_write(CSR_MHPMEVENT7, value); > > + break; > > + case RISCV_PMU_HPMCOUNTER8: > > + csr_write(CSR_MHPMEVENT8, value); > > + break; > > + default: > > + WARN_ON_ONCE(idx < RISCV_PMU_HPMCOUNTER3 || > > + idx > RISCV_TOTAL_COUNTERS); > > + return; > > + } > > +} I was also wondering if you have any suggestions about the PMU SBI extension as I mentioned in the cover letter. Currently, we set the event selectors by emulation of OpenSBI, so just write the m-mode CSRs as above. > > + > > +/* > > + * Enable and disable event counters > > + */ > > + > > +static inline void riscv_pmu_enable_event(struct perf_event *event) > > +{ > > + struct hw_perf_event *hwc = &event->hw; > > + int idx = hwc->idx; > > + > > + if (is_event_counter(idx)) > > + write_event(idx, hwc->config); > > + > > + /* > > + * Since we cannot write to counters, this serves as an initialization > > + * to the delta-mechanism in pmu->read(); otherwise, the delta would be > > + * wrong when pmu->read is called for the first time. > > + */ > > + local64_set(&hwc->prev_count, read_counter(hwc->idx)); > > +} > > + > > +static inline void riscv_pmu_disable_event(struct perf_event *event) > > +{ > > + struct hw_perf_event *hwc = &event->hw; > > + int idx = hwc->idx; > > + > > + if (is_event_counter(idx)) > > + write_event(idx, 0); > > +} > > + > > /* > > * pmu->read: read and update the counter > > * > > @@ -232,6 +356,7 @@ static void riscv_pmu_read(struct perf_event *event) > > */ > > delta = (new_raw_count - prev_raw_count) & > > ((1ULL << riscv_pmu->counter_width) - 1); > > + > > local64_add(delta, &event->count); > > /* > > * Something like local64_sub(delta, &hwc->period_left) here is > > @@ -252,6 +377,11 @@ static void riscv_pmu_stop(struct perf_event *event, int flags) > > { > > struct hw_perf_event *hwc = &event->hw; > > > > + if (WARN_ON_ONCE(hwc->idx == -1)) > > + return; > > + > > + riscv_pmu_disable_event(event); > > + > > WARN_ON_ONCE(hwc->state & PERF_HES_STOPPED); > > hwc->state |= PERF_HES_STOPPED; > > > > @@ -271,6 +401,9 @@ static void riscv_pmu_start(struct perf_event *event, int flags) > > if (WARN_ON_ONCE(!(event->hw.state & PERF_HES_STOPPED))) > > return; > > > > + if (WARN_ON_ONCE(hwc->idx == -1)) > > + return; > > + > > if (flags & PERF_EF_RELOAD) { > > WARN_ON_ONCE(!(event->hw.state & PERF_HES_UPTODATE)); > > > > @@ -281,14 +414,10 @@ static void riscv_pmu_start(struct perf_event *event, int flags) > > } > > > > hwc->state = 0; > > - perf_event_update_userpage(event); > > > > - /* > > - * Since we cannot write to counters, this serves as an initialization > > - * to the delta-mechanism in pmu->read(); otherwise, the delta would be > > - * wrong when pmu->read is called for the first time. > > - */ > > - local64_set(&hwc->prev_count, read_counter(hwc->idx)); > > + riscv_pmu_enable_event(event); > > + > > + perf_event_update_userpage(event); > > } > > > > /* > > @@ -298,21 +427,18 @@ static int riscv_pmu_add(struct perf_event *event, int flags) > > { > > struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events); > > struct hw_perf_event *hwc = &event->hw; > > + int count_idx; > > > > if (cpuc->n_events == riscv_pmu->num_counters) > > return -ENOSPC; > > > > - /* > > - * We don't have general conunters, so no binding-event-to-counter > > - * process here. > > - * > > - * Indexing using hwc->config generally not works, since config may > > - * contain extra information, but here the only info we have in > > - * hwc->config is the event index. > > - */ > > - hwc->idx = hwc->config; > > - cpuc->events[hwc->idx] = event; > > + count_idx = get_available_counter(event); > > + if (count_idx < 0) > > + return -ENOSPC; > > + > > cpuc->n_events++; > > + hwc->idx = count_idx; > > + cpuc->events[hwc->idx] = event; > > > > hwc->state = PERF_HES_UPTODATE | PERF_HES_STOPPED; > > > > @@ -330,8 +456,10 @@ static void riscv_pmu_del(struct perf_event *event, int flags) > > struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events); > > struct hw_perf_event *hwc = &event->hw; > > > > - cpuc->events[hwc->idx] = NULL; > > cpuc->n_events--; > > + __clear_bit(hwc->idx, &cpuc->used_cntr_mask); > > + > > + cpuc->events[hwc->idx] = NULL; > > riscv_pmu->pmu->stop(event, PERF_EF_UPDATE); > > perf_event_update_userpage(event); > > } > > @@ -385,6 +513,7 @@ static int riscv_event_init(struct perf_event *event) > > { > > struct perf_event_attr *attr = &event->attr; > > struct hw_perf_event *hwc = &event->hw; > > + unsigned long config_base = 0; > > int err; > > int code; > > > > @@ -406,11 +535,17 @@ static int riscv_event_init(struct perf_event *event) > > code = riscv_pmu->map_cache_event(attr->config); > > break; > > case PERF_TYPE_RAW: > > - return -EOPNOTSUPP; > > + code = attr->config; > > + break; > > default: > > return -ENOENT; > > } > > > > + if (is_base_counter(code)) > > + config_base |= RISCV_PMU_TYPE_BASE; > > + else > > + config_base |= RISCV_PMU_TYPE_EVENT; > > + > > event->destroy = riscv_event_destroy; > > if (code < 0) { > > event->destroy(event); > > @@ -424,6 +559,7 @@ static int riscv_event_init(struct perf_event *event) > > * But since we don't have such support, later in pmu->add(), we just > > * use hwc->config as the index instead. > > */ > > + hwc->config_base = config_base; > > hwc->config = code; > > hwc->idx = -1; > > > > -- > > 2.27.0 > > _______________________________________________ linux-riscv mailing list linux-riscv@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-riscv ^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: [RFC PATCH 4/6] riscv: perf: Add raw event support 2020-06-29 4:35 ` Zong Li @ 2020-06-29 4:40 ` Anup Patel 0 siblings, 0 replies; 38+ messages in thread From: Anup Patel @ 2020-06-29 4:40 UTC (permalink / raw) To: Zong Li Cc: linux-riscv, Palmer Dabbelt, linux-kernel@vger.kernel.org List, Paul Walmsley On Mon, Jun 29, 2020 at 10:05 AM Zong Li <zong.li@sifive.com> wrote: > > On Mon, Jun 29, 2020 at 12:17 PM Anup Patel <anup@brainfault.org> wrote: > > > > On Mon, Jun 29, 2020 at 8:49 AM Zong Li <zong.li@sifive.com> wrote: > > > > > > Add support for raw events and hardware cache events. Currently, we set > > > the events by writing the mhpmeventN CSRs, it would raise an illegal > > > instruction exception and trap into m-mode to emulate event selector > > > CSRs access. It doesn't make sense because we shouldn't write the > > > m-mode CSRs in s-mode, it would be better that set events through SBI > > > call or the shadow CSRs of s-mode. We would change it later. > > > > > > Signed-off-by: Zong Li <zong.li@sifive.com> > > > --- > > > arch/riscv/include/asm/perf_event.h | 65 ++++++--- > > > arch/riscv/kernel/perf_event.c | 204 +++++++++++++++++++++++----- > > > 2 files changed, 215 insertions(+), 54 deletions(-) > > > > > > diff --git a/arch/riscv/include/asm/perf_event.h b/arch/riscv/include/asm/perf_event.h > > > index 062efd3a1d5d..41d515a1f331 100644 > > > --- a/arch/riscv/include/asm/perf_event.h > > > +++ b/arch/riscv/include/asm/perf_event.h > > > @@ -14,39 +14,64 @@ > > > > > > #ifdef CONFIG_RISCV_BASE_PMU > > > #define RISCV_BASE_COUNTERS 2 > > > +#define RISCV_EVENT_COUNTERS 29 > > > > Same comment as DT documentation related to naming. > > Change it as well. Thanks. > > > > > Regards, > > Anup > > > > > > > +#define RISCV_TOTAL_COUNTERS (RISCV_BASE_COUNTERS + RISCV_EVENT_COUNTERS) > > > > > > /* > > > - * The RISCV_MAX_COUNTERS parameter should be specified. > > > - */ > > > - > > > -#define RISCV_MAX_COUNTERS 2 > > > - > > > -/* > > > - * These are the indexes of bits in counteren register *minus* 1, > > > - * except for cycle. It would be coherent if it can directly mapped > > > - * to counteren bit definition, but there is a *time* register at > > > - * counteren[1]. Per-cpu structure is scarce resource here. > > > - * > > > * According to the spec, an implementation can support counter up to > > > * mhpmcounter31, but many high-end processors has at most 6 general > > > * PMCs, we give the definition to MHPMCOUNTER8 here. > > > */ > > > -#define RISCV_PMU_CYCLE 0 > > > -#define RISCV_PMU_INSTRET 1 > > > -#define RISCV_PMU_MHPMCOUNTER3 2 > > > -#define RISCV_PMU_MHPMCOUNTER4 3 > > > -#define RISCV_PMU_MHPMCOUNTER5 4 > > > -#define RISCV_PMU_MHPMCOUNTER6 5 > > > -#define RISCV_PMU_MHPMCOUNTER7 6 > > > -#define RISCV_PMU_MHPMCOUNTER8 7 > > > +#define RISCV_PMU_CYCLE 0 > > > +#define RISCV_PMU_INSTRET 2 > > > +#define RISCV_PMU_HPMCOUNTER3 3 > > > +#define RISCV_PMU_HPMCOUNTER4 4 > > > +#define RISCV_PMU_HPMCOUNTER5 5 > > > +#define RISCV_PMU_HPMCOUNTER6 6 > > > +#define RISCV_PMU_HPMCOUNTER7 7 > > > +#define RISCV_PMU_HPMCOUNTER8 8 > > > + > > > +#define RISCV_PMU_HPMCOUNTER_FIRST 3 > > > +#define RISCV_PMU_HPMCOUNTER_LAST \ > > > + (RISCV_PMU_HPMCOUNTER_FIRST + riscv_pmu->num_counters - 1) > > > > > > #define RISCV_OP_UNSUPP (-EOPNOTSUPP) > > > > > > +/* Hardware cache event encoding */ > > > +#define PERF_HW_CACHE_TYPE 0 > > > +#define PERF_HW_CACHE_OP 8 > > > +#define PERF_HW_CACHE_RESULT 16 > > > +#define PERF_HW_CACHE_MASK 0xff > > > + > > > +/* config_base encoding */ > > > +#define RISCV_PMU_TYPE_MASK 0x3 > > > +#define RISCV_PMU_TYPE_BASE 0x1 > > > +#define RISCV_PMU_TYPE_EVENT 0x2 > > > +#define RISCV_PMU_EXCLUDE_MASK 0xc > > > +#define RISCV_PMU_EXCLUDE_USER 0x3 > > > +#define RISCV_PMU_EXCLUDE_KERNEL 0x4 > > > + > > > +/* > > > + * Currently, machine-mode supports emulation of mhpmeventN. Setting mhpmeventN > > > + * to raise an illegal instruction exception to set event types in machine-mode. > > > + * Eventually, we should set event types through standard SBI call or the shadow > > > + * CSRs of supervisor-mode, because it is weird for writing CSR of machine-mode > > > + * explicitly in supervisor-mode. These macro should be removed in the future. > > > + */ > > > +#define CSR_MHPMEVENT3 0x323 > > > +#define CSR_MHPMEVENT4 0x324 > > > +#define CSR_MHPMEVENT5 0x325 > > > +#define CSR_MHPMEVENT6 0x326 > > > +#define CSR_MHPMEVENT7 0x327 > > > +#define CSR_MHPMEVENT8 0x328 > > > + > > > struct cpu_hw_events { > > > /* # currently enabled events*/ > > > int n_events; > > > /* currently enabled events */ > > > - struct perf_event *events[RISCV_MAX_COUNTERS]; > > > + struct perf_event *events[RISCV_EVENT_COUNTERS]; > > > + /* bitmap of used event counters */ > > > + unsigned long used_cntr_mask; > > > /* vendor-defined PMU data */ > > > void *platform; > > > }; > > > diff --git a/arch/riscv/kernel/perf_event.c b/arch/riscv/kernel/perf_event.c > > > index c835f0362d94..0cfcd6f1e57b 100644 > > > --- a/arch/riscv/kernel/perf_event.c > > > +++ b/arch/riscv/kernel/perf_event.c > > > @@ -139,6 +139,53 @@ static const int riscv_cache_event_map[PERF_COUNT_HW_CACHE_MAX] > > > }, > > > }; > > > > > > +/* > > > + * Methods for checking and getting PMU information > > > + */ > > > + > > > +static inline int is_base_counter(int idx) > > > +{ > > > + return (idx == RISCV_PMU_CYCLE || idx == RISCV_PMU_INSTRET); > > > +} > > > + > > > +static inline int is_event_counter(int idx) > > > +{ > > > + return (idx >= RISCV_PMU_HPMCOUNTER_FIRST && > > > + idx <= RISCV_PMU_HPMCOUNTER_LAST); > > > +} > > > + > > > +static inline int get_available_counter(struct perf_event *event) > > > +{ > > > + struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events); > > > + struct hw_perf_event *hwc = &event->hw; > > > + unsigned long config_base = hwc->config_base & RISCV_PMU_TYPE_MASK; > > > + unsigned long mask; > > > + int ret; > > > + > > > + switch (config_base) { > > > + case RISCV_PMU_TYPE_BASE: > > > + ret = hwc->config; > > > + if (WARN_ON_ONCE(!is_base_counter(ret))) > > > + return -ENOSPC; > > > + break; > > > + case RISCV_PMU_TYPE_EVENT: > > > + mask = ~cpuc->used_cntr_mask; > > > + ret = find_next_bit(&mask, RISCV_PMU_HPMCOUNTER_LAST, 3); > > > + if (WARN_ON_ONCE(!is_event_counter(ret))) > > > + return -ENOSPC; > > > + break; > > > + default: > > > + return -ENOENT; > > > + } > > > + > > > + __set_bit(ret, &cpuc->used_cntr_mask); > > > + > > > + return ret; > > > +} > > > + > > > +/* > > > + * Map generic hardware event > > > + */ > > > static int riscv_map_hw_event(u64 config) > > > { > > > if (config >= riscv_pmu->max_events) > > > @@ -147,32 +194,28 @@ static int riscv_map_hw_event(u64 config) > > > return riscv_pmu->hw_events[config]; > > > } > > > > > > -static int riscv_map_cache_decode(u64 config, unsigned int *type, > > > - unsigned int *op, unsigned int *result) > > > -{ > > > - return -ENOENT; > > > -} > > > - > > > +/* > > > + * Map generic hardware cache event > > > + */ > > > static int riscv_map_cache_event(u64 config) > > > { > > > unsigned int type, op, result; > > > - int err = -ENOENT; > > > - int code; > > > + int ret; > > > > > > - err = riscv_map_cache_decode(config, &type, &op, &result); > > > - if (!riscv_pmu->cache_events || err) > > > - return err; > > > + type = (config >> PERF_HW_CACHE_TYPE) & PERF_HW_CACHE_MASK; > > > + op = (config >> PERF_HW_CACHE_OP) & PERF_HW_CACHE_MASK; > > > + result = (config >> PERF_HW_CACHE_RESULT) & PERF_HW_CACHE_MASK; > > > > > > if (type >= PERF_COUNT_HW_CACHE_MAX || > > > op >= PERF_COUNT_HW_CACHE_OP_MAX || > > > result >= PERF_COUNT_HW_CACHE_RESULT_MAX) > > > return -EINVAL; > > > > > > - code = (*riscv_pmu->cache_events)[type][op][result]; > > > - if (code == RISCV_OP_UNSUPP) > > > + ret = riscv_cache_event_map[type][op][result]; > > > + if (ret == RISCV_OP_UNSUPP) > > > return -EINVAL; > > > > > > - return code; > > > + return ret == RISCV_OP_UNSUPP ? -ENOENT : ret; > > > } > > > > > > /* > > > @@ -190,8 +233,27 @@ static inline u64 read_counter(int idx) > > > case RISCV_PMU_INSTRET: > > > val = csr_read(CSR_INSTRET); > > > break; > > > + case RISCV_PMU_HPMCOUNTER3: > > > + val = csr_read(CSR_HPMCOUNTER3); > > > + break; > > > + case RISCV_PMU_HPMCOUNTER4: > > > + val = csr_read(CSR_HPMCOUNTER4); > > > + break; > > > + case RISCV_PMU_HPMCOUNTER5: > > > + val = csr_read(CSR_HPMCOUNTER5); > > > + break; > > > + case RISCV_PMU_HPMCOUNTER6: > > > + val = csr_read(CSR_HPMCOUNTER6); > > > + break; > > > + case RISCV_PMU_HPMCOUNTER7: > > > + val = csr_read(CSR_HPMCOUNTER7); > > > + break; > > > + case RISCV_PMU_HPMCOUNTER8: > > > + val = csr_read(CSR_HPMCOUNTER8); > > > > This is broken for RV32 because for RV32 we have to read two > > CSRs to get a counter value. > > Oh yes, thanks for your reminder. Add them in the next version. > > > > > Also, for correctly reading a 64bit counter on RV32 we have > > to read just like get_cycles64() does for RV32. > > > > static inline u64 get_cycles64(void) > > { > > u32 hi, lo; > > > > do { > > hi = get_cycles_hi(); > > lo = get_cycles(); > > } while (hi != get_cycles_hi()); > > > > return ((u64)hi << 32) | lo; > > } > > > > Regards, > > Anup > > > > > > > + break; > > > default: > > > - WARN_ON_ONCE(idx < 0 || idx > RISCV_MAX_COUNTERS); > > > + WARN_ON_ONCE(idx < RISCV_PMU_CYCLE || > > > + idx > RISCV_TOTAL_COUNTERS); > > > return -EINVAL; > > > } > > > > > > @@ -204,6 +266,68 @@ static inline void write_counter(int idx, u64 value) > > > WARN_ON_ONCE(1); > > > } > > > > > > +static inline void write_event(int idx, u64 value) > > > +{ > > > + /* TODO: We shouldn't write CSR of m-mode explicitly here. Ideally, > > > + * it need to set the event selector by SBI call or the s-mode > > > + * shadow CSRs of them. Exploit illegal instruction exception to > > > + * emulate mhpmcounterN access in m-mode. > > > + */ > > > + switch (idx) { > > > + case RISCV_PMU_HPMCOUNTER3: > > > + csr_write(CSR_MHPMEVENT3, value); > > > + break; > > > + case RISCV_PMU_HPMCOUNTER4: > > > + csr_write(CSR_MHPMEVENT4, value); > > > + break; > > > + case RISCV_PMU_HPMCOUNTER5: > > > + csr_write(CSR_MHPMEVENT5, value); > > > + break; > > > + case RISCV_PMU_HPMCOUNTER6: > > > + csr_write(CSR_MHPMEVENT6, value); > > > + break; > > > + case RISCV_PMU_HPMCOUNTER7: > > > + csr_write(CSR_MHPMEVENT7, value); > > > + break; > > > + case RISCV_PMU_HPMCOUNTER8: > > > + csr_write(CSR_MHPMEVENT8, value); > > > + break; > > > + default: > > > + WARN_ON_ONCE(idx < RISCV_PMU_HPMCOUNTER3 || > > > + idx > RISCV_TOTAL_COUNTERS); > > > + return; > > > + } > > > +} > > I was also wondering if you have any suggestions about the PMU SBI > extension as I mentioned in the cover letter. Currently, we set the > event selectors by emulation of OpenSBI, so just write the m-mode CSRs > as above. That's a separate topic but design of this driver will pave way for defining SBI perf counter calls. Let's get this driver in good shape first so that it helps us in defining SBI calls for SBI-level perf counters. Regards, Anup > > > > + > > > +/* > > > + * Enable and disable event counters > > > + */ > > > + > > > +static inline void riscv_pmu_enable_event(struct perf_event *event) > > > +{ > > > + struct hw_perf_event *hwc = &event->hw; > > > + int idx = hwc->idx; > > > + > > > + if (is_event_counter(idx)) > > > + write_event(idx, hwc->config); > > > + > > > + /* > > > + * Since we cannot write to counters, this serves as an initialization > > > + * to the delta-mechanism in pmu->read(); otherwise, the delta would be > > > + * wrong when pmu->read is called for the first time. > > > + */ > > > + local64_set(&hwc->prev_count, read_counter(hwc->idx)); > > > +} > > > + > > > +static inline void riscv_pmu_disable_event(struct perf_event *event) > > > +{ > > > + struct hw_perf_event *hwc = &event->hw; > > > + int idx = hwc->idx; > > > + > > > + if (is_event_counter(idx)) > > > + write_event(idx, 0); > > > +} > > > + > > > /* > > > * pmu->read: read and update the counter > > > * > > > @@ -232,6 +356,7 @@ static void riscv_pmu_read(struct perf_event *event) > > > */ > > > delta = (new_raw_count - prev_raw_count) & > > > ((1ULL << riscv_pmu->counter_width) - 1); > > > + > > > local64_add(delta, &event->count); > > > /* > > > * Something like local64_sub(delta, &hwc->period_left) here is > > > @@ -252,6 +377,11 @@ static void riscv_pmu_stop(struct perf_event *event, int flags) > > > { > > > struct hw_perf_event *hwc = &event->hw; > > > > > > + if (WARN_ON_ONCE(hwc->idx == -1)) > > > + return; > > > + > > > + riscv_pmu_disable_event(event); > > > + > > > WARN_ON_ONCE(hwc->state & PERF_HES_STOPPED); > > > hwc->state |= PERF_HES_STOPPED; > > > > > > @@ -271,6 +401,9 @@ static void riscv_pmu_start(struct perf_event *event, int flags) > > > if (WARN_ON_ONCE(!(event->hw.state & PERF_HES_STOPPED))) > > > return; > > > > > > + if (WARN_ON_ONCE(hwc->idx == -1)) > > > + return; > > > + > > > if (flags & PERF_EF_RELOAD) { > > > WARN_ON_ONCE(!(event->hw.state & PERF_HES_UPTODATE)); > > > > > > @@ -281,14 +414,10 @@ static void riscv_pmu_start(struct perf_event *event, int flags) > > > } > > > > > > hwc->state = 0; > > > - perf_event_update_userpage(event); > > > > > > - /* > > > - * Since we cannot write to counters, this serves as an initialization > > > - * to the delta-mechanism in pmu->read(); otherwise, the delta would be > > > - * wrong when pmu->read is called for the first time. > > > - */ > > > - local64_set(&hwc->prev_count, read_counter(hwc->idx)); > > > + riscv_pmu_enable_event(event); > > > + > > > + perf_event_update_userpage(event); > > > } > > > > > > /* > > > @@ -298,21 +427,18 @@ static int riscv_pmu_add(struct perf_event *event, int flags) > > > { > > > struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events); > > > struct hw_perf_event *hwc = &event->hw; > > > + int count_idx; > > > > > > if (cpuc->n_events == riscv_pmu->num_counters) > > > return -ENOSPC; > > > > > > - /* > > > - * We don't have general conunters, so no binding-event-to-counter > > > - * process here. > > > - * > > > - * Indexing using hwc->config generally not works, since config may > > > - * contain extra information, but here the only info we have in > > > - * hwc->config is the event index. > > > - */ > > > - hwc->idx = hwc->config; > > > - cpuc->events[hwc->idx] = event; > > > + count_idx = get_available_counter(event); > > > + if (count_idx < 0) > > > + return -ENOSPC; > > > + > > > cpuc->n_events++; > > > + hwc->idx = count_idx; > > > + cpuc->events[hwc->idx] = event; > > > > > > hwc->state = PERF_HES_UPTODATE | PERF_HES_STOPPED; > > > > > > @@ -330,8 +456,10 @@ static void riscv_pmu_del(struct perf_event *event, int flags) > > > struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events); > > > struct hw_perf_event *hwc = &event->hw; > > > > > > - cpuc->events[hwc->idx] = NULL; > > > cpuc->n_events--; > > > + __clear_bit(hwc->idx, &cpuc->used_cntr_mask); > > > + > > > + cpuc->events[hwc->idx] = NULL; > > > riscv_pmu->pmu->stop(event, PERF_EF_UPDATE); > > > perf_event_update_userpage(event); > > > } > > > @@ -385,6 +513,7 @@ static int riscv_event_init(struct perf_event *event) > > > { > > > struct perf_event_attr *attr = &event->attr; > > > struct hw_perf_event *hwc = &event->hw; > > > + unsigned long config_base = 0; > > > int err; > > > int code; > > > > > > @@ -406,11 +535,17 @@ static int riscv_event_init(struct perf_event *event) > > > code = riscv_pmu->map_cache_event(attr->config); > > > break; > > > case PERF_TYPE_RAW: > > > - return -EOPNOTSUPP; > > > + code = attr->config; > > > + break; > > > default: > > > return -ENOENT; > > > } > > > > > > + if (is_base_counter(code)) > > > + config_base |= RISCV_PMU_TYPE_BASE; > > > + else > > > + config_base |= RISCV_PMU_TYPE_EVENT; > > > + > > > event->destroy = riscv_event_destroy; > > > if (code < 0) { > > > event->destroy(event); > > > @@ -424,6 +559,7 @@ static int riscv_event_init(struct perf_event *event) > > > * But since we don't have such support, later in pmu->add(), we just > > > * use hwc->config as the index instead. > > > */ > > > + hwc->config_base = config_base; > > > hwc->config = code; > > > hwc->idx = -1; > > > > > > -- > > > 2.27.0 > > > _______________________________________________ linux-riscv mailing list linux-riscv@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-riscv ^ permalink raw reply [flat|nested] 38+ messages in thread
* [RFC PATCH 5/6] riscv: perf: introduce DT mechanism 2020-06-29 3:19 [RFC PATCH 0/6] Support raw event and DT for perf on RISC-V Zong Li ` (3 preceding siblings ...) 2020-06-29 3:19 ` [RFC PATCH 4/6] riscv: perf: Add raw event support Zong Li @ 2020-06-29 3:19 ` Zong Li 2020-06-29 4:36 ` Anup Patel 2020-06-29 3:19 ` [RFC PATCH 6/6] riscv: remove PMU menu of Kconfig Zong Li ` (2 subsequent siblings) 7 siblings, 1 reply; 38+ messages in thread From: Zong Li @ 2020-06-29 3:19 UTC (permalink / raw) To: palmer, paul.walmsley, linux-riscv, linux-kernel; +Cc: Zong Li Each architecture is responsible for mapping generic hardware and cache events to their own specific encoding of hardware events. For each architecture, it also have to distinguish the defination of hardware events of different platforms of each vendor. We use DT file to describe platform-specific information to make our perf implementation more generic and common. Signed-off-by: Zong Li <zong.li@sifive.com> --- arch/riscv/include/asm/perf_event.h | 55 ++---- arch/riscv/kernel/perf_event.c | 273 +++++++++++++--------------- 2 files changed, 139 insertions(+), 189 deletions(-) diff --git a/arch/riscv/include/asm/perf_event.h b/arch/riscv/include/asm/perf_event.h index 41d515a1f331..e95d3bbaae3e 100644 --- a/arch/riscv/include/asm/perf_event.h +++ b/arch/riscv/include/asm/perf_event.h @@ -17,6 +17,8 @@ #define RISCV_EVENT_COUNTERS 29 #define RISCV_TOTAL_COUNTERS (RISCV_BASE_COUNTERS + RISCV_EVENT_COUNTERS) +#define RISCV_DEFAULT_WIDTH_COUNTER 64 + /* * According to the spec, an implementation can support counter up to * mhpmcounter31, but many high-end processors has at most 6 general @@ -33,9 +35,21 @@ #define RISCV_PMU_HPMCOUNTER_FIRST 3 #define RISCV_PMU_HPMCOUNTER_LAST \ - (RISCV_PMU_HPMCOUNTER_FIRST + riscv_pmu->num_counters - 1) + (RISCV_PMU_HPMCOUNTER_FIRST + riscv_pmu.num_event_cntr - 1) + +#define RISCV_OP_UNSUPP (-EOPNOTSUPP) + +#define RISCV_MAP_ALL_UNSUPPORTED \ + [0 ... PERF_COUNT_HW_MAX - 1] = RISCV_OP_UNSUPP -#define RISCV_OP_UNSUPP (-EOPNOTSUPP) +#define C(x) PERF_COUNT_HW_CACHE_##x + +#define RISCV_CACHE_MAP_ALL_UNSUPPORTED \ +[0 ... C(MAX) - 1] = { \ + [0 ... C(OP_MAX) - 1] = { \ + [0 ... C(RESULT_MAX) - 1] = RISCV_OP_UNSUPP, \ + }, \ +} /* Hardware cache event encoding */ #define PERF_HW_CACHE_TYPE 0 @@ -65,43 +79,6 @@ #define CSR_MHPMEVENT7 0x327 #define CSR_MHPMEVENT8 0x328 -struct cpu_hw_events { - /* # currently enabled events*/ - int n_events; - /* currently enabled events */ - struct perf_event *events[RISCV_EVENT_COUNTERS]; - /* bitmap of used event counters */ - unsigned long used_cntr_mask; - /* vendor-defined PMU data */ - void *platform; -}; - -struct riscv_pmu { - struct pmu *pmu; - - /* generic hw/cache events table */ - const int *hw_events; - const int (*cache_events)[PERF_COUNT_HW_CACHE_MAX] - [PERF_COUNT_HW_CACHE_OP_MAX] - [PERF_COUNT_HW_CACHE_RESULT_MAX]; - /* method used to map hw/cache events */ - int (*map_hw_event)(u64 config); - int (*map_cache_event)(u64 config); - - /* max generic hw events in map */ - int max_events; - /* number total counters, 2(base) + x(general) */ - int num_counters; - /* the width of the counter */ - int counter_width; - - /* vendor-defined PMU features */ - void *platform; - - irqreturn_t (*handle_irq)(int irq_num, void *dev); - int irq; -}; - #endif #ifdef CONFIG_PERF_EVENTS #define perf_arch_bpf_user_pt_regs(regs) (struct user_regs_struct *)regs diff --git a/arch/riscv/kernel/perf_event.c b/arch/riscv/kernel/perf_event.c index 0cfcd6f1e57b..3bdfbe4efd5c 100644 --- a/arch/riscv/kernel/perf_event.c +++ b/arch/riscv/kernel/perf_event.c @@ -9,6 +9,7 @@ * Copyright (C) 2009 Google, Inc., Stephane Eranian * Copyright 2014 Tilera Corporation. All Rights Reserved. * Copyright (C) 2018 Andes Technology Corporation + * Copyright (C) 2020 SiFive * * Perf_events support for RISC-V platforms. * @@ -30,113 +31,55 @@ #include <linux/perf_event.h> #include <linux/atomic.h> #include <linux/of.h> +#include <asm/csr.h> #include <asm/perf_event.h> -static const struct riscv_pmu *riscv_pmu __read_mostly; +static struct riscv_pmu { + struct pmu *pmu; + + /* number of event counters */ + int num_event_cntr; + + /* the width of base counters */ + int width_base_cntr; + + /* the width of event counters */ + int width_event_cntr; + + irqreturn_t (*handle_irq)(int irq_num, void *dev); + + int irq; +} riscv_pmu; + +struct cpu_hw_events { + /* # currently enabled events*/ + int n_events; + + /* currently enabled events */ + struct perf_event *events[RISCV_EVENT_COUNTERS]; + + /* bitmap of used event counters */ + unsigned long used_cntr_mask; +}; + static DEFINE_PER_CPU(struct cpu_hw_events, cpu_hw_events); /* * Hardware & cache maps and their methods */ -static const int riscv_hw_event_map[] = { - [PERF_COUNT_HW_CPU_CYCLES] = RISCV_PMU_CYCLE, - [PERF_COUNT_HW_INSTRUCTIONS] = RISCV_PMU_INSTRET, - [PERF_COUNT_HW_CACHE_REFERENCES] = RISCV_OP_UNSUPP, - [PERF_COUNT_HW_CACHE_MISSES] = RISCV_OP_UNSUPP, - [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = RISCV_OP_UNSUPP, - [PERF_COUNT_HW_BRANCH_MISSES] = RISCV_OP_UNSUPP, - [PERF_COUNT_HW_BUS_CYCLES] = RISCV_OP_UNSUPP, +static int riscv_hw_event_map[PERF_COUNT_HW_MAX] = { + RISCV_MAP_ALL_UNSUPPORTED, + + /* Specify base pmu, even if they aren't present in DT file */ + [PERF_COUNT_HW_CPU_CYCLES] = RISCV_PMU_CYCLE, + [PERF_COUNT_HW_INSTRUCTIONS] = RISCV_PMU_INSTRET, }; -#define C(x) PERF_COUNT_HW_CACHE_##x -static const int riscv_cache_event_map[PERF_COUNT_HW_CACHE_MAX] -[PERF_COUNT_HW_CACHE_OP_MAX] -[PERF_COUNT_HW_CACHE_RESULT_MAX] = { - [C(L1D)] = { - [C(OP_READ)] = { - [C(RESULT_ACCESS)] = RISCV_OP_UNSUPP, - [C(RESULT_MISS)] = RISCV_OP_UNSUPP, - }, - [C(OP_WRITE)] = { - [C(RESULT_ACCESS)] = RISCV_OP_UNSUPP, - [C(RESULT_MISS)] = RISCV_OP_UNSUPP, - }, - [C(OP_PREFETCH)] = { - [C(RESULT_ACCESS)] = RISCV_OP_UNSUPP, - [C(RESULT_MISS)] = RISCV_OP_UNSUPP, - }, - }, - [C(L1I)] = { - [C(OP_READ)] = { - [C(RESULT_ACCESS)] = RISCV_OP_UNSUPP, - [C(RESULT_MISS)] = RISCV_OP_UNSUPP, - }, - [C(OP_WRITE)] = { - [C(RESULT_ACCESS)] = RISCV_OP_UNSUPP, - [C(RESULT_MISS)] = RISCV_OP_UNSUPP, - }, - [C(OP_PREFETCH)] = { - [C(RESULT_ACCESS)] = RISCV_OP_UNSUPP, - [C(RESULT_MISS)] = RISCV_OP_UNSUPP, - }, - }, - [C(LL)] = { - [C(OP_READ)] = { - [C(RESULT_ACCESS)] = RISCV_OP_UNSUPP, - [C(RESULT_MISS)] = RISCV_OP_UNSUPP, - }, - [C(OP_WRITE)] = { - [C(RESULT_ACCESS)] = RISCV_OP_UNSUPP, - [C(RESULT_MISS)] = RISCV_OP_UNSUPP, - }, - [C(OP_PREFETCH)] = { - [C(RESULT_ACCESS)] = RISCV_OP_UNSUPP, - [C(RESULT_MISS)] = RISCV_OP_UNSUPP, - }, - }, - [C(DTLB)] = { - [C(OP_READ)] = { - [C(RESULT_ACCESS)] = RISCV_OP_UNSUPP, - [C(RESULT_MISS)] = RISCV_OP_UNSUPP, - }, - [C(OP_WRITE)] = { - [C(RESULT_ACCESS)] = RISCV_OP_UNSUPP, - [C(RESULT_MISS)] = RISCV_OP_UNSUPP, - }, - [C(OP_PREFETCH)] = { - [C(RESULT_ACCESS)] = RISCV_OP_UNSUPP, - [C(RESULT_MISS)] = RISCV_OP_UNSUPP, - }, - }, - [C(ITLB)] = { - [C(OP_READ)] = { - [C(RESULT_ACCESS)] = RISCV_OP_UNSUPP, - [C(RESULT_MISS)] = RISCV_OP_UNSUPP, - }, - [C(OP_WRITE)] = { - [C(RESULT_ACCESS)] = RISCV_OP_UNSUPP, - [C(RESULT_MISS)] = RISCV_OP_UNSUPP, - }, - [C(OP_PREFETCH)] = { - [C(RESULT_ACCESS)] = RISCV_OP_UNSUPP, - [C(RESULT_MISS)] = RISCV_OP_UNSUPP, - }, - }, - [C(BPU)] = { - [C(OP_READ)] = { - [C(RESULT_ACCESS)] = RISCV_OP_UNSUPP, - [C(RESULT_MISS)] = RISCV_OP_UNSUPP, - }, - [C(OP_WRITE)] = { - [C(RESULT_ACCESS)] = RISCV_OP_UNSUPP, - [C(RESULT_MISS)] = RISCV_OP_UNSUPP, - }, - [C(OP_PREFETCH)] = { - [C(RESULT_ACCESS)] = RISCV_OP_UNSUPP, - [C(RESULT_MISS)] = RISCV_OP_UNSUPP, - }, - }, +static int riscv_cache_event_map[PERF_COUNT_HW_CACHE_MAX] + [PERF_COUNT_HW_CACHE_OP_MAX] + [PERF_COUNT_HW_CACHE_RESULT_MAX] = { + RISCV_CACHE_MAP_ALL_UNSUPPORTED, }; /* @@ -154,6 +97,17 @@ static inline int is_event_counter(int idx) idx <= RISCV_PMU_HPMCOUNTER_LAST); } +static inline int get_counter_width(int idx) +{ + if (is_base_counter(idx)) + return riscv_pmu.width_base_cntr; + + if (is_event_counter(idx)) + return riscv_pmu.width_event_cntr; + + return 0; +} + static inline int get_available_counter(struct perf_event *event) { struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events); @@ -188,10 +142,14 @@ static inline int get_available_counter(struct perf_event *event) */ static int riscv_map_hw_event(u64 config) { - if (config >= riscv_pmu->max_events) + int ret; + + if (config >= PERF_COUNT_HW_MAX) return -EINVAL; - return riscv_pmu->hw_events[config]; + ret = riscv_hw_event_map[config]; + + return ret == RISCV_OP_UNSUPP ? -ENOENT : ret; } /* @@ -355,7 +313,7 @@ static void riscv_pmu_read(struct perf_event *event) * delta is the value to update the counter we maintain in the kernel. */ delta = (new_raw_count - prev_raw_count) & - ((1ULL << riscv_pmu->counter_width) - 1); + ((1ULL << get_counter_width(idx)) - 1); local64_add(delta, &event->count); /* @@ -386,7 +344,7 @@ static void riscv_pmu_stop(struct perf_event *event, int flags) hwc->state |= PERF_HES_STOPPED; if ((flags & PERF_EF_UPDATE) && !(hwc->state & PERF_HES_UPTODATE)) { - riscv_pmu->pmu->read(event); + riscv_pmu_read(event); hwc->state |= PERF_HES_UPTODATE; } } @@ -429,7 +387,7 @@ static int riscv_pmu_add(struct perf_event *event, int flags) struct hw_perf_event *hwc = &event->hw; int count_idx; - if (cpuc->n_events == riscv_pmu->num_counters) + if (cpuc->n_events == riscv_pmu.num_event_cntr) return -ENOSPC; count_idx = get_available_counter(event); @@ -437,13 +395,13 @@ static int riscv_pmu_add(struct perf_event *event, int flags) return -ENOSPC; cpuc->n_events++; + hwc->idx = count_idx; - cpuc->events[hwc->idx] = event; hwc->state = PERF_HES_UPTODATE | PERF_HES_STOPPED; if (flags & PERF_EF_START) - riscv_pmu->pmu->start(event, PERF_EF_RELOAD); + riscv_pmu_start(event, PERF_EF_RELOAD); return 0; } @@ -459,8 +417,8 @@ static void riscv_pmu_del(struct perf_event *event, int flags) cpuc->n_events--; __clear_bit(hwc->idx, &cpuc->used_cntr_mask); - cpuc->events[hwc->idx] = NULL; - riscv_pmu->pmu->stop(event, PERF_EF_UPDATE); + riscv_pmu_stop(event, PERF_EF_UPDATE); + perf_event_update_userpage(event); } @@ -470,7 +428,7 @@ static void riscv_pmu_del(struct perf_event *event, int flags) static DEFINE_MUTEX(pmc_reserve_mutex); -static irqreturn_t riscv_base_pmu_handle_irq(int irq_num, void *dev) +static irqreturn_t riscv_pmu_handle_irq(int irq_num, void *dev) { return IRQ_NONE; } @@ -480,8 +438,8 @@ static int reserve_pmc_hardware(void) int err = 0; mutex_lock(&pmc_reserve_mutex); - if (riscv_pmu->irq >= 0 && riscv_pmu->handle_irq) { - err = request_irq(riscv_pmu->irq, riscv_pmu->handle_irq, + if (riscv_pmu.irq >= 0 && riscv_pmu.handle_irq) { + err = request_irq(riscv_pmu.irq, riscv_pmu.handle_irq, IRQF_PERCPU, "riscv-base-perf", NULL); } mutex_unlock(&pmc_reserve_mutex); @@ -492,8 +450,8 @@ static int reserve_pmc_hardware(void) static void release_pmc_hardware(void) { mutex_lock(&pmc_reserve_mutex); - if (riscv_pmu->irq >= 0) - free_irq(riscv_pmu->irq, NULL); + if (riscv_pmu.irq >= 0) + free_irq(riscv_pmu.irq, NULL); mutex_unlock(&pmc_reserve_mutex); } @@ -529,10 +487,10 @@ static int riscv_event_init(struct perf_event *event) switch (event->attr.type) { case PERF_TYPE_HARDWARE: - code = riscv_pmu->map_hw_event(attr->config); + code = riscv_map_hw_event(attr->config); break; case PERF_TYPE_HW_CACHE: - code = riscv_pmu->map_cache_event(attr->config); + code = riscv_map_cache_event(attr->config); break; case PERF_TYPE_RAW: code = attr->config; @@ -555,9 +513,6 @@ static int riscv_event_init(struct perf_event *event) /* * idx is set to -1 because the index of a general event should not be * decided until binding to some counter in pmu->add(). - * - * But since we don't have such support, later in pmu->add(), we just - * use hwc->config as the index instead. */ hwc->config_base = config_base; hwc->config = code; @@ -570,52 +525,70 @@ static int riscv_event_init(struct perf_event *event) * Initialization */ -static struct pmu min_pmu = { - .name = "riscv-base", - .event_init = riscv_event_init, - .add = riscv_pmu_add, - .del = riscv_pmu_del, - .start = riscv_pmu_start, - .stop = riscv_pmu_stop, - .read = riscv_pmu_read, -}; +static struct riscv_pmu riscv_pmu = { + .pmu = &(struct pmu) { + .name = "riscv-pmu", + .event_init = riscv_event_init, + .add = riscv_pmu_add, + .del = riscv_pmu_del, + .start = riscv_pmu_start, + .stop = riscv_pmu_stop, + .read = riscv_pmu_read, + }, -static const struct riscv_pmu riscv_base_pmu = { - .pmu = &min_pmu, - .max_events = ARRAY_SIZE(riscv_hw_event_map), - .map_hw_event = riscv_map_hw_event, - .hw_events = riscv_hw_event_map, - .map_cache_event = riscv_map_cache_event, - .cache_events = &riscv_cache_event_map, - .counter_width = 63, - .num_counters = RISCV_BASE_COUNTERS + 0, - .handle_irq = &riscv_base_pmu_handle_irq, + .num_event_cntr = 0, + .width_event_cntr = RISCV_DEFAULT_WIDTH_COUNTER, + .width_base_cntr = RISCV_DEFAULT_WIDTH_COUNTER, + .handle_irq = &riscv_pmu_handle_irq, /* This means this PMU has no IRQ. */ .irq = -1, }; -static const struct of_device_id riscv_pmu_of_ids[] = { - {.compatible = "riscv,base-pmu", .data = &riscv_base_pmu}, - { /* sentinel value */ } -}; +static int __init init_riscv_pmu(struct device_node *node) +{ + int num_events, key, value, i; + + of_property_read_u32(node, "riscv,width-base-cntr", &riscv_pmu.width_base_cntr); + + of_property_read_u32(node, "riscv,width-event-cntr", &riscv_pmu.width_event_cntr); + + of_property_read_u32(node, "riscv,n-event-cntr", &riscv_pmu.num_event_cntr); + if (riscv_pmu.num_event_cntr > RISCV_EVENT_COUNTERS) + riscv_pmu.num_event_cntr = RISCV_EVENT_COUNTERS; + + num_events = of_property_count_u32_elems(node, "riscv,hw-event-map"); + if (num_events > 0 && num_events % 2 == 0) + for (i = 0; i < num_events;) { + of_property_read_u32_index(node, "riscv,hw-event-map", i++, &key); + of_property_read_u32_index(node, "riscv,hw-event-map", i++, &value); + riscv_hw_event_map[key] = value; + } + + num_events = of_property_count_u32_elems(node, "riscv,hw-cache-event-map"); + if (num_events > 0 && num_events % 2 == 0) + for (i = 0; i < num_events;) { + of_property_read_u32_index(node, "riscv,hw-cache-event-map", i++, &key); + of_property_read_u32_index(node, "riscv,hw-cache-event-map", i++, &value); + riscv_cache_event_map + [(key >> PERF_HW_CACHE_TYPE) & PERF_HW_CACHE_MASK] + [(key >> PERF_HW_CACHE_OP) & PERF_HW_CACHE_MASK] + [(key >> PERF_HW_CACHE_RESULT) & PERF_HW_CACHE_MASK] = value; + } + + return 0; +} static int __init init_hw_perf_events(void) { - struct device_node *node = of_find_node_by_type(NULL, "pmu"); - const struct of_device_id *of_id; + struct device_node *node = of_find_compatible_node(NULL, NULL, "riscv,pmu"); - riscv_pmu = &riscv_base_pmu; + if (node) + init_riscv_pmu(node); - if (node) { - of_id = of_match_node(riscv_pmu_of_ids, node); - - if (of_id) - riscv_pmu = of_id->data; - of_node_put(node); - } + /* Even if there is no pmu node in DT, we reach here for base PMU. */ + perf_pmu_register(riscv_pmu.pmu, "cpu", PERF_TYPE_RAW); - perf_pmu_register(riscv_pmu->pmu, "cpu", PERF_TYPE_RAW); return 0; } arch_initcall(init_hw_perf_events); -- 2.27.0 _______________________________________________ linux-riscv mailing list linux-riscv@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-riscv ^ permalink raw reply related [flat|nested] 38+ messages in thread
* Re: [RFC PATCH 5/6] riscv: perf: introduce DT mechanism 2020-06-29 3:19 ` [RFC PATCH 5/6] riscv: perf: introduce DT mechanism Zong Li @ 2020-06-29 4:36 ` Anup Patel 2020-06-29 6:26 ` Zong Li 0 siblings, 1 reply; 38+ messages in thread From: Anup Patel @ 2020-06-29 4:36 UTC (permalink / raw) To: Zong Li Cc: linux-riscv, Palmer Dabbelt, linux-kernel@vger.kernel.org List, Paul Walmsley On Mon, Jun 29, 2020 at 8:49 AM Zong Li <zong.li@sifive.com> wrote: > > Each architecture is responsible for mapping generic hardware and cache > events to their own specific encoding of hardware events. For each > architecture, it also have to distinguish the defination of hardware > events of different platforms of each vendor. We use DT file to describe > platform-specific information to make our perf implementation more > generic and common. > > Signed-off-by: Zong Li <zong.li@sifive.com> > --- > arch/riscv/include/asm/perf_event.h | 55 ++---- > arch/riscv/kernel/perf_event.c | 273 +++++++++++++--------------- > 2 files changed, 139 insertions(+), 189 deletions(-) > > diff --git a/arch/riscv/include/asm/perf_event.h b/arch/riscv/include/asm/perf_event.h > index 41d515a1f331..e95d3bbaae3e 100644 > --- a/arch/riscv/include/asm/perf_event.h > +++ b/arch/riscv/include/asm/perf_event.h > @@ -17,6 +17,8 @@ > #define RISCV_EVENT_COUNTERS 29 > #define RISCV_TOTAL_COUNTERS (RISCV_BASE_COUNTERS + RISCV_EVENT_COUNTERS) > > +#define RISCV_DEFAULT_WIDTH_COUNTER 64 > + > /* > * According to the spec, an implementation can support counter up to > * mhpmcounter31, but many high-end processors has at most 6 general > @@ -33,9 +35,21 @@ > > #define RISCV_PMU_HPMCOUNTER_FIRST 3 > #define RISCV_PMU_HPMCOUNTER_LAST \ > - (RISCV_PMU_HPMCOUNTER_FIRST + riscv_pmu->num_counters - 1) > + (RISCV_PMU_HPMCOUNTER_FIRST + riscv_pmu.num_event_cntr - 1) > + > +#define RISCV_OP_UNSUPP (-EOPNOTSUPP) > + > +#define RISCV_MAP_ALL_UNSUPPORTED \ > + [0 ... PERF_COUNT_HW_MAX - 1] = RISCV_OP_UNSUPP > > -#define RISCV_OP_UNSUPP (-EOPNOTSUPP) > +#define C(x) PERF_COUNT_HW_CACHE_##x > + > +#define RISCV_CACHE_MAP_ALL_UNSUPPORTED \ > +[0 ... C(MAX) - 1] = { \ > + [0 ... C(OP_MAX) - 1] = { \ > + [0 ... C(RESULT_MAX) - 1] = RISCV_OP_UNSUPP, \ > + }, \ > +} > > /* Hardware cache event encoding */ > #define PERF_HW_CACHE_TYPE 0 > @@ -65,43 +79,6 @@ > #define CSR_MHPMEVENT7 0x327 > #define CSR_MHPMEVENT8 0x328 > > -struct cpu_hw_events { > - /* # currently enabled events*/ > - int n_events; > - /* currently enabled events */ > - struct perf_event *events[RISCV_EVENT_COUNTERS]; > - /* bitmap of used event counters */ > - unsigned long used_cntr_mask; > - /* vendor-defined PMU data */ > - void *platform; > -}; > - > -struct riscv_pmu { > - struct pmu *pmu; > - > - /* generic hw/cache events table */ > - const int *hw_events; > - const int (*cache_events)[PERF_COUNT_HW_CACHE_MAX] > - [PERF_COUNT_HW_CACHE_OP_MAX] > - [PERF_COUNT_HW_CACHE_RESULT_MAX]; > - /* method used to map hw/cache events */ > - int (*map_hw_event)(u64 config); > - int (*map_cache_event)(u64 config); > - > - /* max generic hw events in map */ > - int max_events; > - /* number total counters, 2(base) + x(general) */ > - int num_counters; > - /* the width of the counter */ > - int counter_width; > - > - /* vendor-defined PMU features */ > - void *platform; > - > - irqreturn_t (*handle_irq)(int irq_num, void *dev); > - int irq; > -}; > - > #endif > #ifdef CONFIG_PERF_EVENTS > #define perf_arch_bpf_user_pt_regs(regs) (struct user_regs_struct *)regs > diff --git a/arch/riscv/kernel/perf_event.c b/arch/riscv/kernel/perf_event.c > index 0cfcd6f1e57b..3bdfbe4efd5c 100644 > --- a/arch/riscv/kernel/perf_event.c > +++ b/arch/riscv/kernel/perf_event.c > @@ -9,6 +9,7 @@ > * Copyright (C) 2009 Google, Inc., Stephane Eranian > * Copyright 2014 Tilera Corporation. All Rights Reserved. > * Copyright (C) 2018 Andes Technology Corporation > + * Copyright (C) 2020 SiFive > * > * Perf_events support for RISC-V platforms. > * > @@ -30,113 +31,55 @@ > #include <linux/perf_event.h> > #include <linux/atomic.h> > #include <linux/of.h> > +#include <asm/csr.h> > #include <asm/perf_event.h> > > -static const struct riscv_pmu *riscv_pmu __read_mostly; > +static struct riscv_pmu { > + struct pmu *pmu; > + > + /* number of event counters */ > + int num_event_cntr; > + > + /* the width of base counters */ > + int width_base_cntr; > + > + /* the width of event counters */ > + int width_event_cntr; > + > + irqreturn_t (*handle_irq)(int irq_num, void *dev); > + > + int irq; > +} riscv_pmu; > + > +struct cpu_hw_events { > + /* # currently enabled events*/ > + int n_events; > + > + /* currently enabled events */ > + struct perf_event *events[RISCV_EVENT_COUNTERS]; > + > + /* bitmap of used event counters */ > + unsigned long used_cntr_mask; > +}; > + > static DEFINE_PER_CPU(struct cpu_hw_events, cpu_hw_events); > > /* > * Hardware & cache maps and their methods > */ > > -static const int riscv_hw_event_map[] = { > - [PERF_COUNT_HW_CPU_CYCLES] = RISCV_PMU_CYCLE, > - [PERF_COUNT_HW_INSTRUCTIONS] = RISCV_PMU_INSTRET, > - [PERF_COUNT_HW_CACHE_REFERENCES] = RISCV_OP_UNSUPP, > - [PERF_COUNT_HW_CACHE_MISSES] = RISCV_OP_UNSUPP, > - [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = RISCV_OP_UNSUPP, > - [PERF_COUNT_HW_BRANCH_MISSES] = RISCV_OP_UNSUPP, > - [PERF_COUNT_HW_BUS_CYCLES] = RISCV_OP_UNSUPP, > +static int riscv_hw_event_map[PERF_COUNT_HW_MAX] = { > + RISCV_MAP_ALL_UNSUPPORTED, > + > + /* Specify base pmu, even if they aren't present in DT file */ > + [PERF_COUNT_HW_CPU_CYCLES] = RISCV_PMU_CYCLE, > + [PERF_COUNT_HW_INSTRUCTIONS] = RISCV_PMU_INSTRET, > }; > > -#define C(x) PERF_COUNT_HW_CACHE_##x > -static const int riscv_cache_event_map[PERF_COUNT_HW_CACHE_MAX] > -[PERF_COUNT_HW_CACHE_OP_MAX] > -[PERF_COUNT_HW_CACHE_RESULT_MAX] = { > - [C(L1D)] = { > - [C(OP_READ)] = { > - [C(RESULT_ACCESS)] = RISCV_OP_UNSUPP, > - [C(RESULT_MISS)] = RISCV_OP_UNSUPP, > - }, > - [C(OP_WRITE)] = { > - [C(RESULT_ACCESS)] = RISCV_OP_UNSUPP, > - [C(RESULT_MISS)] = RISCV_OP_UNSUPP, > - }, > - [C(OP_PREFETCH)] = { > - [C(RESULT_ACCESS)] = RISCV_OP_UNSUPP, > - [C(RESULT_MISS)] = RISCV_OP_UNSUPP, > - }, > - }, > - [C(L1I)] = { > - [C(OP_READ)] = { > - [C(RESULT_ACCESS)] = RISCV_OP_UNSUPP, > - [C(RESULT_MISS)] = RISCV_OP_UNSUPP, > - }, > - [C(OP_WRITE)] = { > - [C(RESULT_ACCESS)] = RISCV_OP_UNSUPP, > - [C(RESULT_MISS)] = RISCV_OP_UNSUPP, > - }, > - [C(OP_PREFETCH)] = { > - [C(RESULT_ACCESS)] = RISCV_OP_UNSUPP, > - [C(RESULT_MISS)] = RISCV_OP_UNSUPP, > - }, > - }, > - [C(LL)] = { > - [C(OP_READ)] = { > - [C(RESULT_ACCESS)] = RISCV_OP_UNSUPP, > - [C(RESULT_MISS)] = RISCV_OP_UNSUPP, > - }, > - [C(OP_WRITE)] = { > - [C(RESULT_ACCESS)] = RISCV_OP_UNSUPP, > - [C(RESULT_MISS)] = RISCV_OP_UNSUPP, > - }, > - [C(OP_PREFETCH)] = { > - [C(RESULT_ACCESS)] = RISCV_OP_UNSUPP, > - [C(RESULT_MISS)] = RISCV_OP_UNSUPP, > - }, > - }, > - [C(DTLB)] = { > - [C(OP_READ)] = { > - [C(RESULT_ACCESS)] = RISCV_OP_UNSUPP, > - [C(RESULT_MISS)] = RISCV_OP_UNSUPP, > - }, > - [C(OP_WRITE)] = { > - [C(RESULT_ACCESS)] = RISCV_OP_UNSUPP, > - [C(RESULT_MISS)] = RISCV_OP_UNSUPP, > - }, > - [C(OP_PREFETCH)] = { > - [C(RESULT_ACCESS)] = RISCV_OP_UNSUPP, > - [C(RESULT_MISS)] = RISCV_OP_UNSUPP, > - }, > - }, > - [C(ITLB)] = { > - [C(OP_READ)] = { > - [C(RESULT_ACCESS)] = RISCV_OP_UNSUPP, > - [C(RESULT_MISS)] = RISCV_OP_UNSUPP, > - }, > - [C(OP_WRITE)] = { > - [C(RESULT_ACCESS)] = RISCV_OP_UNSUPP, > - [C(RESULT_MISS)] = RISCV_OP_UNSUPP, > - }, > - [C(OP_PREFETCH)] = { > - [C(RESULT_ACCESS)] = RISCV_OP_UNSUPP, > - [C(RESULT_MISS)] = RISCV_OP_UNSUPP, > - }, > - }, > - [C(BPU)] = { > - [C(OP_READ)] = { > - [C(RESULT_ACCESS)] = RISCV_OP_UNSUPP, > - [C(RESULT_MISS)] = RISCV_OP_UNSUPP, > - }, > - [C(OP_WRITE)] = { > - [C(RESULT_ACCESS)] = RISCV_OP_UNSUPP, > - [C(RESULT_MISS)] = RISCV_OP_UNSUPP, > - }, > - [C(OP_PREFETCH)] = { > - [C(RESULT_ACCESS)] = RISCV_OP_UNSUPP, > - [C(RESULT_MISS)] = RISCV_OP_UNSUPP, > - }, > - }, > +static int riscv_cache_event_map[PERF_COUNT_HW_CACHE_MAX] > + [PERF_COUNT_HW_CACHE_OP_MAX] > + [PERF_COUNT_HW_CACHE_RESULT_MAX] = { > + RISCV_CACHE_MAP_ALL_UNSUPPORTED, > }; > > /* > @@ -154,6 +97,17 @@ static inline int is_event_counter(int idx) > idx <= RISCV_PMU_HPMCOUNTER_LAST); > } > > +static inline int get_counter_width(int idx) > +{ > + if (is_base_counter(idx)) > + return riscv_pmu.width_base_cntr; > + > + if (is_event_counter(idx)) > + return riscv_pmu.width_event_cntr; > + > + return 0; > +} > + > static inline int get_available_counter(struct perf_event *event) > { > struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events); > @@ -188,10 +142,14 @@ static inline int get_available_counter(struct perf_event *event) > */ > static int riscv_map_hw_event(u64 config) > { > - if (config >= riscv_pmu->max_events) > + int ret; > + > + if (config >= PERF_COUNT_HW_MAX) > return -EINVAL; > > - return riscv_pmu->hw_events[config]; > + ret = riscv_hw_event_map[config]; > + > + return ret == RISCV_OP_UNSUPP ? -ENOENT : ret; > } > > /* > @@ -355,7 +313,7 @@ static void riscv_pmu_read(struct perf_event *event) > * delta is the value to update the counter we maintain in the kernel. > */ > delta = (new_raw_count - prev_raw_count) & > - ((1ULL << riscv_pmu->counter_width) - 1); > + ((1ULL << get_counter_width(idx)) - 1); > > local64_add(delta, &event->count); > /* > @@ -386,7 +344,7 @@ static void riscv_pmu_stop(struct perf_event *event, int flags) > hwc->state |= PERF_HES_STOPPED; > > if ((flags & PERF_EF_UPDATE) && !(hwc->state & PERF_HES_UPTODATE)) { > - riscv_pmu->pmu->read(event); > + riscv_pmu_read(event); > hwc->state |= PERF_HES_UPTODATE; > } > } > @@ -429,7 +387,7 @@ static int riscv_pmu_add(struct perf_event *event, int flags) > struct hw_perf_event *hwc = &event->hw; > int count_idx; > > - if (cpuc->n_events == riscv_pmu->num_counters) > + if (cpuc->n_events == riscv_pmu.num_event_cntr) > return -ENOSPC; > > count_idx = get_available_counter(event); > @@ -437,13 +395,13 @@ static int riscv_pmu_add(struct perf_event *event, int flags) > return -ENOSPC; > > cpuc->n_events++; > + > hwc->idx = count_idx; > - cpuc->events[hwc->idx] = event; > > hwc->state = PERF_HES_UPTODATE | PERF_HES_STOPPED; > > if (flags & PERF_EF_START) > - riscv_pmu->pmu->start(event, PERF_EF_RELOAD); > + riscv_pmu_start(event, PERF_EF_RELOAD); > > return 0; > } > @@ -459,8 +417,8 @@ static void riscv_pmu_del(struct perf_event *event, int flags) > cpuc->n_events--; > __clear_bit(hwc->idx, &cpuc->used_cntr_mask); > > - cpuc->events[hwc->idx] = NULL; > - riscv_pmu->pmu->stop(event, PERF_EF_UPDATE); > + riscv_pmu_stop(event, PERF_EF_UPDATE); > + > perf_event_update_userpage(event); > } > > @@ -470,7 +428,7 @@ static void riscv_pmu_del(struct perf_event *event, int flags) > > static DEFINE_MUTEX(pmc_reserve_mutex); > > -static irqreturn_t riscv_base_pmu_handle_irq(int irq_num, void *dev) > +static irqreturn_t riscv_pmu_handle_irq(int irq_num, void *dev) > { > return IRQ_NONE; > } > @@ -480,8 +438,8 @@ static int reserve_pmc_hardware(void) > int err = 0; > > mutex_lock(&pmc_reserve_mutex); > - if (riscv_pmu->irq >= 0 && riscv_pmu->handle_irq) { > - err = request_irq(riscv_pmu->irq, riscv_pmu->handle_irq, > + if (riscv_pmu.irq >= 0 && riscv_pmu.handle_irq) { > + err = request_irq(riscv_pmu.irq, riscv_pmu.handle_irq, > IRQF_PERCPU, "riscv-base-perf", NULL); > } > mutex_unlock(&pmc_reserve_mutex); > @@ -492,8 +450,8 @@ static int reserve_pmc_hardware(void) > static void release_pmc_hardware(void) > { > mutex_lock(&pmc_reserve_mutex); > - if (riscv_pmu->irq >= 0) > - free_irq(riscv_pmu->irq, NULL); > + if (riscv_pmu.irq >= 0) > + free_irq(riscv_pmu.irq, NULL); > mutex_unlock(&pmc_reserve_mutex); > } > > @@ -529,10 +487,10 @@ static int riscv_event_init(struct perf_event *event) > > switch (event->attr.type) { > case PERF_TYPE_HARDWARE: > - code = riscv_pmu->map_hw_event(attr->config); > + code = riscv_map_hw_event(attr->config); > break; > case PERF_TYPE_HW_CACHE: > - code = riscv_pmu->map_cache_event(attr->config); > + code = riscv_map_cache_event(attr->config); > break; > case PERF_TYPE_RAW: > code = attr->config; > @@ -555,9 +513,6 @@ static int riscv_event_init(struct perf_event *event) > /* > * idx is set to -1 because the index of a general event should not be > * decided until binding to some counter in pmu->add(). > - * > - * But since we don't have such support, later in pmu->add(), we just > - * use hwc->config as the index instead. > */ > hwc->config_base = config_base; > hwc->config = code; > @@ -570,52 +525,70 @@ static int riscv_event_init(struct perf_event *event) > * Initialization > */ > > -static struct pmu min_pmu = { > - .name = "riscv-base", > - .event_init = riscv_event_init, > - .add = riscv_pmu_add, > - .del = riscv_pmu_del, > - .start = riscv_pmu_start, > - .stop = riscv_pmu_stop, > - .read = riscv_pmu_read, > -}; > +static struct riscv_pmu riscv_pmu = { > + .pmu = &(struct pmu) { > + .name = "riscv-pmu", > + .event_init = riscv_event_init, > + .add = riscv_pmu_add, > + .del = riscv_pmu_del, > + .start = riscv_pmu_start, > + .stop = riscv_pmu_stop, > + .read = riscv_pmu_read, > + }, > > -static const struct riscv_pmu riscv_base_pmu = { > - .pmu = &min_pmu, > - .max_events = ARRAY_SIZE(riscv_hw_event_map), > - .map_hw_event = riscv_map_hw_event, > - .hw_events = riscv_hw_event_map, > - .map_cache_event = riscv_map_cache_event, > - .cache_events = &riscv_cache_event_map, > - .counter_width = 63, > - .num_counters = RISCV_BASE_COUNTERS + 0, > - .handle_irq = &riscv_base_pmu_handle_irq, > + .num_event_cntr = 0, > + .width_event_cntr = RISCV_DEFAULT_WIDTH_COUNTER, > + .width_base_cntr = RISCV_DEFAULT_WIDTH_COUNTER, > > + .handle_irq = &riscv_pmu_handle_irq, > /* This means this PMU has no IRQ. */ > .irq = -1, > }; > > -static const struct of_device_id riscv_pmu_of_ids[] = { > - {.compatible = "riscv,base-pmu", .data = &riscv_base_pmu}, > - { /* sentinel value */ } > -}; > +static int __init init_riscv_pmu(struct device_node *node) > +{ > + int num_events, key, value, i; > + > + of_property_read_u32(node, "riscv,width-base-cntr", &riscv_pmu.width_base_cntr); > + > + of_property_read_u32(node, "riscv,width-event-cntr", &riscv_pmu.width_event_cntr); > + > + of_property_read_u32(node, "riscv,n-event-cntr", &riscv_pmu.num_event_cntr); > + if (riscv_pmu.num_event_cntr > RISCV_EVENT_COUNTERS) > + riscv_pmu.num_event_cntr = RISCV_EVENT_COUNTERS; > + > + num_events = of_property_count_u32_elems(node, "riscv,hw-event-map"); > + if (num_events > 0 && num_events % 2 == 0) > + for (i = 0; i < num_events;) { > + of_property_read_u32_index(node, "riscv,hw-event-map", i++, &key); > + of_property_read_u32_index(node, "riscv,hw-event-map", i++, &value); > + riscv_hw_event_map[key] = value; > + } > + > + num_events = of_property_count_u32_elems(node, "riscv,hw-cache-event-map"); > + if (num_events > 0 && num_events % 2 == 0) > + for (i = 0; i < num_events;) { > + of_property_read_u32_index(node, "riscv,hw-cache-event-map", i++, &key); > + of_property_read_u32_index(node, "riscv,hw-cache-event-map", i++, &value); > + riscv_cache_event_map > + [(key >> PERF_HW_CACHE_TYPE) & PERF_HW_CACHE_MASK] > + [(key >> PERF_HW_CACHE_OP) & PERF_HW_CACHE_MASK] > + [(key >> PERF_HW_CACHE_RESULT) & PERF_HW_CACHE_MASK] = value; > + } > + > + return 0; > +} > > static int __init init_hw_perf_events(void) > { > - struct device_node *node = of_find_node_by_type(NULL, "pmu"); > - const struct of_device_id *of_id; > + struct device_node *node = of_find_compatible_node(NULL, NULL, "riscv,pmu"); > > - riscv_pmu = &riscv_base_pmu; > + if (node) > + init_riscv_pmu(node); > > - if (node) { > - of_id = of_match_node(riscv_pmu_of_ids, node); > - > - if (of_id) > - riscv_pmu = of_id->data; > - of_node_put(node); > - } > + /* Even if there is no pmu node in DT, we reach here for base PMU. */ > + perf_pmu_register(riscv_pmu.pmu, "cpu", PERF_TYPE_RAW); > > - perf_pmu_register(riscv_pmu->pmu, "cpu", PERF_TYPE_RAW); > return 0; > } > arch_initcall(init_hw_perf_events); Why does this have to arch_initcall() ?? Why can't we just probe this like a regular DT based driver ?? This driver needs total re-write because it has to be a platform driver. Even the names of counters are not registered. The implementation specific counter names should come from DT property. Regards, Anup > -- > 2.27.0 > _______________________________________________ linux-riscv mailing list linux-riscv@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-riscv ^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: [RFC PATCH 5/6] riscv: perf: introduce DT mechanism 2020-06-29 4:36 ` Anup Patel @ 2020-06-29 6:26 ` Zong Li 0 siblings, 0 replies; 38+ messages in thread From: Zong Li @ 2020-06-29 6:26 UTC (permalink / raw) To: Anup Patel Cc: linux-riscv, Palmer Dabbelt, linux-kernel@vger.kernel.org List, Paul Walmsley On Mon, Jun 29, 2020 at 12:37 PM Anup Patel <anup@brainfault.org> wrote: > > On Mon, Jun 29, 2020 at 8:49 AM Zong Li <zong.li@sifive.com> wrote: > > > > Each architecture is responsible for mapping generic hardware and cache > > events to their own specific encoding of hardware events. For each > > architecture, it also have to distinguish the defination of hardware > > events of different platforms of each vendor. We use DT file to describe > > platform-specific information to make our perf implementation more > > generic and common. > > > > Signed-off-by: Zong Li <zong.li@sifive.com> > > --- > > arch/riscv/include/asm/perf_event.h | 55 ++---- > > arch/riscv/kernel/perf_event.c | 273 +++++++++++++--------------- > > 2 files changed, 139 insertions(+), 189 deletions(-) > > > > diff --git a/arch/riscv/include/asm/perf_event.h b/arch/riscv/include/asm/perf_event.h > > index 41d515a1f331..e95d3bbaae3e 100644 > > --- a/arch/riscv/include/asm/perf_event.h > > +++ b/arch/riscv/include/asm/perf_event.h > > @@ -17,6 +17,8 @@ > > #define RISCV_EVENT_COUNTERS 29 > > #define RISCV_TOTAL_COUNTERS (RISCV_BASE_COUNTERS + RISCV_EVENT_COUNTERS) > > > > +#define RISCV_DEFAULT_WIDTH_COUNTER 64 > > + > > /* > > * According to the spec, an implementation can support counter up to > > * mhpmcounter31, but many high-end processors has at most 6 general > > @@ -33,9 +35,21 @@ > > > > #define RISCV_PMU_HPMCOUNTER_FIRST 3 > > #define RISCV_PMU_HPMCOUNTER_LAST \ > > - (RISCV_PMU_HPMCOUNTER_FIRST + riscv_pmu->num_counters - 1) > > + (RISCV_PMU_HPMCOUNTER_FIRST + riscv_pmu.num_event_cntr - 1) > > + > > +#define RISCV_OP_UNSUPP (-EOPNOTSUPP) > > + > > +#define RISCV_MAP_ALL_UNSUPPORTED \ > > + [0 ... PERF_COUNT_HW_MAX - 1] = RISCV_OP_UNSUPP > > > > -#define RISCV_OP_UNSUPP (-EOPNOTSUPP) > > +#define C(x) PERF_COUNT_HW_CACHE_##x > > + > > +#define RISCV_CACHE_MAP_ALL_UNSUPPORTED \ > > +[0 ... C(MAX) - 1] = { \ > > + [0 ... C(OP_MAX) - 1] = { \ > > + [0 ... C(RESULT_MAX) - 1] = RISCV_OP_UNSUPP, \ > > + }, \ > > +} > > > > /* Hardware cache event encoding */ > > #define PERF_HW_CACHE_TYPE 0 > > @@ -65,43 +79,6 @@ > > #define CSR_MHPMEVENT7 0x327 > > #define CSR_MHPMEVENT8 0x328 > > > > -struct cpu_hw_events { > > - /* # currently enabled events*/ > > - int n_events; > > - /* currently enabled events */ > > - struct perf_event *events[RISCV_EVENT_COUNTERS]; > > - /* bitmap of used event counters */ > > - unsigned long used_cntr_mask; > > - /* vendor-defined PMU data */ > > - void *platform; > > -}; > > - > > -struct riscv_pmu { > > - struct pmu *pmu; > > - > > - /* generic hw/cache events table */ > > - const int *hw_events; > > - const int (*cache_events)[PERF_COUNT_HW_CACHE_MAX] > > - [PERF_COUNT_HW_CACHE_OP_MAX] > > - [PERF_COUNT_HW_CACHE_RESULT_MAX]; > > - /* method used to map hw/cache events */ > > - int (*map_hw_event)(u64 config); > > - int (*map_cache_event)(u64 config); > > - > > - /* max generic hw events in map */ > > - int max_events; > > - /* number total counters, 2(base) + x(general) */ > > - int num_counters; > > - /* the width of the counter */ > > - int counter_width; > > - > > - /* vendor-defined PMU features */ > > - void *platform; > > - > > - irqreturn_t (*handle_irq)(int irq_num, void *dev); > > - int irq; > > -}; > > - > > #endif > > #ifdef CONFIG_PERF_EVENTS > > #define perf_arch_bpf_user_pt_regs(regs) (struct user_regs_struct *)regs > > diff --git a/arch/riscv/kernel/perf_event.c b/arch/riscv/kernel/perf_event.c > > index 0cfcd6f1e57b..3bdfbe4efd5c 100644 > > --- a/arch/riscv/kernel/perf_event.c > > +++ b/arch/riscv/kernel/perf_event.c > > @@ -9,6 +9,7 @@ > > * Copyright (C) 2009 Google, Inc., Stephane Eranian > > * Copyright 2014 Tilera Corporation. All Rights Reserved. > > * Copyright (C) 2018 Andes Technology Corporation > > + * Copyright (C) 2020 SiFive > > * > > * Perf_events support for RISC-V platforms. > > * > > @@ -30,113 +31,55 @@ > > #include <linux/perf_event.h> > > #include <linux/atomic.h> > > #include <linux/of.h> > > +#include <asm/csr.h> > > #include <asm/perf_event.h> > > > > -static const struct riscv_pmu *riscv_pmu __read_mostly; > > +static struct riscv_pmu { > > + struct pmu *pmu; > > + > > + /* number of event counters */ > > + int num_event_cntr; > > + > > + /* the width of base counters */ > > + int width_base_cntr; > > + > > + /* the width of event counters */ > > + int width_event_cntr; > > + > > + irqreturn_t (*handle_irq)(int irq_num, void *dev); > > + > > + int irq; > > +} riscv_pmu; > > + > > +struct cpu_hw_events { > > + /* # currently enabled events*/ > > + int n_events; > > + > > + /* currently enabled events */ > > + struct perf_event *events[RISCV_EVENT_COUNTERS]; > > + > > + /* bitmap of used event counters */ > > + unsigned long used_cntr_mask; > > +}; > > + > > static DEFINE_PER_CPU(struct cpu_hw_events, cpu_hw_events); > > > > /* > > * Hardware & cache maps and their methods > > */ > > > > -static const int riscv_hw_event_map[] = { > > - [PERF_COUNT_HW_CPU_CYCLES] = RISCV_PMU_CYCLE, > > - [PERF_COUNT_HW_INSTRUCTIONS] = RISCV_PMU_INSTRET, > > - [PERF_COUNT_HW_CACHE_REFERENCES] = RISCV_OP_UNSUPP, > > - [PERF_COUNT_HW_CACHE_MISSES] = RISCV_OP_UNSUPP, > > - [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = RISCV_OP_UNSUPP, > > - [PERF_COUNT_HW_BRANCH_MISSES] = RISCV_OP_UNSUPP, > > - [PERF_COUNT_HW_BUS_CYCLES] = RISCV_OP_UNSUPP, > > +static int riscv_hw_event_map[PERF_COUNT_HW_MAX] = { > > + RISCV_MAP_ALL_UNSUPPORTED, > > + > > + /* Specify base pmu, even if they aren't present in DT file */ > > + [PERF_COUNT_HW_CPU_CYCLES] = RISCV_PMU_CYCLE, > > + [PERF_COUNT_HW_INSTRUCTIONS] = RISCV_PMU_INSTRET, > > }; > > > > -#define C(x) PERF_COUNT_HW_CACHE_##x > > -static const int riscv_cache_event_map[PERF_COUNT_HW_CACHE_MAX] > > -[PERF_COUNT_HW_CACHE_OP_MAX] > > -[PERF_COUNT_HW_CACHE_RESULT_MAX] = { > > - [C(L1D)] = { > > - [C(OP_READ)] = { > > - [C(RESULT_ACCESS)] = RISCV_OP_UNSUPP, > > - [C(RESULT_MISS)] = RISCV_OP_UNSUPP, > > - }, > > - [C(OP_WRITE)] = { > > - [C(RESULT_ACCESS)] = RISCV_OP_UNSUPP, > > - [C(RESULT_MISS)] = RISCV_OP_UNSUPP, > > - }, > > - [C(OP_PREFETCH)] = { > > - [C(RESULT_ACCESS)] = RISCV_OP_UNSUPP, > > - [C(RESULT_MISS)] = RISCV_OP_UNSUPP, > > - }, > > - }, > > - [C(L1I)] = { > > - [C(OP_READ)] = { > > - [C(RESULT_ACCESS)] = RISCV_OP_UNSUPP, > > - [C(RESULT_MISS)] = RISCV_OP_UNSUPP, > > - }, > > - [C(OP_WRITE)] = { > > - [C(RESULT_ACCESS)] = RISCV_OP_UNSUPP, > > - [C(RESULT_MISS)] = RISCV_OP_UNSUPP, > > - }, > > - [C(OP_PREFETCH)] = { > > - [C(RESULT_ACCESS)] = RISCV_OP_UNSUPP, > > - [C(RESULT_MISS)] = RISCV_OP_UNSUPP, > > - }, > > - }, > > - [C(LL)] = { > > - [C(OP_READ)] = { > > - [C(RESULT_ACCESS)] = RISCV_OP_UNSUPP, > > - [C(RESULT_MISS)] = RISCV_OP_UNSUPP, > > - }, > > - [C(OP_WRITE)] = { > > - [C(RESULT_ACCESS)] = RISCV_OP_UNSUPP, > > - [C(RESULT_MISS)] = RISCV_OP_UNSUPP, > > - }, > > - [C(OP_PREFETCH)] = { > > - [C(RESULT_ACCESS)] = RISCV_OP_UNSUPP, > > - [C(RESULT_MISS)] = RISCV_OP_UNSUPP, > > - }, > > - }, > > - [C(DTLB)] = { > > - [C(OP_READ)] = { > > - [C(RESULT_ACCESS)] = RISCV_OP_UNSUPP, > > - [C(RESULT_MISS)] = RISCV_OP_UNSUPP, > > - }, > > - [C(OP_WRITE)] = { > > - [C(RESULT_ACCESS)] = RISCV_OP_UNSUPP, > > - [C(RESULT_MISS)] = RISCV_OP_UNSUPP, > > - }, > > - [C(OP_PREFETCH)] = { > > - [C(RESULT_ACCESS)] = RISCV_OP_UNSUPP, > > - [C(RESULT_MISS)] = RISCV_OP_UNSUPP, > > - }, > > - }, > > - [C(ITLB)] = { > > - [C(OP_READ)] = { > > - [C(RESULT_ACCESS)] = RISCV_OP_UNSUPP, > > - [C(RESULT_MISS)] = RISCV_OP_UNSUPP, > > - }, > > - [C(OP_WRITE)] = { > > - [C(RESULT_ACCESS)] = RISCV_OP_UNSUPP, > > - [C(RESULT_MISS)] = RISCV_OP_UNSUPP, > > - }, > > - [C(OP_PREFETCH)] = { > > - [C(RESULT_ACCESS)] = RISCV_OP_UNSUPP, > > - [C(RESULT_MISS)] = RISCV_OP_UNSUPP, > > - }, > > - }, > > - [C(BPU)] = { > > - [C(OP_READ)] = { > > - [C(RESULT_ACCESS)] = RISCV_OP_UNSUPP, > > - [C(RESULT_MISS)] = RISCV_OP_UNSUPP, > > - }, > > - [C(OP_WRITE)] = { > > - [C(RESULT_ACCESS)] = RISCV_OP_UNSUPP, > > - [C(RESULT_MISS)] = RISCV_OP_UNSUPP, > > - }, > > - [C(OP_PREFETCH)] = { > > - [C(RESULT_ACCESS)] = RISCV_OP_UNSUPP, > > - [C(RESULT_MISS)] = RISCV_OP_UNSUPP, > > - }, > > - }, > > +static int riscv_cache_event_map[PERF_COUNT_HW_CACHE_MAX] > > + [PERF_COUNT_HW_CACHE_OP_MAX] > > + [PERF_COUNT_HW_CACHE_RESULT_MAX] = { > > + RISCV_CACHE_MAP_ALL_UNSUPPORTED, > > }; > > > > /* > > @@ -154,6 +97,17 @@ static inline int is_event_counter(int idx) > > idx <= RISCV_PMU_HPMCOUNTER_LAST); > > } > > > > +static inline int get_counter_width(int idx) > > +{ > > + if (is_base_counter(idx)) > > + return riscv_pmu.width_base_cntr; > > + > > + if (is_event_counter(idx)) > > + return riscv_pmu.width_event_cntr; > > + > > + return 0; > > +} > > + > > static inline int get_available_counter(struct perf_event *event) > > { > > struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events); > > @@ -188,10 +142,14 @@ static inline int get_available_counter(struct perf_event *event) > > */ > > static int riscv_map_hw_event(u64 config) > > { > > - if (config >= riscv_pmu->max_events) > > + int ret; > > + > > + if (config >= PERF_COUNT_HW_MAX) > > return -EINVAL; > > > > - return riscv_pmu->hw_events[config]; > > + ret = riscv_hw_event_map[config]; > > + > > + return ret == RISCV_OP_UNSUPP ? -ENOENT : ret; > > } > > > > /* > > @@ -355,7 +313,7 @@ static void riscv_pmu_read(struct perf_event *event) > > * delta is the value to update the counter we maintain in the kernel. > > */ > > delta = (new_raw_count - prev_raw_count) & > > - ((1ULL << riscv_pmu->counter_width) - 1); > > + ((1ULL << get_counter_width(idx)) - 1); > > > > local64_add(delta, &event->count); > > /* > > @@ -386,7 +344,7 @@ static void riscv_pmu_stop(struct perf_event *event, int flags) > > hwc->state |= PERF_HES_STOPPED; > > > > if ((flags & PERF_EF_UPDATE) && !(hwc->state & PERF_HES_UPTODATE)) { > > - riscv_pmu->pmu->read(event); > > + riscv_pmu_read(event); > > hwc->state |= PERF_HES_UPTODATE; > > } > > } > > @@ -429,7 +387,7 @@ static int riscv_pmu_add(struct perf_event *event, int flags) > > struct hw_perf_event *hwc = &event->hw; > > int count_idx; > > > > - if (cpuc->n_events == riscv_pmu->num_counters) > > + if (cpuc->n_events == riscv_pmu.num_event_cntr) > > return -ENOSPC; > > > > count_idx = get_available_counter(event); > > @@ -437,13 +395,13 @@ static int riscv_pmu_add(struct perf_event *event, int flags) > > return -ENOSPC; > > > > cpuc->n_events++; > > + > > hwc->idx = count_idx; > > - cpuc->events[hwc->idx] = event; > > > > hwc->state = PERF_HES_UPTODATE | PERF_HES_STOPPED; > > > > if (flags & PERF_EF_START) > > - riscv_pmu->pmu->start(event, PERF_EF_RELOAD); > > + riscv_pmu_start(event, PERF_EF_RELOAD); > > > > return 0; > > } > > @@ -459,8 +417,8 @@ static void riscv_pmu_del(struct perf_event *event, int flags) > > cpuc->n_events--; > > __clear_bit(hwc->idx, &cpuc->used_cntr_mask); > > > > - cpuc->events[hwc->idx] = NULL; > > - riscv_pmu->pmu->stop(event, PERF_EF_UPDATE); > > + riscv_pmu_stop(event, PERF_EF_UPDATE); > > + > > perf_event_update_userpage(event); > > } > > > > @@ -470,7 +428,7 @@ static void riscv_pmu_del(struct perf_event *event, int flags) > > > > static DEFINE_MUTEX(pmc_reserve_mutex); > > > > -static irqreturn_t riscv_base_pmu_handle_irq(int irq_num, void *dev) > > +static irqreturn_t riscv_pmu_handle_irq(int irq_num, void *dev) > > { > > return IRQ_NONE; > > } > > @@ -480,8 +438,8 @@ static int reserve_pmc_hardware(void) > > int err = 0; > > > > mutex_lock(&pmc_reserve_mutex); > > - if (riscv_pmu->irq >= 0 && riscv_pmu->handle_irq) { > > - err = request_irq(riscv_pmu->irq, riscv_pmu->handle_irq, > > + if (riscv_pmu.irq >= 0 && riscv_pmu.handle_irq) { > > + err = request_irq(riscv_pmu.irq, riscv_pmu.handle_irq, > > IRQF_PERCPU, "riscv-base-perf", NULL); > > } > > mutex_unlock(&pmc_reserve_mutex); > > @@ -492,8 +450,8 @@ static int reserve_pmc_hardware(void) > > static void release_pmc_hardware(void) > > { > > mutex_lock(&pmc_reserve_mutex); > > - if (riscv_pmu->irq >= 0) > > - free_irq(riscv_pmu->irq, NULL); > > + if (riscv_pmu.irq >= 0) > > + free_irq(riscv_pmu.irq, NULL); > > mutex_unlock(&pmc_reserve_mutex); > > } > > > > @@ -529,10 +487,10 @@ static int riscv_event_init(struct perf_event *event) > > > > switch (event->attr.type) { > > case PERF_TYPE_HARDWARE: > > - code = riscv_pmu->map_hw_event(attr->config); > > + code = riscv_map_hw_event(attr->config); > > break; > > case PERF_TYPE_HW_CACHE: > > - code = riscv_pmu->map_cache_event(attr->config); > > + code = riscv_map_cache_event(attr->config); > > break; > > case PERF_TYPE_RAW: > > code = attr->config; > > @@ -555,9 +513,6 @@ static int riscv_event_init(struct perf_event *event) > > /* > > * idx is set to -1 because the index of a general event should not be > > * decided until binding to some counter in pmu->add(). > > - * > > - * But since we don't have such support, later in pmu->add(), we just > > - * use hwc->config as the index instead. > > */ > > hwc->config_base = config_base; > > hwc->config = code; > > @@ -570,52 +525,70 @@ static int riscv_event_init(struct perf_event *event) > > * Initialization > > */ > > > > -static struct pmu min_pmu = { > > - .name = "riscv-base", > > - .event_init = riscv_event_init, > > - .add = riscv_pmu_add, > > - .del = riscv_pmu_del, > > - .start = riscv_pmu_start, > > - .stop = riscv_pmu_stop, > > - .read = riscv_pmu_read, > > -}; > > +static struct riscv_pmu riscv_pmu = { > > + .pmu = &(struct pmu) { > > + .name = "riscv-pmu", > > + .event_init = riscv_event_init, > > + .add = riscv_pmu_add, > > + .del = riscv_pmu_del, > > + .start = riscv_pmu_start, > > + .stop = riscv_pmu_stop, > > + .read = riscv_pmu_read, > > + }, > > > > -static const struct riscv_pmu riscv_base_pmu = { > > - .pmu = &min_pmu, > > - .max_events = ARRAY_SIZE(riscv_hw_event_map), > > - .map_hw_event = riscv_map_hw_event, > > - .hw_events = riscv_hw_event_map, > > - .map_cache_event = riscv_map_cache_event, > > - .cache_events = &riscv_cache_event_map, > > - .counter_width = 63, > > - .num_counters = RISCV_BASE_COUNTERS + 0, > > - .handle_irq = &riscv_base_pmu_handle_irq, > > + .num_event_cntr = 0, > > + .width_event_cntr = RISCV_DEFAULT_WIDTH_COUNTER, > > + .width_base_cntr = RISCV_DEFAULT_WIDTH_COUNTER, > > > > + .handle_irq = &riscv_pmu_handle_irq, > > /* This means this PMU has no IRQ. */ > > .irq = -1, > > }; > > > > -static const struct of_device_id riscv_pmu_of_ids[] = { > > - {.compatible = "riscv,base-pmu", .data = &riscv_base_pmu}, > > - { /* sentinel value */ } > > -}; > > +static int __init init_riscv_pmu(struct device_node *node) > > +{ > > + int num_events, key, value, i; > > + > > + of_property_read_u32(node, "riscv,width-base-cntr", &riscv_pmu.width_base_cntr); > > + > > + of_property_read_u32(node, "riscv,width-event-cntr", &riscv_pmu.width_event_cntr); > > + > > + of_property_read_u32(node, "riscv,n-event-cntr", &riscv_pmu.num_event_cntr); > > + if (riscv_pmu.num_event_cntr > RISCV_EVENT_COUNTERS) > > + riscv_pmu.num_event_cntr = RISCV_EVENT_COUNTERS; > > + > > + num_events = of_property_count_u32_elems(node, "riscv,hw-event-map"); > > + if (num_events > 0 && num_events % 2 == 0) > > + for (i = 0; i < num_events;) { > > + of_property_read_u32_index(node, "riscv,hw-event-map", i++, &key); > > + of_property_read_u32_index(node, "riscv,hw-event-map", i++, &value); > > + riscv_hw_event_map[key] = value; > > + } > > + > > + num_events = of_property_count_u32_elems(node, "riscv,hw-cache-event-map"); > > + if (num_events > 0 && num_events % 2 == 0) > > + for (i = 0; i < num_events;) { > > + of_property_read_u32_index(node, "riscv,hw-cache-event-map", i++, &key); > > + of_property_read_u32_index(node, "riscv,hw-cache-event-map", i++, &value); > > + riscv_cache_event_map > > + [(key >> PERF_HW_CACHE_TYPE) & PERF_HW_CACHE_MASK] > > + [(key >> PERF_HW_CACHE_OP) & PERF_HW_CACHE_MASK] > > + [(key >> PERF_HW_CACHE_RESULT) & PERF_HW_CACHE_MASK] = value; > > + } > > + > > + return 0; > > +} > > > > static int __init init_hw_perf_events(void) > > { > > - struct device_node *node = of_find_node_by_type(NULL, "pmu"); > > - const struct of_device_id *of_id; > > + struct device_node *node = of_find_compatible_node(NULL, NULL, "riscv,pmu"); > > > > - riscv_pmu = &riscv_base_pmu; > > + if (node) > > + init_riscv_pmu(node); > > > > - if (node) { > > - of_id = of_match_node(riscv_pmu_of_ids, node); > > - > > - if (of_id) > > - riscv_pmu = of_id->data; > > - of_node_put(node); > > - } > > + /* Even if there is no pmu node in DT, we reach here for base PMU. */ > > + perf_pmu_register(riscv_pmu.pmu, "cpu", PERF_TYPE_RAW); > > > > - perf_pmu_register(riscv_pmu->pmu, "cpu", PERF_TYPE_RAW); > > return 0; > > } > > arch_initcall(init_hw_perf_events); > > Why does this have to arch_initcall() ?? > Why can't we just probe this like a regular DT based driver ?? > > This driver needs total re-write because it has to be a platform driver. > Even the names of counters are not registered. The implementation > specific counter names should come from DT property. > We have some discussion in the cover letter, let us talk about in one place. :) > Regards, > Anup > > > -- > > 2.27.0 > > _______________________________________________ linux-riscv mailing list linux-riscv@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-riscv ^ permalink raw reply [flat|nested] 38+ messages in thread
* [RFC PATCH 6/6] riscv: remove PMU menu of Kconfig 2020-06-29 3:19 [RFC PATCH 0/6] Support raw event and DT for perf on RISC-V Zong Li ` (4 preceding siblings ...) 2020-06-29 3:19 ` [RFC PATCH 5/6] riscv: perf: introduce DT mechanism Zong Li @ 2020-06-29 3:19 ` Zong Li 2020-06-29 4:52 ` [RFC PATCH 0/6] Support raw event and DT for perf on RISC-V Anup Patel 2020-07-01 0:51 ` Alan Kao 7 siblings, 0 replies; 38+ messages in thread From: Zong Li @ 2020-06-29 3:19 UTC (permalink / raw) To: palmer, paul.walmsley, linux-riscv, linux-kernel; +Cc: Zong Li We only one instance of riscv_pmu now, and use DT file to describe the platform-specific information, so drop the dependency and menu of RISCV_BASE_PMU. Signed-off-by: Zong Li <zong.li@sifive.com> --- arch/riscv/Kconfig | 13 ------------- arch/riscv/include/asm/perf_event.h | 2 -- arch/riscv/kernel/Makefile | 2 +- 3 files changed, 1 insertion(+), 16 deletions(-) diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig index 128192e14ff2..deec11e924ce 100644 --- a/arch/riscv/Kconfig +++ b/arch/riscv/Kconfig @@ -292,19 +292,6 @@ config RISCV_ISA_C If you don't know what to do here, say Y. -menu "supported PMU type" - depends on PERF_EVENTS - -config RISCV_BASE_PMU - bool "Base Performance Monitoring Unit" - def_bool y - help - A base PMU that serves as a reference implementation and has limited - feature of perf. It can run on any RISC-V machines so serves as the - fallback, but this option can also be disable to reduce kernel size. - -endmenu - config FPU bool "FPU support" default y diff --git a/arch/riscv/include/asm/perf_event.h b/arch/riscv/include/asm/perf_event.h index e95d3bbaae3e..9ee654381d8c 100644 --- a/arch/riscv/include/asm/perf_event.h +++ b/arch/riscv/include/asm/perf_event.h @@ -12,7 +12,6 @@ #include <linux/ptrace.h> #include <linux/interrupt.h> -#ifdef CONFIG_RISCV_BASE_PMU #define RISCV_BASE_COUNTERS 2 #define RISCV_EVENT_COUNTERS 29 #define RISCV_TOTAL_COUNTERS (RISCV_BASE_COUNTERS + RISCV_EVENT_COUNTERS) @@ -79,7 +78,6 @@ #define CSR_MHPMEVENT7 0x327 #define CSR_MHPMEVENT8 0x328 -#endif #ifdef CONFIG_PERF_EVENTS #define perf_arch_bpf_user_pt_regs(regs) (struct user_regs_struct *)regs #endif diff --git a/arch/riscv/kernel/Makefile b/arch/riscv/kernel/Makefile index b355cf485671..1f5736e996fd 100644 --- a/arch/riscv/kernel/Makefile +++ b/arch/riscv/kernel/Makefile @@ -43,7 +43,7 @@ obj-$(CONFIG_MODULE_SECTIONS) += module-sections.o obj-$(CONFIG_FUNCTION_TRACER) += mcount.o ftrace.o obj-$(CONFIG_DYNAMIC_FTRACE) += mcount-dyn.o -obj-$(CONFIG_RISCV_BASE_PMU) += perf_event.o +obj-$(CONFIG_PERF_EVENTS) += perf_event.o obj-$(CONFIG_PERF_EVENTS) += perf_callchain.o obj-$(CONFIG_HAVE_PERF_REGS) += perf_regs.o obj-$(CONFIG_RISCV_SBI) += sbi.o -- 2.27.0 _______________________________________________ linux-riscv mailing list linux-riscv@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-riscv ^ permalink raw reply related [flat|nested] 38+ messages in thread
* Re: [RFC PATCH 0/6] Support raw event and DT for perf on RISC-V 2020-06-29 3:19 [RFC PATCH 0/6] Support raw event and DT for perf on RISC-V Zong Li ` (5 preceding siblings ...) 2020-06-29 3:19 ` [RFC PATCH 6/6] riscv: remove PMU menu of Kconfig Zong Li @ 2020-06-29 4:52 ` Anup Patel 2020-06-29 5:52 ` Zong Li 2020-07-01 0:51 ` Alan Kao 7 siblings, 1 reply; 38+ messages in thread From: Anup Patel @ 2020-06-29 4:52 UTC (permalink / raw) To: Zong Li Cc: linux-riscv, Palmer Dabbelt, linux-kernel@vger.kernel.org List, Paul Walmsley On Mon, Jun 29, 2020 at 8:49 AM Zong Li <zong.li@sifive.com> wrote: > > This patch set adds raw event support on RISC-V. In addition, we > introduce the DT mechanism to make our perf more generic and common. > > Currently, we set the hardware events by writing the mhpmeventN CSRs, it > would raise an illegal instruction exception and trap into m-mode to > emulate event selector CSRs access. It doesn't make sense because we > shouldn't write the m-mode CSRs in s-mode. Ideally, we should set event > selector through standard SBI call or the shadow CSRs of s-mode. We have > prepared a proposal of a new SBI extension, called "PMU SBI extension", > but we also discussing the feasibility of accessing these PMU CSRs on > s-mode at the same time, such as delegation mechanism, so I was > wondering if we could use SBI calls first and make the PMU SBI extension > as legacy when s-mode access mechanism is accepted by Foundation? or > keep the current situation to see what would happen in the future. > > This patch set also introduces the DT mechanism, we don't want to add too > much platform-dependency code in perf like other architectures, so we > put the mapping of generic hardware events to DT, then we can easy to > transfer generic hardware events to vendor's own hardware events without > any platfrom-dependency stuff in our perf. Please re-write this series to have RISC-V PMU driver as a regular platform driver as drivers/perf/riscv_pmu.c. The PMU related sources will have to be removed from arch/riscv. Based on implementation of final drivers/perf/riscv_pmu.c we will come-up with drivers/perf/riscv_sbi_pmu.c driver for SBI perf counters. Regards, Anup > > Zong Li (6): > dt-bindings: riscv: Add YAML documentation for PMU > riscv: dts: sifive: Add DT support for PMU > riscv: add definition of hpmcounter CSRs > riscv: perf: Add raw event support > riscv: perf: introduce DT mechanism > riscv: remove PMU menu of Kconfig > > .../devicetree/bindings/riscv/pmu.yaml | 59 +++ > arch/riscv/Kconfig | 13 - > arch/riscv/boot/dts/sifive/fu540-c000.dtsi | 13 + > arch/riscv/include/asm/csr.h | 58 +++ > arch/riscv/include/asm/perf_event.h | 100 ++-- > arch/riscv/kernel/Makefile | 2 +- > arch/riscv/kernel/perf_event.c | 471 +++++++++++------- > 7 files changed, 471 insertions(+), 245 deletions(-) > create mode 100644 Documentation/devicetree/bindings/riscv/pmu.yaml > > -- > 2.27.0 > _______________________________________________ linux-riscv mailing list linux-riscv@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-riscv ^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: [RFC PATCH 0/6] Support raw event and DT for perf on RISC-V 2020-06-29 4:52 ` [RFC PATCH 0/6] Support raw event and DT for perf on RISC-V Anup Patel @ 2020-06-29 5:52 ` Zong Li 2020-06-29 8:27 ` Anup Patel 0 siblings, 1 reply; 38+ messages in thread From: Zong Li @ 2020-06-29 5:52 UTC (permalink / raw) To: Anup Patel, alankao Cc: linux-riscv, Palmer Dabbelt, linux-kernel@vger.kernel.org List, Paul Walmsley On Mon, Jun 29, 2020 at 12:53 PM Anup Patel <anup@brainfault.org> wrote: > > On Mon, Jun 29, 2020 at 8:49 AM Zong Li <zong.li@sifive.com> wrote: > > > > This patch set adds raw event support on RISC-V. In addition, we > > introduce the DT mechanism to make our perf more generic and common. > > > > Currently, we set the hardware events by writing the mhpmeventN CSRs, it > > would raise an illegal instruction exception and trap into m-mode to > > emulate event selector CSRs access. It doesn't make sense because we > > shouldn't write the m-mode CSRs in s-mode. Ideally, we should set event > > selector through standard SBI call or the shadow CSRs of s-mode. We have > > prepared a proposal of a new SBI extension, called "PMU SBI extension", > > but we also discussing the feasibility of accessing these PMU CSRs on > > s-mode at the same time, such as delegation mechanism, so I was > > wondering if we could use SBI calls first and make the PMU SBI extension > > as legacy when s-mode access mechanism is accepted by Foundation? or > > keep the current situation to see what would happen in the future. > > > > This patch set also introduces the DT mechanism, we don't want to add too > > much platform-dependency code in perf like other architectures, so we > > put the mapping of generic hardware events to DT, then we can easy to > > transfer generic hardware events to vendor's own hardware events without > > any platfrom-dependency stuff in our perf. > > Please re-write this series to have RISC-V PMU driver as a regular > platform driver as drivers/perf/riscv_pmu.c. > > The PMU related sources will have to be removed from arch/riscv. > > Based on implementation of final drivers/perf/riscv_pmu.c we will > come-up with drivers/perf/riscv_sbi_pmu.c driver for SBI perf counters. > There are some different ways to implement perf, and current implementation seems to be consensus when perf was introduced at the beginning [0][1]. I don't persist to which one, I could change the implementation as you mentioned if it is a new consensus one. [0] https://github.com/riscv/riscv-linux/pull/124#issuecomment-367563910 [1] https://groups.google.com/a/groups.riscv.org/g/sw-dev/c/f19TmCNP6yA > Regards, > Anup > > > > > Zong Li (6): > > dt-bindings: riscv: Add YAML documentation for PMU > > riscv: dts: sifive: Add DT support for PMU > > riscv: add definition of hpmcounter CSRs > > riscv: perf: Add raw event support > > riscv: perf: introduce DT mechanism > > riscv: remove PMU menu of Kconfig > > > > .../devicetree/bindings/riscv/pmu.yaml | 59 +++ > > arch/riscv/Kconfig | 13 - > > arch/riscv/boot/dts/sifive/fu540-c000.dtsi | 13 + > > arch/riscv/include/asm/csr.h | 58 +++ > > arch/riscv/include/asm/perf_event.h | 100 ++-- > > arch/riscv/kernel/Makefile | 2 +- > > arch/riscv/kernel/perf_event.c | 471 +++++++++++------- > > 7 files changed, 471 insertions(+), 245 deletions(-) > > create mode 100644 Documentation/devicetree/bindings/riscv/pmu.yaml > > > > -- > > 2.27.0 > > _______________________________________________ linux-riscv mailing list linux-riscv@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-riscv ^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: [RFC PATCH 0/6] Support raw event and DT for perf on RISC-V 2020-06-29 5:52 ` Zong Li @ 2020-06-29 8:27 ` Anup Patel 2020-06-29 12:53 ` Zong Li 0 siblings, 1 reply; 38+ messages in thread From: Anup Patel @ 2020-06-29 8:27 UTC (permalink / raw) To: Zong Li Cc: linux-riscv, Palmer Dabbelt, linux-kernel@vger.kernel.org List, Alan Kao, Paul Walmsley On Mon, Jun 29, 2020 at 11:22 AM Zong Li <zong.li@sifive.com> wrote: > > On Mon, Jun 29, 2020 at 12:53 PM Anup Patel <anup@brainfault.org> wrote: > > > > On Mon, Jun 29, 2020 at 8:49 AM Zong Li <zong.li@sifive.com> wrote: > > > > > > This patch set adds raw event support on RISC-V. In addition, we > > > introduce the DT mechanism to make our perf more generic and common. > > > > > > Currently, we set the hardware events by writing the mhpmeventN CSRs, it > > > would raise an illegal instruction exception and trap into m-mode to > > > emulate event selector CSRs access. It doesn't make sense because we > > > shouldn't write the m-mode CSRs in s-mode. Ideally, we should set event > > > selector through standard SBI call or the shadow CSRs of s-mode. We have > > > prepared a proposal of a new SBI extension, called "PMU SBI extension", > > > but we also discussing the feasibility of accessing these PMU CSRs on > > > s-mode at the same time, such as delegation mechanism, so I was > > > wondering if we could use SBI calls first and make the PMU SBI extension > > > as legacy when s-mode access mechanism is accepted by Foundation? or > > > keep the current situation to see what would happen in the future. > > > > > > This patch set also introduces the DT mechanism, we don't want to add too > > > much platform-dependency code in perf like other architectures, so we > > > put the mapping of generic hardware events to DT, then we can easy to > > > transfer generic hardware events to vendor's own hardware events without > > > any platfrom-dependency stuff in our perf. > > > > Please re-write this series to have RISC-V PMU driver as a regular > > platform driver as drivers/perf/riscv_pmu.c. > > > > The PMU related sources will have to be removed from arch/riscv. > > > > Based on implementation of final drivers/perf/riscv_pmu.c we will > > come-up with drivers/perf/riscv_sbi_pmu.c driver for SBI perf counters. > > > > There are some different ways to implement perf, and current > implementation seems to be consensus when perf was introduced at the > beginning [0][1]. I don't persist to which one, I could change the > implementation as you mentioned if it is a new consensus one. > > [0] https://github.com/riscv/riscv-linux/pull/124#issuecomment-367563910 I would not recommend taking the original RISC-V linux fork as reference. Rather we should study how things are done on other architectures. I really appreciate the attempt to make RISC-V PMU driver depend on DT but if we are going this route then we should maximize the use of Linux platform driver framework. In fact, whenever possible we should integrate RISC-V features as platform drivers under the drivers/ directory. I thought about SBI PMU counters as well. In future, we can easily expose SBI PMU counters as RAW events in the same RISC-V PMU driver. The sbi_probe_extension() can be used in RISC-V PMU driver to check for SBI PMU counters so no special provisions needed in DT for SBI PMU counters. Also, the RISC-V PMU driver can be implemented such that it will work for RV32, RV64, NoMMU RV32, and NoMMU RV64. Regards, Anup > [1] https://groups.google.com/a/groups.riscv.org/g/sw-dev/c/f19TmCNP6yA > > > Regards, > > Anup > > > > > > > > Zong Li (6): > > > dt-bindings: riscv: Add YAML documentation for PMU > > > riscv: dts: sifive: Add DT support for PMU > > > riscv: add definition of hpmcounter CSRs > > > riscv: perf: Add raw event support > > > riscv: perf: introduce DT mechanism > > > riscv: remove PMU menu of Kconfig > > > > > > .../devicetree/bindings/riscv/pmu.yaml | 59 +++ > > > arch/riscv/Kconfig | 13 - > > > arch/riscv/boot/dts/sifive/fu540-c000.dtsi | 13 + > > > arch/riscv/include/asm/csr.h | 58 +++ > > > arch/riscv/include/asm/perf_event.h | 100 ++-- > > > arch/riscv/kernel/Makefile | 2 +- > > > arch/riscv/kernel/perf_event.c | 471 +++++++++++------- > > > 7 files changed, 471 insertions(+), 245 deletions(-) > > > create mode 100644 Documentation/devicetree/bindings/riscv/pmu.yaml > > > > > > -- > > > 2.27.0 > > > _______________________________________________ linux-riscv mailing list linux-riscv@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-riscv ^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: [RFC PATCH 0/6] Support raw event and DT for perf on RISC-V 2020-06-29 8:27 ` Anup Patel @ 2020-06-29 12:53 ` Zong Li 2020-06-29 13:23 ` Anup Patel 0 siblings, 1 reply; 38+ messages in thread From: Zong Li @ 2020-06-29 12:53 UTC (permalink / raw) To: Anup Patel Cc: linux-riscv, Palmer Dabbelt, linux-kernel@vger.kernel.org List, Alan Kao, Paul Walmsley On Mon, Jun 29, 2020 at 4:28 PM Anup Patel <anup@brainfault.org> wrote: > > On Mon, Jun 29, 2020 at 11:22 AM Zong Li <zong.li@sifive.com> wrote: > > > > On Mon, Jun 29, 2020 at 12:53 PM Anup Patel <anup@brainfault.org> wrote: > > > > > > On Mon, Jun 29, 2020 at 8:49 AM Zong Li <zong.li@sifive.com> wrote: > > > > > > > > This patch set adds raw event support on RISC-V. In addition, we > > > > introduce the DT mechanism to make our perf more generic and common. > > > > > > > > Currently, we set the hardware events by writing the mhpmeventN CSRs, it > > > > would raise an illegal instruction exception and trap into m-mode to > > > > emulate event selector CSRs access. It doesn't make sense because we > > > > shouldn't write the m-mode CSRs in s-mode. Ideally, we should set event > > > > selector through standard SBI call or the shadow CSRs of s-mode. We have > > > > prepared a proposal of a new SBI extension, called "PMU SBI extension", > > > > but we also discussing the feasibility of accessing these PMU CSRs on > > > > s-mode at the same time, such as delegation mechanism, so I was > > > > wondering if we could use SBI calls first and make the PMU SBI extension > > > > as legacy when s-mode access mechanism is accepted by Foundation? or > > > > keep the current situation to see what would happen in the future. > > > > > > > > This patch set also introduces the DT mechanism, we don't want to add too > > > > much platform-dependency code in perf like other architectures, so we > > > > put the mapping of generic hardware events to DT, then we can easy to > > > > transfer generic hardware events to vendor's own hardware events without > > > > any platfrom-dependency stuff in our perf. > > > > > > Please re-write this series to have RISC-V PMU driver as a regular > > > platform driver as drivers/perf/riscv_pmu.c. > > > > > > The PMU related sources will have to be removed from arch/riscv. > > > > > > Based on implementation of final drivers/perf/riscv_pmu.c we will > > > come-up with drivers/perf/riscv_sbi_pmu.c driver for SBI perf counters. > > > > > > > There are some different ways to implement perf, and current > > implementation seems to be consensus when perf was introduced at the > > beginning [0][1]. I don't persist to which one, I could change the > > implementation as you mentioned if it is a new consensus one. > > > > [0] https://github.com/riscv/riscv-linux/pull/124#issuecomment-367563910 > > I would not recommend taking the original RISC-V linux fork as reference. > > Rather we should study how things are done on other architectures. > > I really appreciate the attempt to make RISC-V PMU driver depend on DT > but if we are going this route then we should maximize the use of Linux > platform driver framework. In fact, whenever possible we should integrate > RISC-V features as platform drivers under the drivers/ directory. > OK, I would change the implementation to platform driver if there is no other voice. > I thought about SBI PMU counters as well. In future, we can easily > expose SBI PMU counters as RAW events in the same RISC-V PMU > driver. The sbi_probe_extension() can be used in RISC-V PMU driver > to check for SBI PMU counters so no special provisions needed in DT > for SBI PMU counters. > I thought about probing raw events by SBI extension too, I'm interested if you have more detail about this. It seems to me that it is a little bit hard to return all events through one SBI call, so I thought we could map the generic hardware events and maintain their own raw events by each platform in OpenSBI. But eventually, I thought the DT mechanism is more clear and easy than that. Let me know if you have any ideas about probe function. Thanks. > Also, the RISC-V PMU driver can be implemented such that it will > work for RV32, RV64, NoMMU RV32, and NoMMU RV64. > > Regards, > Anup > > > [1] https://groups.google.com/a/groups.riscv.org/g/sw-dev/c/f19TmCNP6yA > > > > > Regards, > > > Anup > > > > > > > > > > > Zong Li (6): > > > > dt-bindings: riscv: Add YAML documentation for PMU > > > > riscv: dts: sifive: Add DT support for PMU > > > > riscv: add definition of hpmcounter CSRs > > > > riscv: perf: Add raw event support > > > > riscv: perf: introduce DT mechanism > > > > riscv: remove PMU menu of Kconfig > > > > > > > > .../devicetree/bindings/riscv/pmu.yaml | 59 +++ > > > > arch/riscv/Kconfig | 13 - > > > > arch/riscv/boot/dts/sifive/fu540-c000.dtsi | 13 + > > > > arch/riscv/include/asm/csr.h | 58 +++ > > > > arch/riscv/include/asm/perf_event.h | 100 ++-- > > > > arch/riscv/kernel/Makefile | 2 +- > > > > arch/riscv/kernel/perf_event.c | 471 +++++++++++------- > > > > 7 files changed, 471 insertions(+), 245 deletions(-) > > > > create mode 100644 Documentation/devicetree/bindings/riscv/pmu.yaml > > > > > > > > -- > > > > 2.27.0 > > > > _______________________________________________ linux-riscv mailing list linux-riscv@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-riscv ^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: [RFC PATCH 0/6] Support raw event and DT for perf on RISC-V 2020-06-29 12:53 ` Zong Li @ 2020-06-29 13:23 ` Anup Patel 2020-06-30 6:37 ` Zong Li 0 siblings, 1 reply; 38+ messages in thread From: Anup Patel @ 2020-06-29 13:23 UTC (permalink / raw) To: Zong Li Cc: linux-riscv, Palmer Dabbelt, linux-kernel@vger.kernel.org List, Alan Kao, Paul Walmsley On Mon, Jun 29, 2020 at 6:23 PM Zong Li <zong.li@sifive.com> wrote: > > On Mon, Jun 29, 2020 at 4:28 PM Anup Patel <anup@brainfault.org> wrote: > > > > On Mon, Jun 29, 2020 at 11:22 AM Zong Li <zong.li@sifive.com> wrote: > > > > > > On Mon, Jun 29, 2020 at 12:53 PM Anup Patel <anup@brainfault.org> wrote: > > > > > > > > On Mon, Jun 29, 2020 at 8:49 AM Zong Li <zong.li@sifive.com> wrote: > > > > > > > > > > This patch set adds raw event support on RISC-V. In addition, we > > > > > introduce the DT mechanism to make our perf more generic and common. > > > > > > > > > > Currently, we set the hardware events by writing the mhpmeventN CSRs, it > > > > > would raise an illegal instruction exception and trap into m-mode to > > > > > emulate event selector CSRs access. It doesn't make sense because we > > > > > shouldn't write the m-mode CSRs in s-mode. Ideally, we should set event > > > > > selector through standard SBI call or the shadow CSRs of s-mode. We have > > > > > prepared a proposal of a new SBI extension, called "PMU SBI extension", > > > > > but we also discussing the feasibility of accessing these PMU CSRs on > > > > > s-mode at the same time, such as delegation mechanism, so I was > > > > > wondering if we could use SBI calls first and make the PMU SBI extension > > > > > as legacy when s-mode access mechanism is accepted by Foundation? or > > > > > keep the current situation to see what would happen in the future. > > > > > > > > > > This patch set also introduces the DT mechanism, we don't want to add too > > > > > much platform-dependency code in perf like other architectures, so we > > > > > put the mapping of generic hardware events to DT, then we can easy to > > > > > transfer generic hardware events to vendor's own hardware events without > > > > > any platfrom-dependency stuff in our perf. > > > > > > > > Please re-write this series to have RISC-V PMU driver as a regular > > > > platform driver as drivers/perf/riscv_pmu.c. > > > > > > > > The PMU related sources will have to be removed from arch/riscv. > > > > > > > > Based on implementation of final drivers/perf/riscv_pmu.c we will > > > > come-up with drivers/perf/riscv_sbi_pmu.c driver for SBI perf counters. > > > > > > > > > > There are some different ways to implement perf, and current > > > implementation seems to be consensus when perf was introduced at the > > > beginning [0][1]. I don't persist to which one, I could change the > > > implementation as you mentioned if it is a new consensus one. > > > > > > [0] https://github.com/riscv/riscv-linux/pull/124#issuecomment-367563910 > > > > I would not recommend taking the original RISC-V linux fork as reference. > > > > Rather we should study how things are done on other architectures. > > > > I really appreciate the attempt to make RISC-V PMU driver depend on DT > > but if we are going this route then we should maximize the use of Linux > > platform driver framework. In fact, whenever possible we should integrate > > RISC-V features as platform drivers under the drivers/ directory. > > > > OK, I would change the implementation to platform driver if there is no > other voice. > > > I thought about SBI PMU counters as well. In future, we can easily > > expose SBI PMU counters as RAW events in the same RISC-V PMU > > driver. The sbi_probe_extension() can be used in RISC-V PMU driver > > to check for SBI PMU counters so no special provisions needed in DT > > for SBI PMU counters. > > > > I thought about probing raw events by SBI extension too, I'm interested if you > have more detail about this. > > It seems to me that it is a little bit hard to return all events > through one SBI call, > so I thought we could map the generic hardware events and maintain their own > raw events by each platform in OpenSBI. But eventually, I thought the > DT mechanism > is more clear and easy than that. Let me know if you have any ideas about > probe function. Thanks. We can design SBI calls such that no SBI call is required to read the perf counter. The sbi_probe_extension() will only be used to check whether underlying SBI implementation supports SBI PMU extension. As-per my initial thoughts, we can potentially have the following SBI calls: 1. SBI_PMU_NUM_COUNTERS This call will return the number of SBI PMU counters 2. SBI_PMU_COUNTER_DESCRIBE This call takes two parameters: 1) physical address 2) counter index It will write the description of SBI PMU counter at specified physical address. The details of the SBI PMU counter will include name, type, etc 3. SBI_PMU_COUNTER_START This call takes two parameters: 1) physical address 2) counter index It will inform SBI implementation to start counting specified counter on the calling HART. The counter value will be written to the specified physical address whenever it changes. 4. SBI_PMU_COUNTER_STOP This call takes one parameter: 1) counter index It will inform SBI implementation to stop counting specified counters on the calling HART. The above calls are generic enough to support any number of counters and we don't need any SBI call to read the counter. We can also assume all counters to be of fixed 64bit width. In fact, even Hypervisors can support it's own SBI PMU counters with SBI PMU extension. We still need to think more about the above calls because above SBI calls are just initial ideas. Maybe you can refine the above ideas and send a proposal to the UnixPlatformSpec mailing list ?? Regards, Anup > > > Also, the RISC-V PMU driver can be implemented such that it will > > work for RV32, RV64, NoMMU RV32, and NoMMU RV64. > > > > Regards, > > Anup > > > > > [1] https://groups.google.com/a/groups.riscv.org/g/sw-dev/c/f19TmCNP6yA > > > > > > > Regards, > > > > Anup > > > > > > > > > > > > > > Zong Li (6): > > > > > dt-bindings: riscv: Add YAML documentation for PMU > > > > > riscv: dts: sifive: Add DT support for PMU > > > > > riscv: add definition of hpmcounter CSRs > > > > > riscv: perf: Add raw event support > > > > > riscv: perf: introduce DT mechanism > > > > > riscv: remove PMU menu of Kconfig > > > > > > > > > > .../devicetree/bindings/riscv/pmu.yaml | 59 +++ > > > > > arch/riscv/Kconfig | 13 - > > > > > arch/riscv/boot/dts/sifive/fu540-c000.dtsi | 13 + > > > > > arch/riscv/include/asm/csr.h | 58 +++ > > > > > arch/riscv/include/asm/perf_event.h | 100 ++-- > > > > > arch/riscv/kernel/Makefile | 2 +- > > > > > arch/riscv/kernel/perf_event.c | 471 +++++++++++------- > > > > > 7 files changed, 471 insertions(+), 245 deletions(-) > > > > > create mode 100644 Documentation/devicetree/bindings/riscv/pmu.yaml > > > > > > > > > > -- > > > > > 2.27.0 > > > > > _______________________________________________ linux-riscv mailing list linux-riscv@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-riscv ^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: [RFC PATCH 0/6] Support raw event and DT for perf on RISC-V 2020-06-29 13:23 ` Anup Patel @ 2020-06-30 6:37 ` Zong Li 2020-06-30 7:39 ` Anup Patel 0 siblings, 1 reply; 38+ messages in thread From: Zong Li @ 2020-06-30 6:37 UTC (permalink / raw) To: Anup Patel Cc: linux-riscv, Palmer Dabbelt, linux-kernel@vger.kernel.org List, Alan Kao, Paul Walmsley On Mon, Jun 29, 2020 at 9:23 PM Anup Patel <anup@brainfault.org> wrote: > > On Mon, Jun 29, 2020 at 6:23 PM Zong Li <zong.li@sifive.com> wrote: > > > > On Mon, Jun 29, 2020 at 4:28 PM Anup Patel <anup@brainfault.org> wrote: > > > > > > On Mon, Jun 29, 2020 at 11:22 AM Zong Li <zong.li@sifive.com> wrote: > > > > > > > > On Mon, Jun 29, 2020 at 12:53 PM Anup Patel <anup@brainfault.org> wrote: > > > > > > > > > > On Mon, Jun 29, 2020 at 8:49 AM Zong Li <zong.li@sifive.com> wrote: > > > > > > > > > > > > This patch set adds raw event support on RISC-V. In addition, we > > > > > > introduce the DT mechanism to make our perf more generic and common. > > > > > > > > > > > > Currently, we set the hardware events by writing the mhpmeventN CSRs, it > > > > > > would raise an illegal instruction exception and trap into m-mode to > > > > > > emulate event selector CSRs access. It doesn't make sense because we > > > > > > shouldn't write the m-mode CSRs in s-mode. Ideally, we should set event > > > > > > selector through standard SBI call or the shadow CSRs of s-mode. We have > > > > > > prepared a proposal of a new SBI extension, called "PMU SBI extension", > > > > > > but we also discussing the feasibility of accessing these PMU CSRs on > > > > > > s-mode at the same time, such as delegation mechanism, so I was > > > > > > wondering if we could use SBI calls first and make the PMU SBI extension > > > > > > as legacy when s-mode access mechanism is accepted by Foundation? or > > > > > > keep the current situation to see what would happen in the future. > > > > > > > > > > > > This patch set also introduces the DT mechanism, we don't want to add too > > > > > > much platform-dependency code in perf like other architectures, so we > > > > > > put the mapping of generic hardware events to DT, then we can easy to > > > > > > transfer generic hardware events to vendor's own hardware events without > > > > > > any platfrom-dependency stuff in our perf. > > > > > > > > > > Please re-write this series to have RISC-V PMU driver as a regular > > > > > platform driver as drivers/perf/riscv_pmu.c. > > > > > > > > > > The PMU related sources will have to be removed from arch/riscv. > > > > > > > > > > Based on implementation of final drivers/perf/riscv_pmu.c we will > > > > > come-up with drivers/perf/riscv_sbi_pmu.c driver for SBI perf counters. > > > > > > > > > > > > > There are some different ways to implement perf, and current > > > > implementation seems to be consensus when perf was introduced at the > > > > beginning [0][1]. I don't persist to which one, I could change the > > > > implementation as you mentioned if it is a new consensus one. > > > > > > > > [0] https://github.com/riscv/riscv-linux/pull/124#issuecomment-367563910 > > > > > > I would not recommend taking the original RISC-V linux fork as reference. > > > > > > Rather we should study how things are done on other architectures. > > > > > > I really appreciate the attempt to make RISC-V PMU driver depend on DT > > > but if we are going this route then we should maximize the use of Linux > > > platform driver framework. In fact, whenever possible we should integrate > > > RISC-V features as platform drivers under the drivers/ directory. > > > > > > > OK, I would change the implementation to platform driver if there is no > > other voice. > > > > > I thought about SBI PMU counters as well. In future, we can easily > > > expose SBI PMU counters as RAW events in the same RISC-V PMU > > > driver. The sbi_probe_extension() can be used in RISC-V PMU driver > > > to check for SBI PMU counters so no special provisions needed in DT > > > for SBI PMU counters. > > > > > > > I thought about probing raw events by SBI extension too, I'm interested if you > > have more detail about this. > > > > It seems to me that it is a little bit hard to return all events > > through one SBI call, > > so I thought we could map the generic hardware events and maintain their own > > raw events by each platform in OpenSBI. But eventually, I thought the > > DT mechanism > > is more clear and easy than that. Let me know if you have any ideas about > > probe function. Thanks. > > We can design SBI calls such that no SBI call is required to read > the perf counter. > > The sbi_probe_extension() will only be used to check whether > underlying SBI implementation supports SBI PMU extension. > > As-per my initial thoughts, we can potentially have the following SBI calls: > > 1. SBI_PMU_NUM_COUNTERS > This call will return the number of SBI PMU counters > 2. SBI_PMU_COUNTER_DESCRIBE > This call takes two parameters: 1) physical address 2) counter index > It will write the description of SBI PMU counter at specified > physical address. > The details of the SBI PMU counter will include name, type, etc The main things are that we need to pass the information of raw events and the information of mapping of generic hardware events. Maybe this information could be passed by this SBI call. > 3. SBI_PMU_COUNTER_START > This call takes two parameters: 1) physical address 2) counter index > It will inform SBI implementation to start counting specified counter on the > calling HART. The counter value will be written to the specified physical > address whenever it changes. I would prefer to read the counter directly on s-mode. Spec already defines the mechanism to allow that. But this way would still work if we couldn't read counters on s-mode. > 4. SBI_PMU_COUNTER_STOP > This call takes one parameter: 1) counter index > It will inform SBI implementation to stop counting specified counters on > the calling HART. > > The above calls are generic enough to support any number of counters > and we don't need any SBI call to read the counter. We can also assume > all counters to be of fixed 64bit width. In fact, even Hypervisors can support > it's own SBI PMU counters with SBI PMU extension. > > We still need to think more about the above calls because above SBI > calls are just initial ideas. > We also need a SBI call to set the event selector to specify which event is monitored. > Maybe you can refine the above ideas and send a proposal to the > UnixPlatformSpec mailing list ?? > Ok, let us talk about the details in that. > Regards, > Anup > > > > > > Also, the RISC-V PMU driver can be implemented such that it will > > > work for RV32, RV64, NoMMU RV32, and NoMMU RV64. > > > > > > Regards, > > > Anup > > > > > > > [1] https://groups.google.com/a/groups.riscv.org/g/sw-dev/c/f19TmCNP6yA > > > > > > > > > Regards, > > > > > Anup > > > > > > > > > > > > > > > > > Zong Li (6): > > > > > > dt-bindings: riscv: Add YAML documentation for PMU > > > > > > riscv: dts: sifive: Add DT support for PMU > > > > > > riscv: add definition of hpmcounter CSRs > > > > > > riscv: perf: Add raw event support > > > > > > riscv: perf: introduce DT mechanism > > > > > > riscv: remove PMU menu of Kconfig > > > > > > > > > > > > .../devicetree/bindings/riscv/pmu.yaml | 59 +++ > > > > > > arch/riscv/Kconfig | 13 - > > > > > > arch/riscv/boot/dts/sifive/fu540-c000.dtsi | 13 + > > > > > > arch/riscv/include/asm/csr.h | 58 +++ > > > > > > arch/riscv/include/asm/perf_event.h | 100 ++-- > > > > > > arch/riscv/kernel/Makefile | 2 +- > > > > > > arch/riscv/kernel/perf_event.c | 471 +++++++++++------- > > > > > > 7 files changed, 471 insertions(+), 245 deletions(-) > > > > > > create mode 100644 Documentation/devicetree/bindings/riscv/pmu.yaml > > > > > > > > > > > > -- > > > > > > 2.27.0 > > > > > > _______________________________________________ linux-riscv mailing list linux-riscv@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-riscv ^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: [RFC PATCH 0/6] Support raw event and DT for perf on RISC-V 2020-06-30 6:37 ` Zong Li @ 2020-06-30 7:39 ` Anup Patel 2020-06-30 8:04 ` Zong Li 0 siblings, 1 reply; 38+ messages in thread From: Anup Patel @ 2020-06-30 7:39 UTC (permalink / raw) To: Zong Li Cc: linux-riscv, Palmer Dabbelt, linux-kernel@vger.kernel.org List, Alan Kao, Paul Walmsley On Tue, Jun 30, 2020 at 12:07 PM Zong Li <zong.li@sifive.com> wrote: > > On Mon, Jun 29, 2020 at 9:23 PM Anup Patel <anup@brainfault.org> wrote: > > > > On Mon, Jun 29, 2020 at 6:23 PM Zong Li <zong.li@sifive.com> wrote: > > > > > > On Mon, Jun 29, 2020 at 4:28 PM Anup Patel <anup@brainfault.org> wrote: > > > > > > > > On Mon, Jun 29, 2020 at 11:22 AM Zong Li <zong.li@sifive.com> wrote: > > > > > > > > > > On Mon, Jun 29, 2020 at 12:53 PM Anup Patel <anup@brainfault.org> wrote: > > > > > > > > > > > > On Mon, Jun 29, 2020 at 8:49 AM Zong Li <zong.li@sifive.com> wrote: > > > > > > > > > > > > > > This patch set adds raw event support on RISC-V. In addition, we > > > > > > > introduce the DT mechanism to make our perf more generic and common. > > > > > > > > > > > > > > Currently, we set the hardware events by writing the mhpmeventN CSRs, it > > > > > > > would raise an illegal instruction exception and trap into m-mode to > > > > > > > emulate event selector CSRs access. It doesn't make sense because we > > > > > > > shouldn't write the m-mode CSRs in s-mode. Ideally, we should set event > > > > > > > selector through standard SBI call or the shadow CSRs of s-mode. We have > > > > > > > prepared a proposal of a new SBI extension, called "PMU SBI extension", > > > > > > > but we also discussing the feasibility of accessing these PMU CSRs on > > > > > > > s-mode at the same time, such as delegation mechanism, so I was > > > > > > > wondering if we could use SBI calls first and make the PMU SBI extension > > > > > > > as legacy when s-mode access mechanism is accepted by Foundation? or > > > > > > > keep the current situation to see what would happen in the future. > > > > > > > > > > > > > > This patch set also introduces the DT mechanism, we don't want to add too > > > > > > > much platform-dependency code in perf like other architectures, so we > > > > > > > put the mapping of generic hardware events to DT, then we can easy to > > > > > > > transfer generic hardware events to vendor's own hardware events without > > > > > > > any platfrom-dependency stuff in our perf. > > > > > > > > > > > > Please re-write this series to have RISC-V PMU driver as a regular > > > > > > platform driver as drivers/perf/riscv_pmu.c. > > > > > > > > > > > > The PMU related sources will have to be removed from arch/riscv. > > > > > > > > > > > > Based on implementation of final drivers/perf/riscv_pmu.c we will > > > > > > come-up with drivers/perf/riscv_sbi_pmu.c driver for SBI perf counters. > > > > > > > > > > > > > > > > There are some different ways to implement perf, and current > > > > > implementation seems to be consensus when perf was introduced at the > > > > > beginning [0][1]. I don't persist to which one, I could change the > > > > > implementation as you mentioned if it is a new consensus one. > > > > > > > > > > [0] https://github.com/riscv/riscv-linux/pull/124#issuecomment-367563910 > > > > > > > > I would not recommend taking the original RISC-V linux fork as reference. > > > > > > > > Rather we should study how things are done on other architectures. > > > > > > > > I really appreciate the attempt to make RISC-V PMU driver depend on DT > > > > but if we are going this route then we should maximize the use of Linux > > > > platform driver framework. In fact, whenever possible we should integrate > > > > RISC-V features as platform drivers under the drivers/ directory. > > > > > > > > > > OK, I would change the implementation to platform driver if there is no > > > other voice. > > > > > > > I thought about SBI PMU counters as well. In future, we can easily > > > > expose SBI PMU counters as RAW events in the same RISC-V PMU > > > > driver. The sbi_probe_extension() can be used in RISC-V PMU driver > > > > to check for SBI PMU counters so no special provisions needed in DT > > > > for SBI PMU counters. > > > > > > > > > > I thought about probing raw events by SBI extension too, I'm interested if you > > > have more detail about this. > > > > > > It seems to me that it is a little bit hard to return all events > > > through one SBI call, > > > so I thought we could map the generic hardware events and maintain their own > > > raw events by each platform in OpenSBI. But eventually, I thought the > > > DT mechanism > > > is more clear and easy than that. Let me know if you have any ideas about > > > probe function. Thanks. > > > > We can design SBI calls such that no SBI call is required to read > > the perf counter. > > > > The sbi_probe_extension() will only be used to check whether > > underlying SBI implementation supports SBI PMU extension. > > > > As-per my initial thoughts, we can potentially have the following SBI calls: > > > > 1. SBI_PMU_NUM_COUNTERS > > This call will return the number of SBI PMU counters > > 2. SBI_PMU_COUNTER_DESCRIBE > > This call takes two parameters: 1) physical address 2) counter index > > It will write the description of SBI PMU counter at specified > > physical address. > > The details of the SBI PMU counter will include name, type, etc > > The main things are that we need to pass the information of raw events > and the information of mapping of generic hardware events. Maybe > this information could be passed by this SBI call. > > > 3. SBI_PMU_COUNTER_START > > This call takes two parameters: 1) physical address 2) counter index > > It will inform SBI implementation to start counting specified counter on the > > calling HART. The counter value will be written to the specified physical > > address whenever it changes. > > I would prefer to read the counter directly on s-mode. Spec already defines the > mechanism to allow that. But this way would still work if we couldn't > read counters > on s-mode. The SBI PMU counters have nothing to do with RISC-V PMU counters because these are counters provided by SBI implementation. All-in-all, we have three types of counters: 1. PMU counters defined by RISC-V privilege spec. These are TIME, INSRET, and CYCLE CSRs. 2. Implementation specific counters accessed via HPMCOUNTER CSRs. 3. SBI PMU counters for traps taken and processed by M-mode runtime firmware. Examples: number of misaligned load/store, number of illegal instructions, number of SBI RFENCE calls, number of SBI IPI calls, etc. The DT based RISC-V PMU platform driver being discussed in this email thread only addresses points 1) and 2) above. For point 3) above, we need to first define SBI PMU extension. Once SBI PMU extension is defined, we can have separate SBI PMU driver in Linux or extend RISC-V PMU driver to register additonal counters based on SBI PMU extension. I never suggested to access RISC-V HPMCOUNTER CSRs via SBI calls so DT based RISC-V PMU platform driver (for 1) and 2) above) is good to have. The SBI PMU extension is a separate topic. > > > 4. SBI_PMU_COUNTER_STOP > > This call takes one parameter: 1) counter index > > It will inform SBI implementation to stop counting specified counters on > > the calling HART. > > > > The above calls are generic enough to support any number of counters > > and we don't need any SBI call to read the counter. We can also assume > > all counters to be of fixed 64bit width. In fact, even Hypervisors can support > > it's own SBI PMU counters with SBI PMU extension. > > > > We still need to think more about the above calls because above SBI > > calls are just initial ideas. > > > > We also need a SBI call to set the event selector to specify which event > is monitored. SBI_PMU_COUNTER_START will do that. > > > Maybe you can refine the above ideas and send a proposal to the > > UnixPlatformSpec mailing list ?? > > > > Ok, let us talk about the details in that. Regards, Anup > > > > Regards, > > Anup > > > > > > > > > Also, the RISC-V PMU driver can be implemented such that it will > > > > work for RV32, RV64, NoMMU RV32, and NoMMU RV64. > > > > > > > > Regards, > > > > Anup > > > > > > > > > [1] https://groups.google.com/a/groups.riscv.org/g/sw-dev/c/f19TmCNP6yA > > > > > > > > > > > Regards, > > > > > > Anup > > > > > > > > > > > > > > > > > > > > Zong Li (6): > > > > > > > dt-bindings: riscv: Add YAML documentation for PMU > > > > > > > riscv: dts: sifive: Add DT support for PMU > > > > > > > riscv: add definition of hpmcounter CSRs > > > > > > > riscv: perf: Add raw event support > > > > > > > riscv: perf: introduce DT mechanism > > > > > > > riscv: remove PMU menu of Kconfig > > > > > > > > > > > > > > .../devicetree/bindings/riscv/pmu.yaml | 59 +++ > > > > > > > arch/riscv/Kconfig | 13 - > > > > > > > arch/riscv/boot/dts/sifive/fu540-c000.dtsi | 13 + > > > > > > > arch/riscv/include/asm/csr.h | 58 +++ > > > > > > > arch/riscv/include/asm/perf_event.h | 100 ++-- > > > > > > > arch/riscv/kernel/Makefile | 2 +- > > > > > > > arch/riscv/kernel/perf_event.c | 471 +++++++++++------- > > > > > > > 7 files changed, 471 insertions(+), 245 deletions(-) > > > > > > > create mode 100644 Documentation/devicetree/bindings/riscv/pmu.yaml > > > > > > > > > > > > > > -- > > > > > > > 2.27.0 > > > > > > > _______________________________________________ linux-riscv mailing list linux-riscv@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-riscv ^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: [RFC PATCH 0/6] Support raw event and DT for perf on RISC-V 2020-06-30 7:39 ` Anup Patel @ 2020-06-30 8:04 ` Zong Li 2020-06-30 10:18 ` Anup Patel 0 siblings, 1 reply; 38+ messages in thread From: Zong Li @ 2020-06-30 8:04 UTC (permalink / raw) To: Anup Patel Cc: linux-riscv, Palmer Dabbelt, linux-kernel@vger.kernel.org List, Alan Kao, Paul Walmsley On Tue, Jun 30, 2020 at 3:40 PM Anup Patel <anup@brainfault.org> wrote: > > On Tue, Jun 30, 2020 at 12:07 PM Zong Li <zong.li@sifive.com> wrote: > > > > On Mon, Jun 29, 2020 at 9:23 PM Anup Patel <anup@brainfault.org> wrote: > > > > > > On Mon, Jun 29, 2020 at 6:23 PM Zong Li <zong.li@sifive.com> wrote: > > > > > > > > On Mon, Jun 29, 2020 at 4:28 PM Anup Patel <anup@brainfault.org> wrote: > > > > > > > > > > On Mon, Jun 29, 2020 at 11:22 AM Zong Li <zong.li@sifive.com> wrote: > > > > > > > > > > > > On Mon, Jun 29, 2020 at 12:53 PM Anup Patel <anup@brainfault.org> wrote: > > > > > > > > > > > > > > On Mon, Jun 29, 2020 at 8:49 AM Zong Li <zong.li@sifive.com> wrote: > > > > > > > > > > > > > > > > This patch set adds raw event support on RISC-V. In addition, we > > > > > > > > introduce the DT mechanism to make our perf more generic and common. > > > > > > > > > > > > > > > > Currently, we set the hardware events by writing the mhpmeventN CSRs, it > > > > > > > > would raise an illegal instruction exception and trap into m-mode to > > > > > > > > emulate event selector CSRs access. It doesn't make sense because we > > > > > > > > shouldn't write the m-mode CSRs in s-mode. Ideally, we should set event > > > > > > > > selector through standard SBI call or the shadow CSRs of s-mode. We have > > > > > > > > prepared a proposal of a new SBI extension, called "PMU SBI extension", > > > > > > > > but we also discussing the feasibility of accessing these PMU CSRs on > > > > > > > > s-mode at the same time, such as delegation mechanism, so I was > > > > > > > > wondering if we could use SBI calls first and make the PMU SBI extension > > > > > > > > as legacy when s-mode access mechanism is accepted by Foundation? or > > > > > > > > keep the current situation to see what would happen in the future. > > > > > > > > > > > > > > > > This patch set also introduces the DT mechanism, we don't want to add too > > > > > > > > much platform-dependency code in perf like other architectures, so we > > > > > > > > put the mapping of generic hardware events to DT, then we can easy to > > > > > > > > transfer generic hardware events to vendor's own hardware events without > > > > > > > > any platfrom-dependency stuff in our perf. > > > > > > > > > > > > > > Please re-write this series to have RISC-V PMU driver as a regular > > > > > > > platform driver as drivers/perf/riscv_pmu.c. > > > > > > > > > > > > > > The PMU related sources will have to be removed from arch/riscv. > > > > > > > > > > > > > > Based on implementation of final drivers/perf/riscv_pmu.c we will > > > > > > > come-up with drivers/perf/riscv_sbi_pmu.c driver for SBI perf counters. > > > > > > > > > > > > > > > > > > > There are some different ways to implement perf, and current > > > > > > implementation seems to be consensus when perf was introduced at the > > > > > > beginning [0][1]. I don't persist to which one, I could change the > > > > > > implementation as you mentioned if it is a new consensus one. > > > > > > > > > > > > [0] https://github.com/riscv/riscv-linux/pull/124#issuecomment-367563910 > > > > > > > > > > I would not recommend taking the original RISC-V linux fork as reference. > > > > > > > > > > Rather we should study how things are done on other architectures. > > > > > > > > > > I really appreciate the attempt to make RISC-V PMU driver depend on DT > > > > > but if we are going this route then we should maximize the use of Linux > > > > > platform driver framework. In fact, whenever possible we should integrate > > > > > RISC-V features as platform drivers under the drivers/ directory. > > > > > > > > > > > > > OK, I would change the implementation to platform driver if there is no > > > > other voice. > > > > > > > > > I thought about SBI PMU counters as well. In future, we can easily > > > > > expose SBI PMU counters as RAW events in the same RISC-V PMU > > > > > driver. The sbi_probe_extension() can be used in RISC-V PMU driver > > > > > to check for SBI PMU counters so no special provisions needed in DT > > > > > for SBI PMU counters. > > > > > > > > > > > > > I thought about probing raw events by SBI extension too, I'm interested if you > > > > have more detail about this. > > > > > > > > It seems to me that it is a little bit hard to return all events > > > > through one SBI call, > > > > so I thought we could map the generic hardware events and maintain their own > > > > raw events by each platform in OpenSBI. But eventually, I thought the > > > > DT mechanism > > > > is more clear and easy than that. Let me know if you have any ideas about > > > > probe function. Thanks. > > > > > > We can design SBI calls such that no SBI call is required to read > > > the perf counter. > > > > > > The sbi_probe_extension() will only be used to check whether > > > underlying SBI implementation supports SBI PMU extension. > > > > > > As-per my initial thoughts, we can potentially have the following SBI calls: > > > > > > 1. SBI_PMU_NUM_COUNTERS > > > This call will return the number of SBI PMU counters > > > 2. SBI_PMU_COUNTER_DESCRIBE > > > This call takes two parameters: 1) physical address 2) counter index > > > It will write the description of SBI PMU counter at specified > > > physical address. > > > The details of the SBI PMU counter will include name, type, etc > > > > The main things are that we need to pass the information of raw events > > and the information of mapping of generic hardware events. Maybe > > this information could be passed by this SBI call. > > > > > 3. SBI_PMU_COUNTER_START > > > This call takes two parameters: 1) physical address 2) counter index > > > It will inform SBI implementation to start counting specified counter on the > > > calling HART. The counter value will be written to the specified physical > > > address whenever it changes. > > > > I would prefer to read the counter directly on s-mode. Spec already defines the > > mechanism to allow that. But this way would still work if we couldn't > > read counters > > on s-mode. > > The SBI PMU counters have nothing to do with RISC-V PMU counters because > these are counters provided by SBI implementation. > > All-in-all, we have three types of counters: > 1. PMU counters defined by RISC-V privilege spec. These are TIME, > INSRET, and CYCLE CSRs. > 2. Implementation specific counters accessed via HPMCOUNTER CSRs. > 3. SBI PMU counters for traps taken and processed by M-mode runtime > firmware. Examples: number of misaligned load/store, number of illegal > instructions, number of SBI RFENCE calls, number of SBI IPI calls, etc. > > The DT based RISC-V PMU platform driver being discussed in this email > thread only addresses points 1) and 2) above. > OK, sounds good, I misunderstood your ideas, I mixed the 2) and 3) and see them as the same thing. Many thanks for the clear explanation. > For point 3) above, we need to first define SBI PMU extension. Once SBI > PMU extension is defined, we can have separate SBI PMU driver in Linux > or extend RISC-V PMU driver to register additonal counters based on > SBI PMU extension. > > I never suggested to access RISC-V HPMCOUNTER CSRs via SBI calls > so DT based RISC-V PMU platform driver (for 1) and 2) above) is good > to have. The SBI PMU extension is a separate topic. > > > > > > 4. SBI_PMU_COUNTER_STOP > > > This call takes one parameter: 1) counter index > > > It will inform SBI implementation to stop counting specified counters on > > > the calling HART. > > > > > > The above calls are generic enough to support any number of counters > > > and we don't need any SBI call to read the counter. We can also assume > > > all counters to be of fixed 64bit width. In fact, even Hypervisors can support > > > it's own SBI PMU counters with SBI PMU extension. > > > > > > We still need to think more about the above calls because above SBI > > > calls are just initial ideas. > > > > > > > We also need a SBI call to set the event selector to specify which event > > is monitored. > > SBI_PMU_COUNTER_START will do that. I'm not sure whether this SBI call is only for SBI PMU counter and it's own events. For 2), it needs one SBI call to set the events, we just set the event selector by writing m-mode CSRs on s-mode now. If this SBI call could serve 2) and 3) both, we don't need another SBI call. > > > > > > Maybe you can refine the above ideas and send a proposal to the > > > UnixPlatformSpec mailing list ?? > > > > > > > Ok, let us talk about the details in that. > > Regards, > Anup > > > > > > > > Regards, > > > Anup > > > > > > > > > > > > Also, the RISC-V PMU driver can be implemented such that it will > > > > > work for RV32, RV64, NoMMU RV32, and NoMMU RV64. > > > > > > > > > > Regards, > > > > > Anup > > > > > > > > > > > [1] https://groups.google.com/a/groups.riscv.org/g/sw-dev/c/f19TmCNP6yA > > > > > > > > > > > > > Regards, > > > > > > > Anup > > > > > > > > > > > > > > > > > > > > > > > Zong Li (6): > > > > > > > > dt-bindings: riscv: Add YAML documentation for PMU > > > > > > > > riscv: dts: sifive: Add DT support for PMU > > > > > > > > riscv: add definition of hpmcounter CSRs > > > > > > > > riscv: perf: Add raw event support > > > > > > > > riscv: perf: introduce DT mechanism > > > > > > > > riscv: remove PMU menu of Kconfig > > > > > > > > > > > > > > > > .../devicetree/bindings/riscv/pmu.yaml | 59 +++ > > > > > > > > arch/riscv/Kconfig | 13 - > > > > > > > > arch/riscv/boot/dts/sifive/fu540-c000.dtsi | 13 + > > > > > > > > arch/riscv/include/asm/csr.h | 58 +++ > > > > > > > > arch/riscv/include/asm/perf_event.h | 100 ++-- > > > > > > > > arch/riscv/kernel/Makefile | 2 +- > > > > > > > > arch/riscv/kernel/perf_event.c | 471 +++++++++++------- > > > > > > > > 7 files changed, 471 insertions(+), 245 deletions(-) > > > > > > > > create mode 100644 Documentation/devicetree/bindings/riscv/pmu.yaml > > > > > > > > > > > > > > > > -- > > > > > > > > 2.27.0 > > > > > > > > _______________________________________________ linux-riscv mailing list linux-riscv@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-riscv ^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: [RFC PATCH 0/6] Support raw event and DT for perf on RISC-V 2020-06-30 8:04 ` Zong Li @ 2020-06-30 10:18 ` Anup Patel 2020-06-30 11:38 ` Anup Patel 2020-07-01 1:55 ` Zong Li 0 siblings, 2 replies; 38+ messages in thread From: Anup Patel @ 2020-06-30 10:18 UTC (permalink / raw) To: Zong Li Cc: linux-riscv, Palmer Dabbelt, linux-kernel@vger.kernel.org List, Alan Kao, Paul Walmsley On Tue, Jun 30, 2020 at 1:34 PM Zong Li <zong.li@sifive.com> wrote: > > On Tue, Jun 30, 2020 at 3:40 PM Anup Patel <anup@brainfault.org> wrote: > > > > On Tue, Jun 30, 2020 at 12:07 PM Zong Li <zong.li@sifive.com> wrote: > > > > > > On Mon, Jun 29, 2020 at 9:23 PM Anup Patel <anup@brainfault.org> wrote: > > > > > > > > On Mon, Jun 29, 2020 at 6:23 PM Zong Li <zong.li@sifive.com> wrote: > > > > > > > > > > On Mon, Jun 29, 2020 at 4:28 PM Anup Patel <anup@brainfault.org> wrote: > > > > > > > > > > > > On Mon, Jun 29, 2020 at 11:22 AM Zong Li <zong.li@sifive.com> wrote: > > > > > > > > > > > > > > On Mon, Jun 29, 2020 at 12:53 PM Anup Patel <anup@brainfault.org> wrote: > > > > > > > > > > > > > > > > On Mon, Jun 29, 2020 at 8:49 AM Zong Li <zong.li@sifive.com> wrote: > > > > > > > > > > > > > > > > > > This patch set adds raw event support on RISC-V. In addition, we > > > > > > > > > introduce the DT mechanism to make our perf more generic and common. > > > > > > > > > > > > > > > > > > Currently, we set the hardware events by writing the mhpmeventN CSRs, it > > > > > > > > > would raise an illegal instruction exception and trap into m-mode to > > > > > > > > > emulate event selector CSRs access. It doesn't make sense because we > > > > > > > > > shouldn't write the m-mode CSRs in s-mode. Ideally, we should set event > > > > > > > > > selector through standard SBI call or the shadow CSRs of s-mode. We have > > > > > > > > > prepared a proposal of a new SBI extension, called "PMU SBI extension", > > > > > > > > > but we also discussing the feasibility of accessing these PMU CSRs on > > > > > > > > > s-mode at the same time, such as delegation mechanism, so I was > > > > > > > > > wondering if we could use SBI calls first and make the PMU SBI extension > > > > > > > > > as legacy when s-mode access mechanism is accepted by Foundation? or > > > > > > > > > keep the current situation to see what would happen in the future. > > > > > > > > > > > > > > > > > > This patch set also introduces the DT mechanism, we don't want to add too > > > > > > > > > much platform-dependency code in perf like other architectures, so we > > > > > > > > > put the mapping of generic hardware events to DT, then we can easy to > > > > > > > > > transfer generic hardware events to vendor's own hardware events without > > > > > > > > > any platfrom-dependency stuff in our perf. > > > > > > > > > > > > > > > > Please re-write this series to have RISC-V PMU driver as a regular > > > > > > > > platform driver as drivers/perf/riscv_pmu.c. > > > > > > > > > > > > > > > > The PMU related sources will have to be removed from arch/riscv. > > > > > > > > > > > > > > > > Based on implementation of final drivers/perf/riscv_pmu.c we will > > > > > > > > come-up with drivers/perf/riscv_sbi_pmu.c driver for SBI perf counters. > > > > > > > > > > > > > > > > > > > > > > There are some different ways to implement perf, and current > > > > > > > implementation seems to be consensus when perf was introduced at the > > > > > > > beginning [0][1]. I don't persist to which one, I could change the > > > > > > > implementation as you mentioned if it is a new consensus one. > > > > > > > > > > > > > > [0] https://github.com/riscv/riscv-linux/pull/124#issuecomment-367563910 > > > > > > > > > > > > I would not recommend taking the original RISC-V linux fork as reference. > > > > > > > > > > > > Rather we should study how things are done on other architectures. > > > > > > > > > > > > I really appreciate the attempt to make RISC-V PMU driver depend on DT > > > > > > but if we are going this route then we should maximize the use of Linux > > > > > > platform driver framework. In fact, whenever possible we should integrate > > > > > > RISC-V features as platform drivers under the drivers/ directory. > > > > > > > > > > > > > > > > OK, I would change the implementation to platform driver if there is no > > > > > other voice. > > > > > > > > > > > I thought about SBI PMU counters as well. In future, we can easily > > > > > > expose SBI PMU counters as RAW events in the same RISC-V PMU > > > > > > driver. The sbi_probe_extension() can be used in RISC-V PMU driver > > > > > > to check for SBI PMU counters so no special provisions needed in DT > > > > > > for SBI PMU counters. > > > > > > > > > > > > > > > > I thought about probing raw events by SBI extension too, I'm interested if you > > > > > have more detail about this. > > > > > > > > > > It seems to me that it is a little bit hard to return all events > > > > > through one SBI call, > > > > > so I thought we could map the generic hardware events and maintain their own > > > > > raw events by each platform in OpenSBI. But eventually, I thought the > > > > > DT mechanism > > > > > is more clear and easy than that. Let me know if you have any ideas about > > > > > probe function. Thanks. > > > > > > > > We can design SBI calls such that no SBI call is required to read > > > > the perf counter. > > > > > > > > The sbi_probe_extension() will only be used to check whether > > > > underlying SBI implementation supports SBI PMU extension. > > > > > > > > As-per my initial thoughts, we can potentially have the following SBI calls: > > > > > > > > 1. SBI_PMU_NUM_COUNTERS > > > > This call will return the number of SBI PMU counters > > > > 2. SBI_PMU_COUNTER_DESCRIBE > > > > This call takes two parameters: 1) physical address 2) counter index > > > > It will write the description of SBI PMU counter at specified > > > > physical address. > > > > The details of the SBI PMU counter will include name, type, etc > > > > > > The main things are that we need to pass the information of raw events > > > and the information of mapping of generic hardware events. Maybe > > > this information could be passed by this SBI call. > > > > > > > 3. SBI_PMU_COUNTER_START > > > > This call takes two parameters: 1) physical address 2) counter index > > > > It will inform SBI implementation to start counting specified counter on the > > > > calling HART. The counter value will be written to the specified physical > > > > address whenever it changes. > > > > > > I would prefer to read the counter directly on s-mode. Spec already defines the > > > mechanism to allow that. But this way would still work if we couldn't > > > read counters > > > on s-mode. > > > > The SBI PMU counters have nothing to do with RISC-V PMU counters because > > these are counters provided by SBI implementation. > > > > All-in-all, we have three types of counters: > > 1. PMU counters defined by RISC-V privilege spec. These are TIME, > > INSRET, and CYCLE CSRs. > > 2. Implementation specific counters accessed via HPMCOUNTER CSRs. > > 3. SBI PMU counters for traps taken and processed by M-mode runtime > > firmware. Examples: number of misaligned load/store, number of illegal > > instructions, number of SBI RFENCE calls, number of SBI IPI calls, etc. > > > > The DT based RISC-V PMU platform driver being discussed in this email > > thread only addresses points 1) and 2) above. > > > > OK, sounds good, I misunderstood your ideas, I mixed the 2) and 3) > and see them as the same thing. Many thanks for the clear explanation. Cool, we are on the same page till here. > > > For point 3) above, we need to first define SBI PMU extension. Once SBI > > PMU extension is defined, we can have separate SBI PMU driver in Linux > > or extend RISC-V PMU driver to register additonal counters based on > > SBI PMU extension. > > > > I never suggested to access RISC-V HPMCOUNTER CSRs via SBI calls > > so DT based RISC-V PMU platform driver (for 1) and 2) above) is good > > to have. The SBI PMU extension is a separate topic. > > > > > > > > > 4. SBI_PMU_COUNTER_STOP > > > > This call takes one parameter: 1) counter index > > > > It will inform SBI implementation to stop counting specified counters on > > > > the calling HART. > > > > > > > > The above calls are generic enough to support any number of counters > > > > and we don't need any SBI call to read the counter. We can also assume > > > > all counters to be of fixed 64bit width. In fact, even Hypervisors can support > > > > it's own SBI PMU counters with SBI PMU extension. > > > > > > > > We still need to think more about the above calls because above SBI > > > > calls are just initial ideas. > > > > > > > > > > We also need a SBI call to set the event selector to specify which event > > > is monitored. > > > > SBI_PMU_COUNTER_START will do that. > > I'm not sure whether this SBI call is only for SBI PMU counter and > it's own events. > For 2), it needs one SBI call to set the events, we just set the event selector > by writing m-mode CSRs on s-mode now. If this SBI call could serve 2) > and 3) both, > we don't need another SBI call. Can you elaborate more ?? Is the SBI call for 2) needed to enable/disable counters in MCOUNTEREN CSR ? Currently, OpenSBI enables all counters by default but I see the need to enable/disable HPMCOUNTER on-demand from perf event start/stop. I hope we don't need any other implementation specific CSR to be programmed for enabling/disabling counters on SiFive Unleashed ?? Regards, Anup > > > > > > > > > > Maybe you can refine the above ideas and send a proposal to the > > > > UnixPlatformSpec mailing list ?? > > > > > > > > > > Ok, let us talk about the details in that. > > > > Regards, > > Anup > > > > > > > > > > > > Regards, > > > > Anup > > > > > > > > > > > > > > > Also, the RISC-V PMU driver can be implemented such that it will > > > > > > work for RV32, RV64, NoMMU RV32, and NoMMU RV64. > > > > > > > > > > > > Regards, > > > > > > Anup > > > > > > > > > > > > > [1] https://groups.google.com/a/groups.riscv.org/g/sw-dev/c/f19TmCNP6yA > > > > > > > > > > > > > > > Regards, > > > > > > > > Anup > > > > > > > > > > > > > > > > > > > > > > > > > > Zong Li (6): > > > > > > > > > dt-bindings: riscv: Add YAML documentation for PMU > > > > > > > > > riscv: dts: sifive: Add DT support for PMU > > > > > > > > > riscv: add definition of hpmcounter CSRs > > > > > > > > > riscv: perf: Add raw event support > > > > > > > > > riscv: perf: introduce DT mechanism > > > > > > > > > riscv: remove PMU menu of Kconfig > > > > > > > > > > > > > > > > > > .../devicetree/bindings/riscv/pmu.yaml | 59 +++ > > > > > > > > > arch/riscv/Kconfig | 13 - > > > > > > > > > arch/riscv/boot/dts/sifive/fu540-c000.dtsi | 13 + > > > > > > > > > arch/riscv/include/asm/csr.h | 58 +++ > > > > > > > > > arch/riscv/include/asm/perf_event.h | 100 ++-- > > > > > > > > > arch/riscv/kernel/Makefile | 2 +- > > > > > > > > > arch/riscv/kernel/perf_event.c | 471 +++++++++++------- > > > > > > > > > 7 files changed, 471 insertions(+), 245 deletions(-) > > > > > > > > > create mode 100644 Documentation/devicetree/bindings/riscv/pmu.yaml > > > > > > > > > > > > > > > > > > -- > > > > > > > > > 2.27.0 > > > > > > > > > _______________________________________________ linux-riscv mailing list linux-riscv@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-riscv ^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: [RFC PATCH 0/6] Support raw event and DT for perf on RISC-V 2020-06-30 10:18 ` Anup Patel @ 2020-06-30 11:38 ` Anup Patel 2020-06-30 18:57 ` Atish Patra 2020-07-01 2:11 ` Zong Li 2020-07-01 1:55 ` Zong Li 1 sibling, 2 replies; 38+ messages in thread From: Anup Patel @ 2020-06-30 11:38 UTC (permalink / raw) To: Zong Li Cc: linux-riscv, Palmer Dabbelt, linux-kernel@vger.kernel.org List, Alan Kao, Paul Walmsley On Tue, Jun 30, 2020 at 3:48 PM Anup Patel <anup@brainfault.org> wrote: > > On Tue, Jun 30, 2020 at 1:34 PM Zong Li <zong.li@sifive.com> wrote: > > > > On Tue, Jun 30, 2020 at 3:40 PM Anup Patel <anup@brainfault.org> wrote: > > > > > > On Tue, Jun 30, 2020 at 12:07 PM Zong Li <zong.li@sifive.com> wrote: > > > > > > > > On Mon, Jun 29, 2020 at 9:23 PM Anup Patel <anup@brainfault.org> wrote: > > > > > > > > > > On Mon, Jun 29, 2020 at 6:23 PM Zong Li <zong.li@sifive.com> wrote: > > > > > > > > > > > > On Mon, Jun 29, 2020 at 4:28 PM Anup Patel <anup@brainfault.org> wrote: > > > > > > > > > > > > > > On Mon, Jun 29, 2020 at 11:22 AM Zong Li <zong.li@sifive.com> wrote: > > > > > > > > > > > > > > > > On Mon, Jun 29, 2020 at 12:53 PM Anup Patel <anup@brainfault.org> wrote: > > > > > > > > > > > > > > > > > > On Mon, Jun 29, 2020 at 8:49 AM Zong Li <zong.li@sifive.com> wrote: > > > > > > > > > > > > > > > > > > > > This patch set adds raw event support on RISC-V. In addition, we > > > > > > > > > > introduce the DT mechanism to make our perf more generic and common. > > > > > > > > > > > > > > > > > > > > Currently, we set the hardware events by writing the mhpmeventN CSRs, it > > > > > > > > > > would raise an illegal instruction exception and trap into m-mode to > > > > > > > > > > emulate event selector CSRs access. It doesn't make sense because we > > > > > > > > > > shouldn't write the m-mode CSRs in s-mode. Ideally, we should set event > > > > > > > > > > selector through standard SBI call or the shadow CSRs of s-mode. We have > > > > > > > > > > prepared a proposal of a new SBI extension, called "PMU SBI extension", > > > > > > > > > > but we also discussing the feasibility of accessing these PMU CSRs on > > > > > > > > > > s-mode at the same time, such as delegation mechanism, so I was > > > > > > > > > > wondering if we could use SBI calls first and make the PMU SBI extension > > > > > > > > > > as legacy when s-mode access mechanism is accepted by Foundation? or > > > > > > > > > > keep the current situation to see what would happen in the future. > > > > > > > > > > > > > > > > > > > > This patch set also introduces the DT mechanism, we don't want to add too > > > > > > > > > > much platform-dependency code in perf like other architectures, so we > > > > > > > > > > put the mapping of generic hardware events to DT, then we can easy to > > > > > > > > > > transfer generic hardware events to vendor's own hardware events without > > > > > > > > > > any platfrom-dependency stuff in our perf. > > > > > > > > > > > > > > > > > > Please re-write this series to have RISC-V PMU driver as a regular > > > > > > > > > platform driver as drivers/perf/riscv_pmu.c. > > > > > > > > > > > > > > > > > > The PMU related sources will have to be removed from arch/riscv. > > > > > > > > > > > > > > > > > > Based on implementation of final drivers/perf/riscv_pmu.c we will > > > > > > > > > come-up with drivers/perf/riscv_sbi_pmu.c driver for SBI perf counters. > > > > > > > > > > > > > > > > > > > > > > > > > There are some different ways to implement perf, and current > > > > > > > > implementation seems to be consensus when perf was introduced at the > > > > > > > > beginning [0][1]. I don't persist to which one, I could change the > > > > > > > > implementation as you mentioned if it is a new consensus one. > > > > > > > > > > > > > > > > [0] https://github.com/riscv/riscv-linux/pull/124#issuecomment-367563910 > > > > > > > > > > > > > > I would not recommend taking the original RISC-V linux fork as reference. > > > > > > > > > > > > > > Rather we should study how things are done on other architectures. > > > > > > > > > > > > > > I really appreciate the attempt to make RISC-V PMU driver depend on DT > > > > > > > but if we are going this route then we should maximize the use of Linux > > > > > > > platform driver framework. In fact, whenever possible we should integrate > > > > > > > RISC-V features as platform drivers under the drivers/ directory. > > > > > > > > > > > > > > > > > > > OK, I would change the implementation to platform driver if there is no > > > > > > other voice. > > > > > > > > > > > > > I thought about SBI PMU counters as well. In future, we can easily > > > > > > > expose SBI PMU counters as RAW events in the same RISC-V PMU > > > > > > > driver. The sbi_probe_extension() can be used in RISC-V PMU driver > > > > > > > to check for SBI PMU counters so no special provisions needed in DT > > > > > > > for SBI PMU counters. > > > > > > > > > > > > > > > > > > > I thought about probing raw events by SBI extension too, I'm interested if you > > > > > > have more detail about this. > > > > > > > > > > > > It seems to me that it is a little bit hard to return all events > > > > > > through one SBI call, > > > > > > so I thought we could map the generic hardware events and maintain their own > > > > > > raw events by each platform in OpenSBI. But eventually, I thought the > > > > > > DT mechanism > > > > > > is more clear and easy than that. Let me know if you have any ideas about > > > > > > probe function. Thanks. > > > > > > > > > > We can design SBI calls such that no SBI call is required to read > > > > > the perf counter. > > > > > > > > > > The sbi_probe_extension() will only be used to check whether > > > > > underlying SBI implementation supports SBI PMU extension. > > > > > > > > > > As-per my initial thoughts, we can potentially have the following SBI calls: > > > > > > > > > > 1. SBI_PMU_NUM_COUNTERS > > > > > This call will return the number of SBI PMU counters > > > > > 2. SBI_PMU_COUNTER_DESCRIBE > > > > > This call takes two parameters: 1) physical address 2) counter index > > > > > It will write the description of SBI PMU counter at specified > > > > > physical address. > > > > > The details of the SBI PMU counter will include name, type, etc > > > > > > > > The main things are that we need to pass the information of raw events > > > > and the information of mapping of generic hardware events. Maybe > > > > this information could be passed by this SBI call. > > > > > > > > > 3. SBI_PMU_COUNTER_START > > > > > This call takes two parameters: 1) physical address 2) counter index > > > > > It will inform SBI implementation to start counting specified counter on the > > > > > calling HART. The counter value will be written to the specified physical > > > > > address whenever it changes. > > > > > > > > I would prefer to read the counter directly on s-mode. Spec already defines the > > > > mechanism to allow that. But this way would still work if we couldn't > > > > read counters > > > > on s-mode. > > > > > > The SBI PMU counters have nothing to do with RISC-V PMU counters because > > > these are counters provided by SBI implementation. > > > > > > All-in-all, we have three types of counters: > > > 1. PMU counters defined by RISC-V privilege spec. These are TIME, > > > INSRET, and CYCLE CSRs. > > > 2. Implementation specific counters accessed via HPMCOUNTER CSRs. > > > 3. SBI PMU counters for traps taken and processed by M-mode runtime > > > firmware. Examples: number of misaligned load/store, number of illegal > > > instructions, number of SBI RFENCE calls, number of SBI IPI calls, etc. > > > > > > The DT based RISC-V PMU platform driver being discussed in this email > > > thread only addresses points 1) and 2) above. > > > > > > > OK, sounds good, I misunderstood your ideas, I mixed the 2) and 3) > > and see them as the same thing. Many thanks for the clear explanation. > > Cool, we are on the same page till here. > > > > > > For point 3) above, we need to first define SBI PMU extension. Once SBI > > > PMU extension is defined, we can have separate SBI PMU driver in Linux > > > or extend RISC-V PMU driver to register additonal counters based on > > > SBI PMU extension. > > > > > > I never suggested to access RISC-V HPMCOUNTER CSRs via SBI calls > > > so DT based RISC-V PMU platform driver (for 1) and 2) above) is good > > > to have. The SBI PMU extension is a separate topic. > > > > > > > > > > > > 4. SBI_PMU_COUNTER_STOP > > > > > This call takes one parameter: 1) counter index > > > > > It will inform SBI implementation to stop counting specified counters on > > > > > the calling HART. > > > > > > > > > > The above calls are generic enough to support any number of counters > > > > > and we don't need any SBI call to read the counter. We can also assume > > > > > all counters to be of fixed 64bit width. In fact, even Hypervisors can support > > > > > it's own SBI PMU counters with SBI PMU extension. > > > > > > > > > > We still need to think more about the above calls because above SBI > > > > > calls are just initial ideas. > > > > > > > > > > > > > We also need a SBI call to set the event selector to specify which event > > > > is monitored. > > > > > > SBI_PMU_COUNTER_START will do that. > > > > I'm not sure whether this SBI call is only for SBI PMU counter and > > it's own events. > > For 2), it needs one SBI call to set the events, we just set the event selector > > by writing m-mode CSRs on s-mode now. If this SBI call could serve 2) > > and 3) both, > > we don't need another SBI call. > > Can you elaborate more ?? > > Is the SBI call for 2) needed to enable/disable counters in MCOUNTEREN CSR ? > > Currently, OpenSBI enables all counters by default but I see the need > to enable/disable HPMCOUNTER on-demand from perf event start/stop. > > I hope we don't need any other implementation specific CSR to be programmed > for enabling/disabling counters on SiFive Unleashed ?? > Here's the next version of SBI PMU extension, which tries to address both 2) and 3). In other words, it covers all HPMCOUNTER CSRs and software counters of SBI implementation. To define SBI PMU extension, we first define counter_idx which is a unique number assigned to a counter: 1. counter_idx = 0 to 2 are for CYCLE, TIME, and INSTRET 2. counter_idx = 3 to 31 are for HPMCOUNTER CSRs 3. counter_idx = 32 or higher are for software counters provided by SBI implementation The counter_idx == 1 (i.e. TIME CSR) is always enabled when underlying HW implements it. Otherwise it is always disabled. Based on above definition of counter_idx definition, we can potentially have the following SBI calls: 1. SBI_PMU_NUM_HPMCOUNTER This call will return the number of HPMCOUNTER CSRs 2. SBI_PMU_NUM_SOFTWARE This call will return the number of software counters provided by SBI implementation 3. SBI_PMU_COUNTER_DESCRIBE This call takes two parameters: 1) counter_idx 2) physical address It will write the description of SBI PMU counter at specified physical address. The details of the SBI PMU counter will include name, type, width, events etc 4. SBI_PMU_COUNTER_SET_PHYS_ADDR This call takes two parameters: 1) counter_idx 2) physical address It will set the physical address where SBI implementation will write the software counter. This SBI call is only for software counters (i.e. counter_idx >= 32) so it will fail for other counters. 5. SBI_PMU_COUNTER_SELECT_EVENT This call takes two parameters: 1) counter_idx 2) event number It will select a particular HW event to monitor in a HPMCOUNTER CSR. This SBI call is only for HPMCOUNTER CSRs (i.e 3 <= counter_idx <= 31) 6. SBI_PMU_COUNTER_START This call takes one parameter: 1) counter_idx It will inform SBI implementation to start/enable specified counter on the calling HART. This SBI call will fail for counter_idx == 1 and counters which are not present. 7. SBI_PMU_COUNTER_STOP This call takes one parameter: 1) counter_idx It will inform SBI implementation to stop/disable specified counters on the calling HART. This SBI call will fail for counter_idx == 1 and counters which are not present. The above described SBI calls can be conveniently implemented in M-mode runtime firmware (OpenSBI) and various hypervisors (Xvisor, KVM, etc). We can have a single RISC-V PMU driver using above SBI calls which can be used natively in HS-mode and Guest/VM in VS-mode. Of course, we won't need any information to be passed in DT/ACPI for this driver and it can be under arch/riscv/kernel because without DT/ACPI it can't be a platform driver. The availability of SBI PMU extension can be checked using sbi_probe_extension() SBI call. Regards, Anup _______________________________________________ linux-riscv mailing list linux-riscv@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-riscv ^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: [RFC PATCH 0/6] Support raw event and DT for perf on RISC-V 2020-06-30 11:38 ` Anup Patel @ 2020-06-30 18:57 ` Atish Patra 2020-07-01 2:14 ` Zong Li 2020-07-01 2:11 ` Zong Li 1 sibling, 1 reply; 38+ messages in thread From: Atish Patra @ 2020-06-30 18:57 UTC (permalink / raw) To: anup, zong.li; +Cc: linux-riscv, palmer, linux-kernel, alankao, paul.walmsley On Tue, 2020-06-30 at 17:08 +0530, Anup Patel wrote: > On Tue, Jun 30, 2020 at 3:48 PM Anup Patel <anup@brainfault.org> > wrote: > > On Tue, Jun 30, 2020 at 1:34 PM Zong Li <zong.li@sifive.com> wrote: > > > On Tue, Jun 30, 2020 at 3:40 PM Anup Patel <anup@brainfault.org> > > > wrote: > > > > On Tue, Jun 30, 2020 at 12:07 PM Zong Li <zong.li@sifive.com> > > > > wrote: > > > > > On Mon, Jun 29, 2020 at 9:23 PM Anup Patel < > > > > > anup@brainfault.org> wrote: > > > > > > On Mon, Jun 29, 2020 at 6:23 PM Zong Li <zong.li@sifive.com > > > > > > > wrote: > > > > > > > On Mon, Jun 29, 2020 at 4:28 PM Anup Patel < > > > > > > > anup@brainfault.org> wrote: > > > > > > > > On Mon, Jun 29, 2020 at 11:22 AM Zong Li < > > > > > > > > zong.li@sifive.com> wrote: > > > > > > > > > On Mon, Jun 29, 2020 at 12:53 PM Anup Patel < > > > > > > > > > anup@brainfault.org> wrote: > > > > > > > > > > On Mon, Jun 29, 2020 at 8:49 AM Zong Li < > > > > > > > > > > zong.li@sifive.com> wrote: > > > > > > > > > > > This patch set adds raw event support on RISC-V. > > > > > > > > > > > In addition, we > > > > > > > > > > > introduce the DT mechanism to make our perf more > > > > > > > > > > > generic and common. > > > > > > > > > > > > > > > > > > > > > > Currently, we set the hardware events by writing > > > > > > > > > > > the mhpmeventN CSRs, it > > > > > > > > > > > would raise an illegal instruction exception and > > > > > > > > > > > trap into m-mode to > > > > > > > > > > > emulate event selector CSRs access. It doesn't > > > > > > > > > > > make sense because we > > > > > > > > > > > shouldn't write the m-mode CSRs in s-mode. > > > > > > > > > > > Ideally, we should set event > > > > > > > > > > > selector through standard SBI call or the shadow > > > > > > > > > > > CSRs of s-mode. We have > > > > > > > > > > > prepared a proposal of a new SBI extension, > > > > > > > > > > > called "PMU SBI extension", > > > > > > > > > > > but we also discussing the feasibility of > > > > > > > > > > > accessing these PMU CSRs on > > > > > > > > > > > s-mode at the same time, such as delegation > > > > > > > > > > > mechanism, so I was > > > > > > > > > > > wondering if we could use SBI calls first and > > > > > > > > > > > make the PMU SBI extension > > > > > > > > > > > as legacy when s-mode access mechanism is > > > > > > > > > > > accepted by Foundation? or > > > > > > > > > > > keep the current situation to see what would > > > > > > > > > > > happen in the future. > > > > > > > > > > > > > > > > > > > > > > This patch set also introduces the DT mechanism, > > > > > > > > > > > we don't want to add too > > > > > > > > > > > much platform-dependency code in perf like other > > > > > > > > > > > architectures, so we > > > > > > > > > > > put the mapping of generic hardware events to DT, > > > > > > > > > > > then we can easy to > > > > > > > > > > > transfer generic hardware events to vendor's own > > > > > > > > > > > hardware events without > > > > > > > > > > > any platfrom-dependency stuff in our perf. > > > > > > > > > > > > > > > > > > > > Please re-write this series to have RISC-V PMU > > > > > > > > > > driver as a regular > > > > > > > > > > platform driver as drivers/perf/riscv_pmu.c. > > > > > > > > > > > > > > > > > > > > The PMU related sources will have to be removed > > > > > > > > > > from arch/riscv. > > > > > > > > > > > > > > > > > > > > Based on implementation of final > > > > > > > > > > drivers/perf/riscv_pmu.c we will > > > > > > > > > > come-up with drivers/perf/riscv_sbi_pmu.c driver > > > > > > > > > > for SBI perf counters. > > > > > > > > > > > > > > > > > > > > > > > > > > > > There are some different ways to implement perf, and > > > > > > > > > current > > > > > > > > > implementation seems to be consensus when perf was > > > > > > > > > introduced at the > > > > > > > > > beginning [0][1]. I don't persist to which one, I > > > > > > > > > could change the > > > > > > > > > implementation as you mentioned if it is a new > > > > > > > > > consensus one. > > > > > > > > > > > > > > > > > > [0] > > > > > > > > > https://github.com/riscv/riscv-linux/pull/124#issuecomment-367563910 > > > > > > > > > > > > > > > > I would not recommend taking the original RISC-V linux > > > > > > > > fork as reference. > > > > > > > > > > > > > > > > Rather we should study how things are done on other > > > > > > > > architectures. > > > > > > > > > > > > > > > > I really appreciate the attempt to make RISC-V PMU > > > > > > > > driver depend on DT > > > > > > > > but if we are going this route then we should maximize > > > > > > > > the use of Linux > > > > > > > > platform driver framework. In fact, whenever possible > > > > > > > > we should integrate > > > > > > > > RISC-V features as platform drivers under the drivers/ > > > > > > > > directory. > > > > > > > > > > > > > > > > > > > > > > OK, I would change the implementation to platform driver > > > > > > > if there is no > > > > > > > other voice. > > > > > > > > > > > > > > > I thought about SBI PMU counters as well. In future, we > > > > > > > > can easily > > > > > > > > expose SBI PMU counters as RAW events in the same RISC- > > > > > > > > V PMU > > > > > > > > driver. The sbi_probe_extension() can be used in RISC-V > > > > > > > > PMU driver > > > > > > > > to check for SBI PMU counters so no special provisions > > > > > > > > needed in DT > > > > > > > > for SBI PMU counters. > > > > > > > > > > > > > > > > > > > > > > I thought about probing raw events by SBI extension too, > > > > > > > I'm interested if you > > > > > > > have more detail about this. > > > > > > > > > > > > > > It seems to me that it is a little bit hard to return all > > > > > > > events > > > > > > > through one SBI call, > > > > > > > so I thought we could map the generic hardware events and > > > > > > > maintain their own > > > > > > > raw events by each platform in OpenSBI. But eventually, I > > > > > > > thought the > > > > > > > DT mechanism > > > > > > > is more clear and easy than that. Let me know if you have > > > > > > > any ideas about > > > > > > > probe function. Thanks. > > > > > > > > > > > > We can design SBI calls such that no SBI call is required > > > > > > to read > > > > > > the perf counter. > > > > > > > > > > > > The sbi_probe_extension() will only be used to check > > > > > > whether > > > > > > underlying SBI implementation supports SBI PMU extension. > > > > > > > > > > > > As-per my initial thoughts, we can potentially have the > > > > > > following SBI calls: > > > > > > > > > > > > 1. SBI_PMU_NUM_COUNTERS > > > > > > This call will return the number of SBI PMU counters > > > > > > 2. SBI_PMU_COUNTER_DESCRIBE > > > > > > This call takes two parameters: 1) physical address 2) > > > > > > counter index > > > > > > It will write the description of SBI PMU counter at > > > > > > specified > > > > > > physical address. > > > > > > The details of the SBI PMU counter will include name, > > > > > > type, etc > > > > > > > > > > The main things are that we need to pass the information of > > > > > raw events > > > > > and the information of mapping of generic hardware events. > > > > > Maybe > > > > > this information could be passed by this SBI call. > > > > > > > > > > > 3. SBI_PMU_COUNTER_START > > > > > > This call takes two parameters: 1) physical address 2) > > > > > > counter index > > > > > > It will inform SBI implementation to start counting > > > > > > specified counter on the > > > > > > calling HART. The counter value will be written to the > > > > > > specified physical > > > > > > address whenever it changes. > > > > > > > > > > I would prefer to read the counter directly on s-mode. Spec > > > > > already defines the > > > > > mechanism to allow that. But this way would still work if we > > > > > couldn't > > > > > read counters > > > > > on s-mode. > > > > > > > > The SBI PMU counters have nothing to do with RISC-V PMU > > > > counters because > > > > these are counters provided by SBI implementation. > > > > > > > > All-in-all, we have three types of counters: > > > > 1. PMU counters defined by RISC-V privilege spec. These are > > > > TIME, > > > > INSRET, and CYCLE CSRs. > > > > 2. Implementation specific counters accessed via HPMCOUNTER > > > > CSRs. > > > > 3. SBI PMU counters for traps taken and processed by M-mode > > > > runtime > > > > firmware. Examples: number of misaligned load/store, number of > > > > illegal > > > > instructions, number of SBI RFENCE calls, number of SBI IPI > > > > calls, etc. > > > > > > > > The DT based RISC-V PMU platform driver being discussed in this > > > > email > > > > thread only addresses points 1) and 2) above. > > > > > > > > > > OK, sounds good, I misunderstood your ideas, I mixed the 2) and > > > 3) > > > and see them as the same thing. Many thanks for the clear > > > explanation. > > > > Cool, we are on the same page till here. > > > > > > For point 3) above, we need to first define SBI PMU extension. > > > > Once SBI > > > > PMU extension is defined, we can have separate SBI PMU driver > > > > in Linux > > > > or extend RISC-V PMU driver to register additonal counters > > > > based on > > > > SBI PMU extension. > > > > > > > > I never suggested to access RISC-V HPMCOUNTER CSRs via SBI > > > > calls > > > > so DT based RISC-V PMU platform driver (for 1) and 2) above) is > > > > good > > > > to have. The SBI PMU extension is a separate topic. > > > > > > > > > > 4. SBI_PMU_COUNTER_STOP > > > > > > This call takes one parameter: 1) counter index > > > > > > It will inform SBI implementation to stop counting > > > > > > specified counters on > > > > > > the calling HART. > > > > > > > > > > > > The above calls are generic enough to support any number of > > > > > > counters > > > > > > and we don't need any SBI call to read the counter. We can > > > > > > also assume > > > > > > all counters to be of fixed 64bit width. In fact, even > > > > > > Hypervisors can support > > > > > > it's own SBI PMU counters with SBI PMU extension. > > > > > > > > > > > > We still need to think more about the above calls because > > > > > > above SBI > > > > > > calls are just initial ideas. > > > > > > > > > > > > > > > > We also need a SBI call to set the event selector to specify > > > > > which event > > > > > is monitored. > > > > > > > > SBI_PMU_COUNTER_START will do that. > > > > > > I'm not sure whether this SBI call is only for SBI PMU counter > > > and > > > it's own events. > > > For 2), it needs one SBI call to set the events, we just set the > > > event selector > > > by writing m-mode CSRs on s-mode now. If this SBI call could > > > serve 2) > > > and 3) both, > > > we don't need another SBI call. > > > > Can you elaborate more ?? > > > > Is the SBI call for 2) needed to enable/disable counters in > > MCOUNTEREN CSR ? > > > > Currently, OpenSBI enables all counters by default but I see the > > need > > to enable/disable HPMCOUNTER on-demand from perf event start/stop. > > > > I hope we don't need any other implementation specific CSR to be > > programmed > > for enabling/disabling counters on SiFive Unleashed ?? > > > > Here's the next version of SBI PMU extension, which tries to address > both > 2) and 3). In other words, it covers all HPMCOUNTER CSRs and software > counters of SBI implementation. > > To define SBI PMU extension, we first define counter_idx which is a > unique > number assigned to a counter: > 1. counter_idx = 0 to 2 are for CYCLE, TIME, and INSTRET > 2. counter_idx = 3 to 31 are for HPMCOUNTER > 3. counter_idx = 32 or higher are for software counters counters > provided by SBI implementation > The number of HPMCOUNTER may increase in future. Right ? How about using a higher starting idx for software counters from SBI impolementation ? > The counter_idx == 1 (i.e. TIME CSR) is always enabled when > underlying > HW implements it. Otherwise it is always disabled. > > Based on above definition of counter_idx definition, we can > potentially have > the following SBI calls: > > 1. SBI_PMU_NUM_HPMCOUNTER > This call will return the number of HPMCOUNTER CSRs > 2. SBI_PMU_NUM_SOFTWARE > This call will return the number of software counters provided by > SBI implementation > 3. SBI_PMU_COUNTER_DESCRIBE > This call takes two parameters: 1) counter_idx 2) physical > address > It will write the description of SBI PMU counter at specified > physical address. > The details of the SBI PMU counter will include name, type, > width, > events etc > 4. SBI_PMU_COUNTER_SET_PHYS_ADDR > This call takes two parameters: 1) counter_idx 2) physical > address > It will set the physical address where SBI implementation will > write > the software counter. This SBI call is only for software counters > (i.e. > counter_idx >= 32) so it will fail for other counters. > 5. SBI_PMU_COUNTER_SELECT_EVENT > This call takes two parameters: 1) counter_idx 2) event number > It will select a particular HW event to monitor in a HPMCOUNTER > CSR. > This SBI call is only for HPMCOUNTER CSRs (i.e 3 <= counter_idx > <= 31) > 6. SBI_PMU_COUNTER_START > This call takes one parameter: 1) counter_idx > It will inform SBI implementation to start/enable specified > counter on the > calling HART. This SBI call will fail for counter_idx == 1 and > counters > which are not present. > 7. SBI_PMU_COUNTER_STOP > This call takes one parameter: 1) counter_idx > It will inform SBI implementation to stop/disable specified > counters on > the calling HART. This SBI call will fail for counter_idx == 1 > and counters > which are not present. > > The above described SBI calls can be conveniently implemented in > M-mode runtime firmware (OpenSBI) and various hypervisors (Xvisor, > KVM, etc). > > We can have a single RISC-V PMU driver using above SBI calls which > can be used natively in HS-mode and Guest/VM in VS-mode. Of course, > we won't need any information to be passed in DT/ACPI for this driver > and it can be under arch/riscv/kernel because without DT/ACPI it > can't > be a platform driver. We still need the information in DT for mapping generic hardware events. No ? > The availability of SBI PMU extension can be checked > using sbi_probe_extension() SBI call. > > Regards, > Anup > > _______________________________________________ > linux-riscv mailing list > linux-riscv@lists.infradead.org > http://lists.infradead.org/mailman/listinfo/linux-riscv -- Regards, Atish _______________________________________________ linux-riscv mailing list linux-riscv@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-riscv ^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: [RFC PATCH 0/6] Support raw event and DT for perf on RISC-V 2020-06-30 18:57 ` Atish Patra @ 2020-07-01 2:14 ` Zong Li 2020-07-01 11:43 ` Anup Patel 0 siblings, 1 reply; 38+ messages in thread From: Zong Li @ 2020-07-01 2:14 UTC (permalink / raw) To: Atish Patra Cc: alankao, anup, linux-kernel, palmer, paul.walmsley, linux-riscv On Wed, Jul 1, 2020 at 2:57 AM Atish Patra <Atish.Patra@wdc.com> wrote: > > On Tue, 2020-06-30 at 17:08 +0530, Anup Patel wrote: > > On Tue, Jun 30, 2020 at 3:48 PM Anup Patel <anup@brainfault.org> > > wrote: > > > On Tue, Jun 30, 2020 at 1:34 PM Zong Li <zong.li@sifive.com> wrote: > > > > On Tue, Jun 30, 2020 at 3:40 PM Anup Patel <anup@brainfault.org> > > > > wrote: > > > > > On Tue, Jun 30, 2020 at 12:07 PM Zong Li <zong.li@sifive.com> > > > > > wrote: > > > > > > On Mon, Jun 29, 2020 at 9:23 PM Anup Patel < > > > > > > anup@brainfault.org> wrote: > > > > > > > On Mon, Jun 29, 2020 at 6:23 PM Zong Li <zong.li@sifive.com > > > > > > > > wrote: > > > > > > > > On Mon, Jun 29, 2020 at 4:28 PM Anup Patel < > > > > > > > > anup@brainfault.org> wrote: > > > > > > > > > On Mon, Jun 29, 2020 at 11:22 AM Zong Li < > > > > > > > > > zong.li@sifive.com> wrote: > > > > > > > > > > On Mon, Jun 29, 2020 at 12:53 PM Anup Patel < > > > > > > > > > > anup@brainfault.org> wrote: > > > > > > > > > > > On Mon, Jun 29, 2020 at 8:49 AM Zong Li < > > > > > > > > > > > zong.li@sifive.com> wrote: > > > > > > > > > > > > This patch set adds raw event support on RISC-V. > > > > > > > > > > > > In addition, we > > > > > > > > > > > > introduce the DT mechanism to make our perf more > > > > > > > > > > > > generic and common. > > > > > > > > > > > > > > > > > > > > > > > > Currently, we set the hardware events by writing > > > > > > > > > > > > the mhpmeventN CSRs, it > > > > > > > > > > > > would raise an illegal instruction exception and > > > > > > > > > > > > trap into m-mode to > > > > > > > > > > > > emulate event selector CSRs access. It doesn't > > > > > > > > > > > > make sense because we > > > > > > > > > > > > shouldn't write the m-mode CSRs in s-mode. > > > > > > > > > > > > Ideally, we should set event > > > > > > > > > > > > selector through standard SBI call or the shadow > > > > > > > > > > > > CSRs of s-mode. We have > > > > > > > > > > > > prepared a proposal of a new SBI extension, > > > > > > > > > > > > called "PMU SBI extension", > > > > > > > > > > > > but we also discussing the feasibility of > > > > > > > > > > > > accessing these PMU CSRs on > > > > > > > > > > > > s-mode at the same time, such as delegation > > > > > > > > > > > > mechanism, so I was > > > > > > > > > > > > wondering if we could use SBI calls first and > > > > > > > > > > > > make the PMU SBI extension > > > > > > > > > > > > as legacy when s-mode access mechanism is > > > > > > > > > > > > accepted by Foundation? or > > > > > > > > > > > > keep the current situation to see what would > > > > > > > > > > > > happen in the future. > > > > > > > > > > > > > > > > > > > > > > > > This patch set also introduces the DT mechanism, > > > > > > > > > > > > we don't want to add too > > > > > > > > > > > > much platform-dependency code in perf like other > > > > > > > > > > > > architectures, so we > > > > > > > > > > > > put the mapping of generic hardware events to DT, > > > > > > > > > > > > then we can easy to > > > > > > > > > > > > transfer generic hardware events to vendor's own > > > > > > > > > > > > hardware events without > > > > > > > > > > > > any platfrom-dependency stuff in our perf. > > > > > > > > > > > > > > > > > > > > > > Please re-write this series to have RISC-V PMU > > > > > > > > > > > driver as a regular > > > > > > > > > > > platform driver as drivers/perf/riscv_pmu.c. > > > > > > > > > > > > > > > > > > > > > > The PMU related sources will have to be removed > > > > > > > > > > > from arch/riscv. > > > > > > > > > > > > > > > > > > > > > > Based on implementation of final > > > > > > > > > > > drivers/perf/riscv_pmu.c we will > > > > > > > > > > > come-up with drivers/perf/riscv_sbi_pmu.c driver > > > > > > > > > > > for SBI perf counters. > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > There are some different ways to implement perf, and > > > > > > > > > > current > > > > > > > > > > implementation seems to be consensus when perf was > > > > > > > > > > introduced at the > > > > > > > > > > beginning [0][1]. I don't persist to which one, I > > > > > > > > > > could change the > > > > > > > > > > implementation as you mentioned if it is a new > > > > > > > > > > consensus one. > > > > > > > > > > > > > > > > > > > > [0] > > > > > > > > > > https://github.com/riscv/riscv-linux/pull/124#issuecomment-367563910 > > > > > > > > > > > > > > > > > > I would not recommend taking the original RISC-V linux > > > > > > > > > fork as reference. > > > > > > > > > > > > > > > > > > Rather we should study how things are done on other > > > > > > > > > architectures. > > > > > > > > > > > > > > > > > > I really appreciate the attempt to make RISC-V PMU > > > > > > > > > driver depend on DT > > > > > > > > > but if we are going this route then we should maximize > > > > > > > > > the use of Linux > > > > > > > > > platform driver framework. In fact, whenever possible > > > > > > > > > we should integrate > > > > > > > > > RISC-V features as platform drivers under the drivers/ > > > > > > > > > directory. > > > > > > > > > > > > > > > > > > > > > > > > > OK, I would change the implementation to platform driver > > > > > > > > if there is no > > > > > > > > other voice. > > > > > > > > > > > > > > > > > I thought about SBI PMU counters as well. In future, we > > > > > > > > > can easily > > > > > > > > > expose SBI PMU counters as RAW events in the same RISC- > > > > > > > > > V PMU > > > > > > > > > driver. The sbi_probe_extension() can be used in RISC-V > > > > > > > > > PMU driver > > > > > > > > > to check for SBI PMU counters so no special provisions > > > > > > > > > needed in DT > > > > > > > > > for SBI PMU counters. > > > > > > > > > > > > > > > > > > > > > > > > > I thought about probing raw events by SBI extension too, > > > > > > > > I'm interested if you > > > > > > > > have more detail about this. > > > > > > > > > > > > > > > > It seems to me that it is a little bit hard to return all > > > > > > > > events > > > > > > > > through one SBI call, > > > > > > > > so I thought we could map the generic hardware events and > > > > > > > > maintain their own > > > > > > > > raw events by each platform in OpenSBI. But eventually, I > > > > > > > > thought the > > > > > > > > DT mechanism > > > > > > > > is more clear and easy than that. Let me know if you have > > > > > > > > any ideas about > > > > > > > > probe function. Thanks. > > > > > > > > > > > > > > We can design SBI calls such that no SBI call is required > > > > > > > to read > > > > > > > the perf counter. > > > > > > > > > > > > > > The sbi_probe_extension() will only be used to check > > > > > > > whether > > > > > > > underlying SBI implementation supports SBI PMU extension. > > > > > > > > > > > > > > As-per my initial thoughts, we can potentially have the > > > > > > > following SBI calls: > > > > > > > > > > > > > > 1. SBI_PMU_NUM_COUNTERS > > > > > > > This call will return the number of SBI PMU counters > > > > > > > 2. SBI_PMU_COUNTER_DESCRIBE > > > > > > > This call takes two parameters: 1) physical address 2) > > > > > > > counter index > > > > > > > It will write the description of SBI PMU counter at > > > > > > > specified > > > > > > > physical address. > > > > > > > The details of the SBI PMU counter will include name, > > > > > > > type, etc > > > > > > > > > > > > The main things are that we need to pass the information of > > > > > > raw events > > > > > > and the information of mapping of generic hardware events. > > > > > > Maybe > > > > > > this information could be passed by this SBI call. > > > > > > > > > > > > > 3. SBI_PMU_COUNTER_START > > > > > > > This call takes two parameters: 1) physical address 2) > > > > > > > counter index > > > > > > > It will inform SBI implementation to start counting > > > > > > > specified counter on the > > > > > > > calling HART. The counter value will be written to the > > > > > > > specified physical > > > > > > > address whenever it changes. > > > > > > > > > > > > I would prefer to read the counter directly on s-mode. Spec > > > > > > already defines the > > > > > > mechanism to allow that. But this way would still work if we > > > > > > couldn't > > > > > > read counters > > > > > > on s-mode. > > > > > > > > > > The SBI PMU counters have nothing to do with RISC-V PMU > > > > > counters because > > > > > these are counters provided by SBI implementation. > > > > > > > > > > All-in-all, we have three types of counters: > > > > > 1. PMU counters defined by RISC-V privilege spec. These are > > > > > TIME, > > > > > INSRET, and CYCLE CSRs. > > > > > 2. Implementation specific counters accessed via HPMCOUNTER > > > > > CSRs. > > > > > 3. SBI PMU counters for traps taken and processed by M-mode > > > > > runtime > > > > > firmware. Examples: number of misaligned load/store, number of > > > > > illegal > > > > > instructions, number of SBI RFENCE calls, number of SBI IPI > > > > > calls, etc. > > > > > > > > > > The DT based RISC-V PMU platform driver being discussed in this > > > > > email > > > > > thread only addresses points 1) and 2) above. > > > > > > > > > > > > > OK, sounds good, I misunderstood your ideas, I mixed the 2) and > > > > 3) > > > > and see them as the same thing. Many thanks for the clear > > > > explanation. > > > > > > Cool, we are on the same page till here. > > > > > > > > For point 3) above, we need to first define SBI PMU extension. > > > > > Once SBI > > > > > PMU extension is defined, we can have separate SBI PMU driver > > > > > in Linux > > > > > or extend RISC-V PMU driver to register additonal counters > > > > > based on > > > > > SBI PMU extension. > > > > > > > > > > I never suggested to access RISC-V HPMCOUNTER CSRs via SBI > > > > > calls > > > > > so DT based RISC-V PMU platform driver (for 1) and 2) above) is > > > > > good > > > > > to have. The SBI PMU extension is a separate topic. > > > > > > > > > > > > 4. SBI_PMU_COUNTER_STOP > > > > > > > This call takes one parameter: 1) counter index > > > > > > > It will inform SBI implementation to stop counting > > > > > > > specified counters on > > > > > > > the calling HART. > > > > > > > > > > > > > > The above calls are generic enough to support any number of > > > > > > > counters > > > > > > > and we don't need any SBI call to read the counter. We can > > > > > > > also assume > > > > > > > all counters to be of fixed 64bit width. In fact, even > > > > > > > Hypervisors can support > > > > > > > it's own SBI PMU counters with SBI PMU extension. > > > > > > > > > > > > > > We still need to think more about the above calls because > > > > > > > above SBI > > > > > > > calls are just initial ideas. > > > > > > > > > > > > > > > > > > > We also need a SBI call to set the event selector to specify > > > > > > which event > > > > > > is monitored. > > > > > > > > > > SBI_PMU_COUNTER_START will do that. > > > > > > > > I'm not sure whether this SBI call is only for SBI PMU counter > > > > and > > > > it's own events. > > > > For 2), it needs one SBI call to set the events, we just set the > > > > event selector > > > > by writing m-mode CSRs on s-mode now. If this SBI call could > > > > serve 2) > > > > and 3) both, > > > > we don't need another SBI call. > > > > > > Can you elaborate more ?? > > > > > > Is the SBI call for 2) needed to enable/disable counters in > > > MCOUNTEREN CSR ? > > > > > > Currently, OpenSBI enables all counters by default but I see the > > > need > > > to enable/disable HPMCOUNTER on-demand from perf event start/stop. > > > > > > I hope we don't need any other implementation specific CSR to be > > > programmed > > > for enabling/disabling counters on SiFive Unleashed ?? > > > > > > > Here's the next version of SBI PMU extension, which tries to address > > both > > 2) and 3). In other words, it covers all HPMCOUNTER CSRs and software > > counters of SBI implementation. > > > > To define SBI PMU extension, we first define counter_idx which is a > > unique > > number assigned to a counter: > > 1. counter_idx = 0 to 2 are for CYCLE, TIME, and INSTRET > > 2. counter_idx = 3 to 31 are for HPMCOUNTER > > 3. counter_idx = 32 or higher are for software counters counters > > provided by SBI implementation > > > > The number of HPMCOUNTER may increase in future. Right ? > > How about using a higher starting idx for software counters from SBI > impolementation ? > Sounds good to me. > > The counter_idx == 1 (i.e. TIME CSR) is always enabled when > > underlying > > HW implements it. Otherwise it is always disabled. > > > > Based on above definition of counter_idx definition, we can > > potentially have > > the following SBI calls: > > > > 1. SBI_PMU_NUM_HPMCOUNTER > > This call will return the number of HPMCOUNTER CSRs > > 2. SBI_PMU_NUM_SOFTWARE > > This call will return the number of software counters provided by > > SBI implementation > > 3. SBI_PMU_COUNTER_DESCRIBE > > This call takes two parameters: 1) counter_idx 2) physical > > address > > It will write the description of SBI PMU counter at specified > > physical address. > > The details of the SBI PMU counter will include name, type, > > width, > > events etc > > 4. SBI_PMU_COUNTER_SET_PHYS_ADDR > > This call takes two parameters: 1) counter_idx 2) physical > > address > > It will set the physical address where SBI implementation will > > write > > the software counter. This SBI call is only for software counters > > (i.e. > > counter_idx >= 32) so it will fail for other counters. > > 5. SBI_PMU_COUNTER_SELECT_EVENT > > This call takes two parameters: 1) counter_idx 2) event number > > It will select a particular HW event to monitor in a HPMCOUNTER > > CSR. > > This SBI call is only for HPMCOUNTER CSRs (i.e 3 <= counter_idx > > <= 31) > > 6. SBI_PMU_COUNTER_START > > This call takes one parameter: 1) counter_idx > > It will inform SBI implementation to start/enable specified > > counter on the > > calling HART. This SBI call will fail for counter_idx == 1 and > > counters > > which are not present. > > 7. SBI_PMU_COUNTER_STOP > > This call takes one parameter: 1) counter_idx > > It will inform SBI implementation to stop/disable specified > > counters on > > the calling HART. This SBI call will fail for counter_idx == 1 > > and counters > > which are not present. > > > > The above described SBI calls can be conveniently implemented in > > M-mode runtime firmware (OpenSBI) and various hypervisors (Xvisor, > > KVM, etc). > > > > We can have a single RISC-V PMU driver using above SBI calls which > > can be used natively in HS-mode and Guest/VM in VS-mode. Of course, > > we won't need any information to be passed in DT/ACPI for this driver > > and it can be under arch/riscv/kernel because without DT/ACPI it > > can't > > be a platform driver. > > We still need the information in DT for mapping generic hardware > events. No ? Yes, I think it does. > > > > The availability of SBI PMU extension can be checked > > using sbi_probe_extension() SBI call. > > > > Regards, > > Anup > > > > _______________________________________________ > > linux-riscv mailing list > > linux-riscv@lists.infradead.org > > http://lists.infradead.org/mailman/listinfo/linux-riscv > > -- > Regards, > Atish _______________________________________________ linux-riscv mailing list linux-riscv@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-riscv ^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: [RFC PATCH 0/6] Support raw event and DT for perf on RISC-V 2020-07-01 2:14 ` Zong Li @ 2020-07-01 11:43 ` Anup Patel 0 siblings, 0 replies; 38+ messages in thread From: Anup Patel @ 2020-07-01 11:43 UTC (permalink / raw) To: Zong Li Cc: alankao, linux-kernel, Atish Patra, palmer, paul.walmsley, linux-riscv On Wed, Jul 1, 2020 at 7:44 AM Zong Li <zong.li@sifive.com> wrote: > > On Wed, Jul 1, 2020 at 2:57 AM Atish Patra <Atish.Patra@wdc.com> wrote: > > > > On Tue, 2020-06-30 at 17:08 +0530, Anup Patel wrote: > > > On Tue, Jun 30, 2020 at 3:48 PM Anup Patel <anup@brainfault.org> > > > wrote: > > > > On Tue, Jun 30, 2020 at 1:34 PM Zong Li <zong.li@sifive.com> wrote: > > > > > On Tue, Jun 30, 2020 at 3:40 PM Anup Patel <anup@brainfault.org> > > > > > wrote: > > > > > > On Tue, Jun 30, 2020 at 12:07 PM Zong Li <zong.li@sifive.com> > > > > > > wrote: > > > > > > > On Mon, Jun 29, 2020 at 9:23 PM Anup Patel < > > > > > > > anup@brainfault.org> wrote: > > > > > > > > On Mon, Jun 29, 2020 at 6:23 PM Zong Li <zong.li@sifive.com > > > > > > > > > wrote: > > > > > > > > > On Mon, Jun 29, 2020 at 4:28 PM Anup Patel < > > > > > > > > > anup@brainfault.org> wrote: > > > > > > > > > > On Mon, Jun 29, 2020 at 11:22 AM Zong Li < > > > > > > > > > > zong.li@sifive.com> wrote: > > > > > > > > > > > On Mon, Jun 29, 2020 at 12:53 PM Anup Patel < > > > > > > > > > > > anup@brainfault.org> wrote: > > > > > > > > > > > > On Mon, Jun 29, 2020 at 8:49 AM Zong Li < > > > > > > > > > > > > zong.li@sifive.com> wrote: > > > > > > > > > > > > > This patch set adds raw event support on RISC-V. > > > > > > > > > > > > > In addition, we > > > > > > > > > > > > > introduce the DT mechanism to make our perf more > > > > > > > > > > > > > generic and common. > > > > > > > > > > > > > > > > > > > > > > > > > > Currently, we set the hardware events by writing > > > > > > > > > > > > > the mhpmeventN CSRs, it > > > > > > > > > > > > > would raise an illegal instruction exception and > > > > > > > > > > > > > trap into m-mode to > > > > > > > > > > > > > emulate event selector CSRs access. It doesn't > > > > > > > > > > > > > make sense because we > > > > > > > > > > > > > shouldn't write the m-mode CSRs in s-mode. > > > > > > > > > > > > > Ideally, we should set event > > > > > > > > > > > > > selector through standard SBI call or the shadow > > > > > > > > > > > > > CSRs of s-mode. We have > > > > > > > > > > > > > prepared a proposal of a new SBI extension, > > > > > > > > > > > > > called "PMU SBI extension", > > > > > > > > > > > > > but we also discussing the feasibility of > > > > > > > > > > > > > accessing these PMU CSRs on > > > > > > > > > > > > > s-mode at the same time, such as delegation > > > > > > > > > > > > > mechanism, so I was > > > > > > > > > > > > > wondering if we could use SBI calls first and > > > > > > > > > > > > > make the PMU SBI extension > > > > > > > > > > > > > as legacy when s-mode access mechanism is > > > > > > > > > > > > > accepted by Foundation? or > > > > > > > > > > > > > keep the current situation to see what would > > > > > > > > > > > > > happen in the future. > > > > > > > > > > > > > > > > > > > > > > > > > > This patch set also introduces the DT mechanism, > > > > > > > > > > > > > we don't want to add too > > > > > > > > > > > > > much platform-dependency code in perf like other > > > > > > > > > > > > > architectures, so we > > > > > > > > > > > > > put the mapping of generic hardware events to DT, > > > > > > > > > > > > > then we can easy to > > > > > > > > > > > > > transfer generic hardware events to vendor's own > > > > > > > > > > > > > hardware events without > > > > > > > > > > > > > any platfrom-dependency stuff in our perf. > > > > > > > > > > > > > > > > > > > > > > > > Please re-write this series to have RISC-V PMU > > > > > > > > > > > > driver as a regular > > > > > > > > > > > > platform driver as drivers/perf/riscv_pmu.c. > > > > > > > > > > > > > > > > > > > > > > > > The PMU related sources will have to be removed > > > > > > > > > > > > from arch/riscv. > > > > > > > > > > > > > > > > > > > > > > > > Based on implementation of final > > > > > > > > > > > > drivers/perf/riscv_pmu.c we will > > > > > > > > > > > > come-up with drivers/perf/riscv_sbi_pmu.c driver > > > > > > > > > > > > for SBI perf counters. > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > There are some different ways to implement perf, and > > > > > > > > > > > current > > > > > > > > > > > implementation seems to be consensus when perf was > > > > > > > > > > > introduced at the > > > > > > > > > > > beginning [0][1]. I don't persist to which one, I > > > > > > > > > > > could change the > > > > > > > > > > > implementation as you mentioned if it is a new > > > > > > > > > > > consensus one. > > > > > > > > > > > > > > > > > > > > > > [0] > > > > > > > > > > > https://github.com/riscv/riscv-linux/pull/124#issuecomment-367563910 > > > > > > > > > > > > > > > > > > > > I would not recommend taking the original RISC-V linux > > > > > > > > > > fork as reference. > > > > > > > > > > > > > > > > > > > > Rather we should study how things are done on other > > > > > > > > > > architectures. > > > > > > > > > > > > > > > > > > > > I really appreciate the attempt to make RISC-V PMU > > > > > > > > > > driver depend on DT > > > > > > > > > > but if we are going this route then we should maximize > > > > > > > > > > the use of Linux > > > > > > > > > > platform driver framework. In fact, whenever possible > > > > > > > > > > we should integrate > > > > > > > > > > RISC-V features as platform drivers under the drivers/ > > > > > > > > > > directory. > > > > > > > > > > > > > > > > > > > > > > > > > > > > OK, I would change the implementation to platform driver > > > > > > > > > if there is no > > > > > > > > > other voice. > > > > > > > > > > > > > > > > > > > I thought about SBI PMU counters as well. In future, we > > > > > > > > > > can easily > > > > > > > > > > expose SBI PMU counters as RAW events in the same RISC- > > > > > > > > > > V PMU > > > > > > > > > > driver. The sbi_probe_extension() can be used in RISC-V > > > > > > > > > > PMU driver > > > > > > > > > > to check for SBI PMU counters so no special provisions > > > > > > > > > > needed in DT > > > > > > > > > > for SBI PMU counters. > > > > > > > > > > > > > > > > > > > > > > > > > > > > I thought about probing raw events by SBI extension too, > > > > > > > > > I'm interested if you > > > > > > > > > have more detail about this. > > > > > > > > > > > > > > > > > > It seems to me that it is a little bit hard to return all > > > > > > > > > events > > > > > > > > > through one SBI call, > > > > > > > > > so I thought we could map the generic hardware events and > > > > > > > > > maintain their own > > > > > > > > > raw events by each platform in OpenSBI. But eventually, I > > > > > > > > > thought the > > > > > > > > > DT mechanism > > > > > > > > > is more clear and easy than that. Let me know if you have > > > > > > > > > any ideas about > > > > > > > > > probe function. Thanks. > > > > > > > > > > > > > > > > We can design SBI calls such that no SBI call is required > > > > > > > > to read > > > > > > > > the perf counter. > > > > > > > > > > > > > > > > The sbi_probe_extension() will only be used to check > > > > > > > > whether > > > > > > > > underlying SBI implementation supports SBI PMU extension. > > > > > > > > > > > > > > > > As-per my initial thoughts, we can potentially have the > > > > > > > > following SBI calls: > > > > > > > > > > > > > > > > 1. SBI_PMU_NUM_COUNTERS > > > > > > > > This call will return the number of SBI PMU counters > > > > > > > > 2. SBI_PMU_COUNTER_DESCRIBE > > > > > > > > This call takes two parameters: 1) physical address 2) > > > > > > > > counter index > > > > > > > > It will write the description of SBI PMU counter at > > > > > > > > specified > > > > > > > > physical address. > > > > > > > > The details of the SBI PMU counter will include name, > > > > > > > > type, etc > > > > > > > > > > > > > > The main things are that we need to pass the information of > > > > > > > raw events > > > > > > > and the information of mapping of generic hardware events. > > > > > > > Maybe > > > > > > > this information could be passed by this SBI call. > > > > > > > > > > > > > > > 3. SBI_PMU_COUNTER_START > > > > > > > > This call takes two parameters: 1) physical address 2) > > > > > > > > counter index > > > > > > > > It will inform SBI implementation to start counting > > > > > > > > specified counter on the > > > > > > > > calling HART. The counter value will be written to the > > > > > > > > specified physical > > > > > > > > address whenever it changes. > > > > > > > > > > > > > > I would prefer to read the counter directly on s-mode. Spec > > > > > > > already defines the > > > > > > > mechanism to allow that. But this way would still work if we > > > > > > > couldn't > > > > > > > read counters > > > > > > > on s-mode. > > > > > > > > > > > > The SBI PMU counters have nothing to do with RISC-V PMU > > > > > > counters because > > > > > > these are counters provided by SBI implementation. > > > > > > > > > > > > All-in-all, we have three types of counters: > > > > > > 1. PMU counters defined by RISC-V privilege spec. These are > > > > > > TIME, > > > > > > INSRET, and CYCLE CSRs. > > > > > > 2. Implementation specific counters accessed via HPMCOUNTER > > > > > > CSRs. > > > > > > 3. SBI PMU counters for traps taken and processed by M-mode > > > > > > runtime > > > > > > firmware. Examples: number of misaligned load/store, number of > > > > > > illegal > > > > > > instructions, number of SBI RFENCE calls, number of SBI IPI > > > > > > calls, etc. > > > > > > > > > > > > The DT based RISC-V PMU platform driver being discussed in this > > > > > > email > > > > > > thread only addresses points 1) and 2) above. > > > > > > > > > > > > > > > > OK, sounds good, I misunderstood your ideas, I mixed the 2) and > > > > > 3) > > > > > and see them as the same thing. Many thanks for the clear > > > > > explanation. > > > > > > > > Cool, we are on the same page till here. > > > > > > > > > > For point 3) above, we need to first define SBI PMU extension. > > > > > > Once SBI > > > > > > PMU extension is defined, we can have separate SBI PMU driver > > > > > > in Linux > > > > > > or extend RISC-V PMU driver to register additonal counters > > > > > > based on > > > > > > SBI PMU extension. > > > > > > > > > > > > I never suggested to access RISC-V HPMCOUNTER CSRs via SBI > > > > > > calls > > > > > > so DT based RISC-V PMU platform driver (for 1) and 2) above) is > > > > > > good > > > > > > to have. The SBI PMU extension is a separate topic. > > > > > > > > > > > > > > 4. SBI_PMU_COUNTER_STOP > > > > > > > > This call takes one parameter: 1) counter index > > > > > > > > It will inform SBI implementation to stop counting > > > > > > > > specified counters on > > > > > > > > the calling HART. > > > > > > > > > > > > > > > > The above calls are generic enough to support any number of > > > > > > > > counters > > > > > > > > and we don't need any SBI call to read the counter. We can > > > > > > > > also assume > > > > > > > > all counters to be of fixed 64bit width. In fact, even > > > > > > > > Hypervisors can support > > > > > > > > it's own SBI PMU counters with SBI PMU extension. > > > > > > > > > > > > > > > > We still need to think more about the above calls because > > > > > > > > above SBI > > > > > > > > calls are just initial ideas. > > > > > > > > > > > > > > > > > > > > > > We also need a SBI call to set the event selector to specify > > > > > > > which event > > > > > > > is monitored. > > > > > > > > > > > > SBI_PMU_COUNTER_START will do that. > > > > > > > > > > I'm not sure whether this SBI call is only for SBI PMU counter > > > > > and > > > > > it's own events. > > > > > For 2), it needs one SBI call to set the events, we just set the > > > > > event selector > > > > > by writing m-mode CSRs on s-mode now. If this SBI call could > > > > > serve 2) > > > > > and 3) both, > > > > > we don't need another SBI call. > > > > > > > > Can you elaborate more ?? > > > > > > > > Is the SBI call for 2) needed to enable/disable counters in > > > > MCOUNTEREN CSR ? > > > > > > > > Currently, OpenSBI enables all counters by default but I see the > > > > need > > > > to enable/disable HPMCOUNTER on-demand from perf event start/stop. > > > > > > > > I hope we don't need any other implementation specific CSR to be > > > > programmed > > > > for enabling/disabling counters on SiFive Unleashed ?? > > > > > > > > > > Here's the next version of SBI PMU extension, which tries to address > > > both > > > 2) and 3). In other words, it covers all HPMCOUNTER CSRs and software > > > counters of SBI implementation. > > > > > > To define SBI PMU extension, we first define counter_idx which is a > > > unique > > > number assigned to a counter: > > > 1. counter_idx = 0 to 2 are for CYCLE, TIME, and INSTRET > > > 2. counter_idx = 3 to 31 are for HPMCOUNTER > > > 3. counter_idx = 32 or higher are for software counters counters > > > provided by SBI implementation > > > > > > > The number of HPMCOUNTER may increase in future. Right ? > > > > How about using a higher starting idx for software counters from SBI > > impolementation ? > > > > Sounds good to me. > > > > The counter_idx == 1 (i.e. TIME CSR) is always enabled when > > > underlying > > > HW implements it. Otherwise it is always disabled. > > > > > > Based on above definition of counter_idx definition, we can > > > potentially have > > > the following SBI calls: > > > > > > 1. SBI_PMU_NUM_HPMCOUNTER > > > This call will return the number of HPMCOUNTER CSRs > > > 2. SBI_PMU_NUM_SOFTWARE > > > This call will return the number of software counters provided by > > > SBI implementation > > > 3. SBI_PMU_COUNTER_DESCRIBE > > > This call takes two parameters: 1) counter_idx 2) physical > > > address > > > It will write the description of SBI PMU counter at specified > > > physical address. > > > The details of the SBI PMU counter will include name, type, > > > width, > > > events etc > > > 4. SBI_PMU_COUNTER_SET_PHYS_ADDR > > > This call takes two parameters: 1) counter_idx 2) physical > > > address > > > It will set the physical address where SBI implementation will > > > write > > > the software counter. This SBI call is only for software counters > > > (i.e. > > > counter_idx >= 32) so it will fail for other counters. > > > 5. SBI_PMU_COUNTER_SELECT_EVENT > > > This call takes two parameters: 1) counter_idx 2) event number > > > It will select a particular HW event to monitor in a HPMCOUNTER > > > CSR. > > > This SBI call is only for HPMCOUNTER CSRs (i.e 3 <= counter_idx > > > <= 31) > > > 6. SBI_PMU_COUNTER_START > > > This call takes one parameter: 1) counter_idx > > > It will inform SBI implementation to start/enable specified > > > counter on the > > > calling HART. This SBI call will fail for counter_idx == 1 and > > > counters > > > which are not present. > > > 7. SBI_PMU_COUNTER_STOP > > > This call takes one parameter: 1) counter_idx > > > It will inform SBI implementation to stop/disable specified > > > counters on > > > the calling HART. This SBI call will fail for counter_idx == 1 > > > and counters > > > which are not present. > > > > > > The above described SBI calls can be conveniently implemented in > > > M-mode runtime firmware (OpenSBI) and various hypervisors (Xvisor, > > > KVM, etc). > > > > > > We can have a single RISC-V PMU driver using above SBI calls which > > > can be used natively in HS-mode and Guest/VM in VS-mode. Of course, > > > we won't need any information to be passed in DT/ACPI for this driver > > > and it can be under arch/riscv/kernel because without DT/ACPI it > > > can't > > > be a platform driver. > > > > We still need the information in DT for mapping generic hardware > > events. No ? > > Yes, I think it does. > Here's v3 of SBI PMU extension which tries to cover CYCLE CSR, INSTRET CSR, HPMCOUNTER CSRs and software counters of the SBI implementation. To define SBI PMU extension, we first define counter_idx which is a unique number assigned to a counter and event_idx which is an encoded number representing event to be monitored. The SBI PMU event_idx is 15bit number encoded as follows: event_idx[14:12] = type event_idx[11:0] = code If event_idx.type == 0 then it is HARDWARE event and event_idx.code can be one of the following: enum sbi_pmu_hw_id { /* * Common hardware events, generalized by the kernel: */ PERF_COUNT_HW_CPU_CYCLES = 0, PERF_COUNT_HW_INSTRUCTIONS = 1, PERF_COUNT_HW_CACHE_REFERENCES = 2, PERF_COUNT_HW_CACHE_MISSES = 3, PERF_COUNT_HW_BRANCH_INSTRUCTIONS = 4, PERF_COUNT_HW_BRANCH_MISSES = 5, PERF_COUNT_HW_BUS_CYCLES = 6, PERF_COUNT_HW_STALLED_CYCLES_FRONTEND = 7, PERF_COUNT_HW_STALLED_CYCLES_BACKEND = 8, PERF_COUNT_HW_REF_CPU_CYCLES = 9, PERF_COUNT_HW_MAX, /* non-ABI */ }; (NOTE: Same as described in <linux_source>/include/uapi/linux/perf_event.h) If event_idx.type == 1 then it is CACHE event and event_idx.code is encoded as follows: event_idx.code[11:4] = cache_id event_idx.code[3:1] = op_id event_idx.code[0:0] = result_id enum sbi_pmu_hw_cache_id { PERF_COUNT_HW_CACHE_L1D = 0, PERF_COUNT_HW_CACHE_L1I = 1, PERF_COUNT_HW_CACHE_LL = 2, PERF_COUNT_HW_CACHE_DTLB = 3, PERF_COUNT_HW_CACHE_ITLB = 4, PERF_COUNT_HW_CACHE_BPU = 5, PERF_COUNT_HW_CACHE_NODE = 6, PERF_COUNT_HW_CACHE_MAX, /* non-ABI */ }; enum sbi_pmu_hw_cache_op_id { PERF_COUNT_HW_CACHE_OP_READ = 0, PERF_COUNT_HW_CACHE_OP_WRITE = 1, PERF_COUNT_HW_CACHE_OP_PREFETCH = 2, PERF_COUNT_HW_CACHE_OP_MAX, /* non-ABI */ }; enum sbi_pmu_hw_cache_op_result_id { PERF_COUNT_HW_CACHE_RESULT_ACCESS = 0, PERF_COUNT_HW_CACHE_RESULT_MISS = 1, PERF_COUNT_HW_CACHE_RESULT_MAX, /* non-ABI */ }; (NOTE: Same as described in <linux_source>/include/uapi/linux/perf_event.h) If event_idx.type == 2 then it is RAW event and event_idx.code is just a RAW event number. In future, more event_idx can be defined without breaking ABI compatibility of SBI calls. Based on above definition of counter_idx definition, we can potentially have the following SBI calls: 1. SBI_PMU_NUM_COUNTERS This call will return the number of COUNTERs 2. SBI_PMU_COUNTER_DESCRIBE This call takes two parameters: 1) counter_idx 2) physical address of 4k page It will write the description of SBI PMU counter at specified physical address. The details of the SBI PMU counter written at specified physical address are as follows: 1. Name (64 bytes) 2. CSR_Offset (4 bytes) (E.g. CSR_Offset == 0x2 imply CSR 0xC02) (E.g. CSR_Offset == 0xffffffff means it is SBI implementation counter) 3. CSR_Width (4 bytes) (Number of CSR bits implemented in HW) 4. Event bitmap (2048 bytes) (i.e. 1-bit for each possible event_idx) (If bit corresponding to a event_idx is 1 then event_idx is supported by the counter) 5. Any thing else ?? 3. SBI_PMU_COUNTER_SET_PHYS_ADDR This call takes two parameters: 1) counter_idx 2) physical address It will set the physical address where SBI implementation will write the software counter. This SBI call is only for counters not mapped to any CSR (i.e. only for counters with CSR_Offset == 0xffffffff). 4. SBI_PMU_COUNTER_START This call takes two parameters: 1) counter_idx 2) event_idx It will inform SBI implementation to configure and start/enable specified counter on the calling HART to monitor specified event. This SBI call will fail for counters which are not present. 5. SBI_PMU_COUNTER_STOP This call takes one parameter: 1) counter_idx It will inform SBI implementation to stop/disable specified counters on the calling HART. This SBI call will fail for counters which are not present. From above, the RISC-V PMU driver will use most of the SBI calls at boot time. Only SBI_PMU_COUNTER_START to used once before using the counter. The reading of counter is by reading CSR (for CSR_Offset != 0xffffffff) OR by reading memory location (for CSR_Offset == 0xffffffff). The counter overflow handling will have to be done in software by Linux kernel. The information returned by SBI_PMU_NUM_COUNTERS and SBI_PMU_COUNTER_DESCRIBE can be passed via DT/ACPI but it will be difficult to maintain because we have hardware counters and SBI implementation counters both provided by SBI PMU extension. The SBI implementation counters are specific to underlying SBI implementation so we will have to keep counters/events described in DT/ACPI in-sync with underlying SBI implementation. Regards, Anup _______________________________________________ linux-riscv mailing list linux-riscv@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-riscv ^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: [RFC PATCH 0/6] Support raw event and DT for perf on RISC-V 2020-06-30 11:38 ` Anup Patel 2020-06-30 18:57 ` Atish Patra @ 2020-07-01 2:11 ` Zong Li 1 sibling, 0 replies; 38+ messages in thread From: Zong Li @ 2020-07-01 2:11 UTC (permalink / raw) To: Anup Patel Cc: linux-riscv, Palmer Dabbelt, linux-kernel@vger.kernel.org List, Alan Kao, Paul Walmsley On Tue, Jun 30, 2020 at 7:38 PM Anup Patel <anup@brainfault.org> wrote: > > On Tue, Jun 30, 2020 at 3:48 PM Anup Patel <anup@brainfault.org> wrote: > > > > On Tue, Jun 30, 2020 at 1:34 PM Zong Li <zong.li@sifive.com> wrote: > > > > > > On Tue, Jun 30, 2020 at 3:40 PM Anup Patel <anup@brainfault.org> wrote: > > > > > > > > On Tue, Jun 30, 2020 at 12:07 PM Zong Li <zong.li@sifive.com> wrote: > > > > > > > > > > On Mon, Jun 29, 2020 at 9:23 PM Anup Patel <anup@brainfault.org> wrote: > > > > > > > > > > > > On Mon, Jun 29, 2020 at 6:23 PM Zong Li <zong.li@sifive.com> wrote: > > > > > > > > > > > > > > On Mon, Jun 29, 2020 at 4:28 PM Anup Patel <anup@brainfault.org> wrote: > > > > > > > > > > > > > > > > On Mon, Jun 29, 2020 at 11:22 AM Zong Li <zong.li@sifive.com> wrote: > > > > > > > > > > > > > > > > > > On Mon, Jun 29, 2020 at 12:53 PM Anup Patel <anup@brainfault.org> wrote: > > > > > > > > > > > > > > > > > > > > On Mon, Jun 29, 2020 at 8:49 AM Zong Li <zong.li@sifive.com> wrote: > > > > > > > > > > > > > > > > > > > > > > This patch set adds raw event support on RISC-V. In addition, we > > > > > > > > > > > introduce the DT mechanism to make our perf more generic and common. > > > > > > > > > > > > > > > > > > > > > > Currently, we set the hardware events by writing the mhpmeventN CSRs, it > > > > > > > > > > > would raise an illegal instruction exception and trap into m-mode to > > > > > > > > > > > emulate event selector CSRs access. It doesn't make sense because we > > > > > > > > > > > shouldn't write the m-mode CSRs in s-mode. Ideally, we should set event > > > > > > > > > > > selector through standard SBI call or the shadow CSRs of s-mode. We have > > > > > > > > > > > prepared a proposal of a new SBI extension, called "PMU SBI extension", > > > > > > > > > > > but we also discussing the feasibility of accessing these PMU CSRs on > > > > > > > > > > > s-mode at the same time, such as delegation mechanism, so I was > > > > > > > > > > > wondering if we could use SBI calls first and make the PMU SBI extension > > > > > > > > > > > as legacy when s-mode access mechanism is accepted by Foundation? or > > > > > > > > > > > keep the current situation to see what would happen in the future. > > > > > > > > > > > > > > > > > > > > > > This patch set also introduces the DT mechanism, we don't want to add too > > > > > > > > > > > much platform-dependency code in perf like other architectures, so we > > > > > > > > > > > put the mapping of generic hardware events to DT, then we can easy to > > > > > > > > > > > transfer generic hardware events to vendor's own hardware events without > > > > > > > > > > > any platfrom-dependency stuff in our perf. > > > > > > > > > > > > > > > > > > > > Please re-write this series to have RISC-V PMU driver as a regular > > > > > > > > > > platform driver as drivers/perf/riscv_pmu.c. > > > > > > > > > > > > > > > > > > > > The PMU related sources will have to be removed from arch/riscv. > > > > > > > > > > > > > > > > > > > > Based on implementation of final drivers/perf/riscv_pmu.c we will > > > > > > > > > > come-up with drivers/perf/riscv_sbi_pmu.c driver for SBI perf counters. > > > > > > > > > > > > > > > > > > > > > > > > > > > > There are some different ways to implement perf, and current > > > > > > > > > implementation seems to be consensus when perf was introduced at the > > > > > > > > > beginning [0][1]. I don't persist to which one, I could change the > > > > > > > > > implementation as you mentioned if it is a new consensus one. > > > > > > > > > > > > > > > > > > [0] https://github.com/riscv/riscv-linux/pull/124#issuecomment-367563910 > > > > > > > > > > > > > > > > I would not recommend taking the original RISC-V linux fork as reference. > > > > > > > > > > > > > > > > Rather we should study how things are done on other architectures. > > > > > > > > > > > > > > > > I really appreciate the attempt to make RISC-V PMU driver depend on DT > > > > > > > > but if we are going this route then we should maximize the use of Linux > > > > > > > > platform driver framework. In fact, whenever possible we should integrate > > > > > > > > RISC-V features as platform drivers under the drivers/ directory. > > > > > > > > > > > > > > > > > > > > > > OK, I would change the implementation to platform driver if there is no > > > > > > > other voice. > > > > > > > > > > > > > > > I thought about SBI PMU counters as well. In future, we can easily > > > > > > > > expose SBI PMU counters as RAW events in the same RISC-V PMU > > > > > > > > driver. The sbi_probe_extension() can be used in RISC-V PMU driver > > > > > > > > to check for SBI PMU counters so no special provisions needed in DT > > > > > > > > for SBI PMU counters. > > > > > > > > > > > > > > > > > > > > > > I thought about probing raw events by SBI extension too, I'm interested if you > > > > > > > have more detail about this. > > > > > > > > > > > > > > It seems to me that it is a little bit hard to return all events > > > > > > > through one SBI call, > > > > > > > so I thought we could map the generic hardware events and maintain their own > > > > > > > raw events by each platform in OpenSBI. But eventually, I thought the > > > > > > > DT mechanism > > > > > > > is more clear and easy than that. Let me know if you have any ideas about > > > > > > > probe function. Thanks. > > > > > > > > > > > > We can design SBI calls such that no SBI call is required to read > > > > > > the perf counter. > > > > > > > > > > > > The sbi_probe_extension() will only be used to check whether > > > > > > underlying SBI implementation supports SBI PMU extension. > > > > > > > > > > > > As-per my initial thoughts, we can potentially have the following SBI calls: > > > > > > > > > > > > 1. SBI_PMU_NUM_COUNTERS > > > > > > This call will return the number of SBI PMU counters > > > > > > 2. SBI_PMU_COUNTER_DESCRIBE > > > > > > This call takes two parameters: 1) physical address 2) counter index > > > > > > It will write the description of SBI PMU counter at specified > > > > > > physical address. > > > > > > The details of the SBI PMU counter will include name, type, etc > > > > > > > > > > The main things are that we need to pass the information of raw events > > > > > and the information of mapping of generic hardware events. Maybe > > > > > this information could be passed by this SBI call. > > > > > > > > > > > 3. SBI_PMU_COUNTER_START > > > > > > This call takes two parameters: 1) physical address 2) counter index > > > > > > It will inform SBI implementation to start counting specified counter on the > > > > > > calling HART. The counter value will be written to the specified physical > > > > > > address whenever it changes. > > > > > > > > > > I would prefer to read the counter directly on s-mode. Spec already defines the > > > > > mechanism to allow that. But this way would still work if we couldn't > > > > > read counters > > > > > on s-mode. > > > > > > > > The SBI PMU counters have nothing to do with RISC-V PMU counters because > > > > these are counters provided by SBI implementation. > > > > > > > > All-in-all, we have three types of counters: > > > > 1. PMU counters defined by RISC-V privilege spec. These are TIME, > > > > INSRET, and CYCLE CSRs. > > > > 2. Implementation specific counters accessed via HPMCOUNTER CSRs. > > > > 3. SBI PMU counters for traps taken and processed by M-mode runtime > > > > firmware. Examples: number of misaligned load/store, number of illegal > > > > instructions, number of SBI RFENCE calls, number of SBI IPI calls, etc. > > > > > > > > The DT based RISC-V PMU platform driver being discussed in this email > > > > thread only addresses points 1) and 2) above. > > > > > > > > > > OK, sounds good, I misunderstood your ideas, I mixed the 2) and 3) > > > and see them as the same thing. Many thanks for the clear explanation. > > > > Cool, we are on the same page till here. > > > > > > > > > For point 3) above, we need to first define SBI PMU extension. Once SBI > > > > PMU extension is defined, we can have separate SBI PMU driver in Linux > > > > or extend RISC-V PMU driver to register additonal counters based on > > > > SBI PMU extension. > > > > > > > > I never suggested to access RISC-V HPMCOUNTER CSRs via SBI calls > > > > so DT based RISC-V PMU platform driver (for 1) and 2) above) is good > > > > to have. The SBI PMU extension is a separate topic. > > > > > > > > > > > > > > > 4. SBI_PMU_COUNTER_STOP > > > > > > This call takes one parameter: 1) counter index > > > > > > It will inform SBI implementation to stop counting specified counters on > > > > > > the calling HART. > > > > > > > > > > > > The above calls are generic enough to support any number of counters > > > > > > and we don't need any SBI call to read the counter. We can also assume > > > > > > all counters to be of fixed 64bit width. In fact, even Hypervisors can support > > > > > > it's own SBI PMU counters with SBI PMU extension. > > > > > > > > > > > > We still need to think more about the above calls because above SBI > > > > > > calls are just initial ideas. > > > > > > > > > > > > > > > > We also need a SBI call to set the event selector to specify which event > > > > > is monitored. > > > > > > > > SBI_PMU_COUNTER_START will do that. > > > > > > I'm not sure whether this SBI call is only for SBI PMU counter and > > > it's own events. > > > For 2), it needs one SBI call to set the events, we just set the event selector > > > by writing m-mode CSRs on s-mode now. If this SBI call could serve 2) > > > and 3) both, > > > we don't need another SBI call. > > > > Can you elaborate more ?? > > > > Is the SBI call for 2) needed to enable/disable counters in MCOUNTEREN CSR ? > > > > Currently, OpenSBI enables all counters by default but I see the need > > to enable/disable HPMCOUNTER on-demand from perf event start/stop. > > > > I hope we don't need any other implementation specific CSR to be programmed > > for enabling/disabling counters on SiFive Unleashed ?? > > > > Here's the next version of SBI PMU extension, which tries to address both > 2) and 3). In other words, it covers all HPMCOUNTER CSRs and software > counters of SBI implementation. > > To define SBI PMU extension, we first define counter_idx which is a unique > number assigned to a counter: > 1. counter_idx = 0 to 2 are for CYCLE, TIME, and INSTRET > 2. counter_idx = 3 to 31 are for HPMCOUNTER CSRs > 3. counter_idx = 32 or higher are for software counters provided by > SBI implementation > > The counter_idx == 1 (i.e. TIME CSR) is always enabled when underlying > HW implements it. Otherwise it is always disabled. > > Based on above definition of counter_idx definition, we can potentially have > the following SBI calls: > > 1. SBI_PMU_NUM_HPMCOUNTER > This call will return the number of HPMCOUNTER CSRs > 2. SBI_PMU_NUM_SOFTWARE > This call will return the number of software counters provided by > SBI implementation > 3. SBI_PMU_COUNTER_DESCRIBE > This call takes two parameters: 1) counter_idx 2) physical address > It will write the description of SBI PMU counter at specified > physical address. > The details of the SBI PMU counter will include name, type, width, > events etc > 4. SBI_PMU_COUNTER_SET_PHYS_ADDR > This call takes two parameters: 1) counter_idx 2) physical address > It will set the physical address where SBI implementation will write > the software counter. This SBI call is only for software counters (i.e. > counter_idx >= 32) so it will fail for other counters. > 5. SBI_PMU_COUNTER_SELECT_EVENT > This call takes two parameters: 1) counter_idx 2) event number > It will select a particular HW event to monitor in a HPMCOUNTER CSR. > This SBI call is only for HPMCOUNTER CSRs (i.e 3 <= counter_idx <= 31) > 6. SBI_PMU_COUNTER_START > This call takes one parameter: 1) counter_idx > It will inform SBI implementation to start/enable specified counter on the > calling HART. This SBI call will fail for counter_idx == 1 and counters > which are not present. > 7. SBI_PMU_COUNTER_STOP > This call takes one parameter: 1) counter_idx > It will inform SBI implementation to stop/disable specified counters on > the calling HART. This SBI call will fail for counter_idx == 1 and counters > which are not present. > > The above described SBI calls can be conveniently implemented in > M-mode runtime firmware (OpenSBI) and various hypervisors (Xvisor, KVM, etc). > > We can have a single RISC-V PMU driver using above SBI calls which > can be used natively in HS-mode and Guest/VM in VS-mode. Of course, > we won't need any information to be passed in DT/ACPI for this driver > and it can be under arch/riscv/kernel because without DT/ACPI it can't > be a platform driver. The availability of SBI PMU extension can be checked > using sbi_probe_extension() SBI call. > It seems to me that we could separate the function id for MHPMCOUNTER and SBI PMU counters in SBI PMU extension. For example, use MSB of function id to distinguish them. It would be more clear to propose. OTOH, do we also need to define a series of event types of SBI PMU counters? > Regards, > Anup _______________________________________________ linux-riscv mailing list linux-riscv@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-riscv ^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: [RFC PATCH 0/6] Support raw event and DT for perf on RISC-V 2020-06-30 10:18 ` Anup Patel 2020-06-30 11:38 ` Anup Patel @ 2020-07-01 1:55 ` Zong Li 1 sibling, 0 replies; 38+ messages in thread From: Zong Li @ 2020-07-01 1:55 UTC (permalink / raw) To: Anup Patel Cc: linux-riscv, Palmer Dabbelt, linux-kernel@vger.kernel.org List, Alan Kao, Paul Walmsley On Tue, Jun 30, 2020 at 6:19 PM Anup Patel <anup@brainfault.org> wrote: > > On Tue, Jun 30, 2020 at 1:34 PM Zong Li <zong.li@sifive.com> wrote: > > > > On Tue, Jun 30, 2020 at 3:40 PM Anup Patel <anup@brainfault.org> wrote: > > > > > > On Tue, Jun 30, 2020 at 12:07 PM Zong Li <zong.li@sifive.com> wrote: > > > > > > > > On Mon, Jun 29, 2020 at 9:23 PM Anup Patel <anup@brainfault.org> wrote: > > > > > > > > > > On Mon, Jun 29, 2020 at 6:23 PM Zong Li <zong.li@sifive.com> wrote: > > > > > > > > > > > > On Mon, Jun 29, 2020 at 4:28 PM Anup Patel <anup@brainfault.org> wrote: > > > > > > > > > > > > > > On Mon, Jun 29, 2020 at 11:22 AM Zong Li <zong.li@sifive.com> wrote: > > > > > > > > > > > > > > > > On Mon, Jun 29, 2020 at 12:53 PM Anup Patel <anup@brainfault.org> wrote: > > > > > > > > > > > > > > > > > > On Mon, Jun 29, 2020 at 8:49 AM Zong Li <zong.li@sifive.com> wrote: > > > > > > > > > > > > > > > > > > > > This patch set adds raw event support on RISC-V. In addition, we > > > > > > > > > > introduce the DT mechanism to make our perf more generic and common. > > > > > > > > > > > > > > > > > > > > Currently, we set the hardware events by writing the mhpmeventN CSRs, it > > > > > > > > > > would raise an illegal instruction exception and trap into m-mode to > > > > > > > > > > emulate event selector CSRs access. It doesn't make sense because we > > > > > > > > > > shouldn't write the m-mode CSRs in s-mode. Ideally, we should set event > > > > > > > > > > selector through standard SBI call or the shadow CSRs of s-mode. We have > > > > > > > > > > prepared a proposal of a new SBI extension, called "PMU SBI extension", > > > > > > > > > > but we also discussing the feasibility of accessing these PMU CSRs on > > > > > > > > > > s-mode at the same time, such as delegation mechanism, so I was > > > > > > > > > > wondering if we could use SBI calls first and make the PMU SBI extension > > > > > > > > > > as legacy when s-mode access mechanism is accepted by Foundation? or > > > > > > > > > > keep the current situation to see what would happen in the future. > > > > > > > > > > > > > > > > > > > > This patch set also introduces the DT mechanism, we don't want to add too > > > > > > > > > > much platform-dependency code in perf like other architectures, so we > > > > > > > > > > put the mapping of generic hardware events to DT, then we can easy to > > > > > > > > > > transfer generic hardware events to vendor's own hardware events without > > > > > > > > > > any platfrom-dependency stuff in our perf. > > > > > > > > > > > > > > > > > > Please re-write this series to have RISC-V PMU driver as a regular > > > > > > > > > platform driver as drivers/perf/riscv_pmu.c. > > > > > > > > > > > > > > > > > > The PMU related sources will have to be removed from arch/riscv. > > > > > > > > > > > > > > > > > > Based on implementation of final drivers/perf/riscv_pmu.c we will > > > > > > > > > come-up with drivers/perf/riscv_sbi_pmu.c driver for SBI perf counters. > > > > > > > > > > > > > > > > > > > > > > > > > There are some different ways to implement perf, and current > > > > > > > > implementation seems to be consensus when perf was introduced at the > > > > > > > > beginning [0][1]. I don't persist to which one, I could change the > > > > > > > > implementation as you mentioned if it is a new consensus one. > > > > > > > > > > > > > > > > [0] https://github.com/riscv/riscv-linux/pull/124#issuecomment-367563910 > > > > > > > > > > > > > > I would not recommend taking the original RISC-V linux fork as reference. > > > > > > > > > > > > > > Rather we should study how things are done on other architectures. > > > > > > > > > > > > > > I really appreciate the attempt to make RISC-V PMU driver depend on DT > > > > > > > but if we are going this route then we should maximize the use of Linux > > > > > > > platform driver framework. In fact, whenever possible we should integrate > > > > > > > RISC-V features as platform drivers under the drivers/ directory. > > > > > > > > > > > > > > > > > > > OK, I would change the implementation to platform driver if there is no > > > > > > other voice. > > > > > > > > > > > > > I thought about SBI PMU counters as well. In future, we can easily > > > > > > > expose SBI PMU counters as RAW events in the same RISC-V PMU > > > > > > > driver. The sbi_probe_extension() can be used in RISC-V PMU driver > > > > > > > to check for SBI PMU counters so no special provisions needed in DT > > > > > > > for SBI PMU counters. > > > > > > > > > > > > > > > > > > > I thought about probing raw events by SBI extension too, I'm interested if you > > > > > > have more detail about this. > > > > > > > > > > > > It seems to me that it is a little bit hard to return all events > > > > > > through one SBI call, > > > > > > so I thought we could map the generic hardware events and maintain their own > > > > > > raw events by each platform in OpenSBI. But eventually, I thought the > > > > > > DT mechanism > > > > > > is more clear and easy than that. Let me know if you have any ideas about > > > > > > probe function. Thanks. > > > > > > > > > > We can design SBI calls such that no SBI call is required to read > > > > > the perf counter. > > > > > > > > > > The sbi_probe_extension() will only be used to check whether > > > > > underlying SBI implementation supports SBI PMU extension. > > > > > > > > > > As-per my initial thoughts, we can potentially have the following SBI calls: > > > > > > > > > > 1. SBI_PMU_NUM_COUNTERS > > > > > This call will return the number of SBI PMU counters > > > > > 2. SBI_PMU_COUNTER_DESCRIBE > > > > > This call takes two parameters: 1) physical address 2) counter index > > > > > It will write the description of SBI PMU counter at specified > > > > > physical address. > > > > > The details of the SBI PMU counter will include name, type, etc > > > > > > > > The main things are that we need to pass the information of raw events > > > > and the information of mapping of generic hardware events. Maybe > > > > this information could be passed by this SBI call. > > > > > > > > > 3. SBI_PMU_COUNTER_START > > > > > This call takes two parameters: 1) physical address 2) counter index > > > > > It will inform SBI implementation to start counting specified counter on the > > > > > calling HART. The counter value will be written to the specified physical > > > > > address whenever it changes. > > > > > > > > I would prefer to read the counter directly on s-mode. Spec already defines the > > > > mechanism to allow that. But this way would still work if we couldn't > > > > read counters > > > > on s-mode. > > > > > > The SBI PMU counters have nothing to do with RISC-V PMU counters because > > > these are counters provided by SBI implementation. > > > > > > All-in-all, we have three types of counters: > > > 1. PMU counters defined by RISC-V privilege spec. These are TIME, > > > INSRET, and CYCLE CSRs. > > > 2. Implementation specific counters accessed via HPMCOUNTER CSRs. > > > 3. SBI PMU counters for traps taken and processed by M-mode runtime > > > firmware. Examples: number of misaligned load/store, number of illegal > > > instructions, number of SBI RFENCE calls, number of SBI IPI calls, etc. > > > > > > The DT based RISC-V PMU platform driver being discussed in this email > > > thread only addresses points 1) and 2) above. > > > > > > > OK, sounds good, I misunderstood your ideas, I mixed the 2) and 3) > > and see them as the same thing. Many thanks for the clear explanation. > > Cool, we are on the same page till here. > > > > > > For point 3) above, we need to first define SBI PMU extension. Once SBI > > > PMU extension is defined, we can have separate SBI PMU driver in Linux > > > or extend RISC-V PMU driver to register additonal counters based on > > > SBI PMU extension. > > > > > > I never suggested to access RISC-V HPMCOUNTER CSRs via SBI calls > > > so DT based RISC-V PMU platform driver (for 1) and 2) above) is good > > > to have. The SBI PMU extension is a separate topic. > > > > > > > > > > > > 4. SBI_PMU_COUNTER_STOP > > > > > This call takes one parameter: 1) counter index > > > > > It will inform SBI implementation to stop counting specified counters on > > > > > the calling HART. > > > > > > > > > > The above calls are generic enough to support any number of counters > > > > > and we don't need any SBI call to read the counter. We can also assume > > > > > all counters to be of fixed 64bit width. In fact, even Hypervisors can support > > > > > it's own SBI PMU counters with SBI PMU extension. > > > > > > > > > > We still need to think more about the above calls because above SBI > > > > > calls are just initial ideas. > > > > > > > > > > > > > We also need a SBI call to set the event selector to specify which event > > > > is monitored. > > > > > > SBI_PMU_COUNTER_START will do that. > > > > I'm not sure whether this SBI call is only for SBI PMU counter and > > it's own events. > > For 2), it needs one SBI call to set the events, we just set the event selector > > by writing m-mode CSRs on s-mode now. If this SBI call could serve 2) > > and 3) both, > > we don't need another SBI call. > > Can you elaborate more ?? > > Is the SBI call for 2) needed to enable/disable counters in MCOUNTEREN CSR ? > > Currently, OpenSBI enables all counters by default but I see the need > to enable/disable HPMCOUNTER on-demand from perf event start/stop. > > I hope we don't need any other implementation specific CSR to be programmed > for enabling/disabling counters on SiFive Unleashed ?? Your next version 5) is good to my case, we need a way to set the mhpmeventN. Thanks. We don't need to configure enable/disable now, but it would be good if we can set mcounteren and mcountinhib through SBI calls at runtime. > > Regards, > Anup > > > > > > > > > > > > > > > Maybe you can refine the above ideas and send a proposal to the > > > > > UnixPlatformSpec mailing list ?? > > > > > > > > > > > > > Ok, let us talk about the details in that. > > > > > > Regards, > > > Anup > > > > > > > > > > > > > > > > Regards, > > > > > Anup > > > > > > > > > > > > > > > > > > Also, the RISC-V PMU driver can be implemented such that it will > > > > > > > work for RV32, RV64, NoMMU RV32, and NoMMU RV64. > > > > > > > > > > > > > > Regards, > > > > > > > Anup > > > > > > > > > > > > > > > [1] https://groups.google.com/a/groups.riscv.org/g/sw-dev/c/f19TmCNP6yA > > > > > > > > > > > > > > > > > Regards, > > > > > > > > > Anup > > > > > > > > > > > > > > > > > > > > > > > > > > > > > Zong Li (6): > > > > > > > > > > dt-bindings: riscv: Add YAML documentation for PMU > > > > > > > > > > riscv: dts: sifive: Add DT support for PMU > > > > > > > > > > riscv: add definition of hpmcounter CSRs > > > > > > > > > > riscv: perf: Add raw event support > > > > > > > > > > riscv: perf: introduce DT mechanism > > > > > > > > > > riscv: remove PMU menu of Kconfig > > > > > > > > > > > > > > > > > > > > .../devicetree/bindings/riscv/pmu.yaml | 59 +++ > > > > > > > > > > arch/riscv/Kconfig | 13 - > > > > > > > > > > arch/riscv/boot/dts/sifive/fu540-c000.dtsi | 13 + > > > > > > > > > > arch/riscv/include/asm/csr.h | 58 +++ > > > > > > > > > > arch/riscv/include/asm/perf_event.h | 100 ++-- > > > > > > > > > > arch/riscv/kernel/Makefile | 2 +- > > > > > > > > > > arch/riscv/kernel/perf_event.c | 471 +++++++++++------- > > > > > > > > > > 7 files changed, 471 insertions(+), 245 deletions(-) > > > > > > > > > > create mode 100644 Documentation/devicetree/bindings/riscv/pmu.yaml > > > > > > > > > > > > > > > > > > > > -- > > > > > > > > > > 2.27.0 > > > > > > > > > > _______________________________________________ linux-riscv mailing list linux-riscv@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-riscv ^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: [RFC PATCH 0/6] Support raw event and DT for perf on RISC-V 2020-06-29 3:19 [RFC PATCH 0/6] Support raw event and DT for perf on RISC-V Zong Li ` (6 preceding siblings ...) 2020-06-29 4:52 ` [RFC PATCH 0/6] Support raw event and DT for perf on RISC-V Anup Patel @ 2020-07-01 0:51 ` Alan Kao 2020-07-01 1:02 ` Atish Patra ` (2 more replies) 7 siblings, 3 replies; 38+ messages in thread From: Alan Kao @ 2020-07-01 0:51 UTC (permalink / raw) To: Zong Li; +Cc: linux-riscv, palmer, linux-kernel, paul.walmsley On Mon, Jun 29, 2020 at 11:19:09AM +0800, Zong Li wrote: > This patch set adds raw event support on RISC-V. In addition, we > introduce the DT mechanism to make our perf more generic and common. > > Currently, we set the hardware events by writing the mhpmeventN CSRs, it > would raise an illegal instruction exception and trap into m-mode to > emulate event selector CSRs access. It doesn't make sense because we > shouldn't write the m-mode CSRs in s-mode. Ideally, we should set event > selector through standard SBI call or the shadow CSRs of s-mode. We have > prepared a proposal of a new SBI extension, called "PMU SBI extension", > but we also discussing the feasibility of accessing these PMU CSRs on > s-mode at the same time, such as delegation mechanism, so I was > wondering if we could use SBI calls first and make the PMU SBI extension > as legacy when s-mode access mechanism is accepted by Foundation? or > keep the current situation to see what would happen in the future. > > This patch set also introduces the DT mechanism, we don't want to add too > much platform-dependency code in perf like other architectures, so we > put the mapping of generic hardware events to DT, then we can easy to > transfer generic hardware events to vendor's own hardware events without > any platfrom-dependency stuff in our perf. > > Zong Li (6): > dt-bindings: riscv: Add YAML documentation for PMU > riscv: dts: sifive: Add DT support for PMU > riscv: add definition of hpmcounter CSRs > riscv: perf: Add raw event support > riscv: perf: introduce DT mechanism > riscv: remove PMU menu of Kconfig > DT-based PMU registration looks good to me. Together with Anup's feedback, we can anticipate that the following items will be: - rewrite RISC-V PMU to a platform driver - propose SBI PMU extention - fixes: RV32 counter access, namings, etc. Yes, all are good directions towards better counting (`perf stat`) function. But as the original author of RISC-V perf port, please allow me to address the fundamental problems of RISC-V perf, again [0][1][2][3], that the sampling (`perf record`) function never earned enough respect. Counting gives you a shallow view regarding an application, while sampling demystifies one for you. The problems are three-fold (1) Interrupt Sampling in perf requires that a HPM raises an interrupt when it overflows. Making RISC-V perf platform driver or not has nothing to do with this. This requires more discussions in TGs. (2) S-mode access to PMU CSRs This is also addressed in this patch set but to me, it is kind of like a SBI-solves-them-all mindset to me. Perf event is for performance monitoring thus we should eliminate any possible overhead if we can. Setting event masks through SBI calls for counting maybe OK, but if we really take sampling and interrupt handling into consideration, it is questionable if it is still a viable way. (3) Registers, registers, registers There is just no enough CSR/function for perf sampling. The previous proposal explains why [2]. Perf sampling is off-topic but somehow related, so I bring it up here just for your information. As this patch set goes v2, the PMU porting guide in [0] should be removed since it contains no useful information anymore. [0] Documentation/riscv/pmu.rst [1] https://www.youtube.com/watch?v=Onvlcl4e2IU [2] https://github.com/riscv/riscv-isa-manual/issues/402 This proposal has been posted in Privileged Spec Task Group, in https://lists.riscv.org/g/tech-privileged-archive/message/488?p=,,,20,0,0,0::Created,,Proposal,20,2,40,32306071 but never receive any feedback. [3] https://lists.riscv.org/g/tech-unixplatformspec/message/84 I intended to discuss [2] in the Unixplatform Spec Task Group at the online meeting, but obviously people were too busy knowing who the new RISC-V CTO is and what he has done to even follow the agenda. _______________________________________________ linux-riscv mailing list linux-riscv@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-riscv ^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: [RFC PATCH 0/6] Support raw event and DT for perf on RISC-V 2020-07-01 0:51 ` Alan Kao @ 2020-07-01 1:02 ` Atish Patra 2020-07-01 2:45 ` Alan Kao 2020-07-01 3:15 ` Zong Li 2020-07-01 4:13 ` Anup Patel 2 siblings, 1 reply; 38+ messages in thread From: Atish Patra @ 2020-07-01 1:02 UTC (permalink / raw) To: Alan Kao Cc: linux-riscv, Palmer Dabbelt, linux-kernel@vger.kernel.org List, Zong Li, Paul Walmsley On Tue, Jun 30, 2020 at 5:52 PM Alan Kao <alankao@andestech.com> wrote: > > On Mon, Jun 29, 2020 at 11:19:09AM +0800, Zong Li wrote: > > This patch set adds raw event support on RISC-V. In addition, we > > introduce the DT mechanism to make our perf more generic and common. > > > > Currently, we set the hardware events by writing the mhpmeventN CSRs, it > > would raise an illegal instruction exception and trap into m-mode to > > emulate event selector CSRs access. It doesn't make sense because we > > shouldn't write the m-mode CSRs in s-mode. Ideally, we should set event > > selector through standard SBI call or the shadow CSRs of s-mode. We have > > prepared a proposal of a new SBI extension, called "PMU SBI extension", > > but we also discussing the feasibility of accessing these PMU CSRs on > > s-mode at the same time, such as delegation mechanism, so I was > > wondering if we could use SBI calls first and make the PMU SBI extension > > as legacy when s-mode access mechanism is accepted by Foundation? or > > keep the current situation to see what would happen in the future. > > > > This patch set also introduces the DT mechanism, we don't want to add too > > much platform-dependency code in perf like other architectures, so we > > put the mapping of generic hardware events to DT, then we can easy to > > transfer generic hardware events to vendor's own hardware events without > > any platfrom-dependency stuff in our perf. > > > > Zong Li (6): > > dt-bindings: riscv: Add YAML documentation for PMU > > riscv: dts: sifive: Add DT support for PMU > > riscv: add definition of hpmcounter CSRs > > riscv: perf: Add raw event support > > riscv: perf: introduce DT mechanism > > riscv: remove PMU menu of Kconfig > > > > DT-based PMU registration looks good to me. Together with Anup's feedback, > we can anticipate that the following items will be: > > - rewrite RISC-V PMU to a platform driver > - propose SBI PMU extention > - fixes: RV32 counter access, namings, etc. > > Yes, all are good directions towards better counting (`perf stat`) function. > But as the original author of RISC-V perf port, please allow me to address > the fundamental problems of RISC-V perf, again [0][1][2][3], that the sampling > (`perf record`) function never earned enough respect. Counting gives you a > shallow view regarding an application, while sampling demystifies one for you. > > The problems are three-fold > (1) Interrupt > Sampling in perf requires that a HPM raises an interrupt when it overflows. > Making RISC-V perf platform driver or not has nothing to do with this. This > requires more discussions in TGs. > (2) S-mode access to PMU CSRs > This is also addressed in this patch set but to me, it is kind of like a > SBI-solves-them-all mindset to me. Perf event is for performance monitoring > thus we should eliminate any possible overhead if we can. Setting event masks > through SBI calls for counting maybe OK, but if we really take sampling and > interrupt handling into consideration, it is questionable if it is still a > viable way. > (3) Registers, registers, registers > There is just no enough CSR/function for perf sampling. The previous proposal > explains why [2]. > > Perf sampling is off-topic but somehow related, so I bring it up here just > for your information. > > As this patch set goes v2, the PMU porting guide in [0] should be removed since > it contains no useful information anymore. > > [0] Documentation/riscv/pmu.rst > [1] https://www.youtube.com/watch?v=Onvlcl4e2IU > [2] https://github.com/riscv/riscv-isa-manual/issues/402 > This proposal has been posted in Privileged Spec Task Group, in > https://lists.riscv.org/g/tech-privileged-archive/message/488?p=,,,20,0,0,0::Created,,Proposal,20,2,40,32306071 > but never receive any feedback. > [3] https://lists.riscv.org/g/tech-unixplatformspec/message/84 > I intended to discuss [2] in the Unixplatform Spec Task Group at the > online meeting, but obviously people were too busy knowing who the new > RISC-V CTO is and what he has done to even follow the agenda. > Sorry. The last meeting's agenda was derailed for numerous reasons. Are you okay with discussing this during the next meeting ? I have not scheduled one yet but will probably schedule it on next Wednesday (8th July) if there is no objection. I can check with Anup if he can present the SBI PMU extension as well. > > _______________________________________________ > linux-riscv mailing list > linux-riscv@lists.infradead.org > http://lists.infradead.org/mailman/listinfo/linux-riscv -- Regards, Atish _______________________________________________ linux-riscv mailing list linux-riscv@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-riscv ^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: [RFC PATCH 0/6] Support raw event and DT for perf on RISC-V 2020-07-01 1:02 ` Atish Patra @ 2020-07-01 2:45 ` Alan Kao 0 siblings, 0 replies; 38+ messages in thread From: Alan Kao @ 2020-07-01 2:45 UTC (permalink / raw) To: Atish Patra Cc: linux-riscv, Palmer Dabbelt, linux-kernel@vger.kernel.org List, Zong Li, Paul Walmsley Tue, Jun 30, 2020 at 06:02:43PM -0700, Atish Patra wrote: > On Tue, Jun 30, 2020 at 5:52 PM Alan Kao <alankao@andestech.com> wrote: > > > > On Mon, Jun 29, 2020 at 11:19:09AM +0800, Zong Li wrote: > > > This patch set adds raw event support on RISC-V. In addition, we > > > introduce the DT mechanism to make our perf more generic and common. > > > > > > Currently, we set the hardware events by writing the mhpmeventN CSRs, it > > > would raise an illegal instruction exception and trap into m-mode to > > > emulate event selector CSRs access. It doesn't make sense because we > > > shouldn't write the m-mode CSRs in s-mode. Ideally, we should set event > > > selector through standard SBI call or the shadow CSRs of s-mode. We have > > > prepared a proposal of a new SBI extension, called "PMU SBI extension", > > > but we also discussing the feasibility of accessing these PMU CSRs on > > > s-mode at the same time, such as delegation mechanism, so I was > > > wondering if we could use SBI calls first and make the PMU SBI extension > > > as legacy when s-mode access mechanism is accepted by Foundation? or > > > keep the current situation to see what would happen in the future. > > > > > > This patch set also introduces the DT mechanism, we don't want to add too > > > much platform-dependency code in perf like other architectures, so we > > > put the mapping of generic hardware events to DT, then we can easy to > > > transfer generic hardware events to vendor's own hardware events without > > > any platfrom-dependency stuff in our perf. > > > > > > Zong Li (6): > > > dt-bindings: riscv: Add YAML documentation for PMU > > > riscv: dts: sifive: Add DT support for PMU > > > riscv: add definition of hpmcounter CSRs > > > riscv: perf: Add raw event support > > > riscv: perf: introduce DT mechanism > > > riscv: remove PMU menu of Kconfig > > > > > > > DT-based PMU registration looks good to me. Together with Anup's feedback, > > we can anticipate that the following items will be: > > > > - rewrite RISC-V PMU to a platform driver > > - propose SBI PMU extention > > - fixes: RV32 counter access, namings, etc. > > > > Yes, all are good directions towards better counting (`perf stat`) function. > > But as the original author of RISC-V perf port, please allow me to address > > the fundamental problems of RISC-V perf, again [0][1][2][3], that the sampling > > (`perf record`) function never earned enough respect. Counting gives you a > > shallow view regarding an application, while sampling demystifies one for you. > > > > The problems are three-fold > > (1) Interrupt > > Sampling in perf requires that a HPM raises an interrupt when it overflows. > > Making RISC-V perf platform driver or not has nothing to do with this. This > > requires more discussions in TGs. > > (2) S-mode access to PMU CSRs > > This is also addressed in this patch set but to me, it is kind of like a > > SBI-solves-them-all mindset to me. Perf event is for performance monitoring > > thus we should eliminate any possible overhead if we can. Setting event masks > > through SBI calls for counting maybe OK, but if we really take sampling and > > interrupt handling into consideration, it is questionable if it is still a > > viable way. > > (3) Registers, registers, registers > > There is just no enough CSR/function for perf sampling. The previous proposal > > explains why [2]. > > > > Perf sampling is off-topic but somehow related, so I bring it up here just > > for your information. > > > > As this patch set goes v2, the PMU porting guide in [0] should be removed since > > it contains no useful information anymore. > > > > [0] Documentation/riscv/pmu.rst > > [1] https://www.youtube.com/watch?v=Onvlcl4e2IU > > [2] https://github.com/riscv/riscv-isa-manual/issues/402 > > This proposal has been posted in Privileged Spec Task Group, in > > https://lists.riscv.org/g/tech-privileged-archive/message/488?p=,,,20,0,0,0::Created,,Proposal,20,2,40,32306071 > > but never receive any feedback. > > [3] https://lists.riscv.org/g/tech-unixplatformspec/message/84 > > I intended to discuss [2] in the Unixplatform Spec Task Group at the > > online meeting, but obviously people were too busy knowing who the new > > RISC-V CTO is and what he has done to even follow the agenda. > > > > Sorry. The last meeting's agenda was derailed for numerous reasons. > Are you okay with discussing this during the next meeting ? > I have not scheduled one yet but will probably schedule it on next > Wednesday (8th July) if there is no objection. > I can check with Anup if he can present the SBI PMU extension as well. Thanks for the oppertunity. But I don't think that the time is enough for every important topic to be covered. What I provided in the previous citation [2] is a proposal, which need expert to judge and critique after thorough reading. The TG Chair should decide the priority of the items. If there is any chance for our proposal, I can give brief introductions. > > > > > _______________________________________________ > > linux-riscv mailing list > > linux-riscv@lists.infradead.org > > http://lists.infradead.org/mailman/listinfo/linux-riscv > > > > -- > Regards, > Atish _______________________________________________ linux-riscv mailing list linux-riscv@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-riscv ^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: [RFC PATCH 0/6] Support raw event and DT for perf on RISC-V 2020-07-01 0:51 ` Alan Kao 2020-07-01 1:02 ` Atish Patra @ 2020-07-01 3:15 ` Zong Li 2020-07-01 4:13 ` Anup Patel 2 siblings, 0 replies; 38+ messages in thread From: Zong Li @ 2020-07-01 3:15 UTC (permalink / raw) To: Alan Kao Cc: linux-riscv, Palmer Dabbelt, linux-kernel@vger.kernel.org List, Paul Walmsley On Wed, Jul 1, 2020 at 8:52 AM Alan Kao <alankao@andestech.com> wrote: > > On Mon, Jun 29, 2020 at 11:19:09AM +0800, Zong Li wrote: > > This patch set adds raw event support on RISC-V. In addition, we > > introduce the DT mechanism to make our perf more generic and common. > > > > Currently, we set the hardware events by writing the mhpmeventN CSRs, it > > would raise an illegal instruction exception and trap into m-mode to > > emulate event selector CSRs access. It doesn't make sense because we > > shouldn't write the m-mode CSRs in s-mode. Ideally, we should set event > > selector through standard SBI call or the shadow CSRs of s-mode. We have > > prepared a proposal of a new SBI extension, called "PMU SBI extension", > > but we also discussing the feasibility of accessing these PMU CSRs on > > s-mode at the same time, such as delegation mechanism, so I was > > wondering if we could use SBI calls first and make the PMU SBI extension > > as legacy when s-mode access mechanism is accepted by Foundation? or > > keep the current situation to see what would happen in the future. > > > > This patch set also introduces the DT mechanism, we don't want to add too > > much platform-dependency code in perf like other architectures, so we > > put the mapping of generic hardware events to DT, then we can easy to > > transfer generic hardware events to vendor's own hardware events without > > any platfrom-dependency stuff in our perf. > > > > Zong Li (6): > > dt-bindings: riscv: Add YAML documentation for PMU > > riscv: dts: sifive: Add DT support for PMU > > riscv: add definition of hpmcounter CSRs > > riscv: perf: Add raw event support > > riscv: perf: introduce DT mechanism > > riscv: remove PMU menu of Kconfig > > > > DT-based PMU registration looks good to me. Together with Anup's feedback, > we can anticipate that the following items will be: > > - rewrite RISC-V PMU to a platform driver > - propose SBI PMU extention > - fixes: RV32 counter access, namings, etc. > > Yes, all are good directions towards better counting (`perf stat`) function. > But as the original author of RISC-V perf port, please allow me to address > the fundamental problems of RISC-V perf, again [0][1][2][3], that the sampling > (`perf record`) function never earned enough respect. Counting gives you a > shallow view regarding an application, while sampling demystifies one for you. > > The problems are three-fold > (1) Interrupt > Sampling in perf requires that a HPM raises an interrupt when it overflows. > Making RISC-V perf platform driver or not has nothing to do with this. This > requires more discussions in TGs. > (2) S-mode access to PMU CSRs > This is also addressed in this patch set but to me, it is kind of like a > SBI-solves-them-all mindset to me. Perf event is for performance monitoring > thus we should eliminate any possible overhead if we can. Setting event masks > through SBI calls for counting maybe OK, but if we really take sampling and > interrupt handling into consideration, it is questionable if it is still a > viable way. > (3) Registers, registers, registers > There is just no enough CSR/function for perf sampling. The previous proposal > explains why [2]. > > Perf sampling is off-topic but somehow related, so I bring it up here just > for your information. > Agree, sampling is an important measurement for perf, we should integrate it to perf as soon as possible after overflow interrupt mechanism is standardized. > As this patch set goes v2, the PMU porting guide in [0] should be removed since > it contains no useful information anymore. > It seems that the document mentioned some hook functions, it is good for me to reserve this document, maybe we could try to give some modification. I would check that. Thanks > [0] Documentation/riscv/pmu.rst > [1] https://www.youtube.com/watch?v=Onvlcl4e2IU > [2] https://github.com/riscv/riscv-isa-manual/issues/402 > This proposal has been posted in Privileged Spec Task Group, in > https://lists.riscv.org/g/tech-privileged-archive/message/488?p=,,,20,0,0,0::Created,,Proposal,20,2,40,32306071 > but never receive any feedback. > [3] https://lists.riscv.org/g/tech-unixplatformspec/message/84 > I intended to discuss [2] in the Unixplatform Spec Task Group at the > online meeting, but obviously people were too busy knowing who the new > RISC-V CTO is and what he has done to even follow the agenda. > _______________________________________________ linux-riscv mailing list linux-riscv@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-riscv ^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: [RFC PATCH 0/6] Support raw event and DT for perf on RISC-V 2020-07-01 0:51 ` Alan Kao 2020-07-01 1:02 ` Atish Patra 2020-07-01 3:15 ` Zong Li @ 2020-07-01 4:13 ` Anup Patel 2 siblings, 0 replies; 38+ messages in thread From: Anup Patel @ 2020-07-01 4:13 UTC (permalink / raw) To: Alan Kao Cc: linux-riscv, Palmer Dabbelt, linux-kernel@vger.kernel.org List, Zong Li, Paul Walmsley On Wed, Jul 1, 2020 at 6:48 AM Alan Kao <alankao@andestech.com> wrote: > > On Mon, Jun 29, 2020 at 11:19:09AM +0800, Zong Li wrote: > > This patch set adds raw event support on RISC-V. In addition, we > > introduce the DT mechanism to make our perf more generic and common. > > > > Currently, we set the hardware events by writing the mhpmeventN CSRs, it > > would raise an illegal instruction exception and trap into m-mode to > > emulate event selector CSRs access. It doesn't make sense because we > > shouldn't write the m-mode CSRs in s-mode. Ideally, we should set event > > selector through standard SBI call or the shadow CSRs of s-mode. We have > > prepared a proposal of a new SBI extension, called "PMU SBI extension", > > but we also discussing the feasibility of accessing these PMU CSRs on > > s-mode at the same time, such as delegation mechanism, so I was > > wondering if we could use SBI calls first and make the PMU SBI extension > > as legacy when s-mode access mechanism is accepted by Foundation? or > > keep the current situation to see what would happen in the future. > > > > This patch set also introduces the DT mechanism, we don't want to add too > > much platform-dependency code in perf like other architectures, so we > > put the mapping of generic hardware events to DT, then we can easy to > > transfer generic hardware events to vendor's own hardware events without > > any platfrom-dependency stuff in our perf. > > > > Zong Li (6): > > dt-bindings: riscv: Add YAML documentation for PMU > > riscv: dts: sifive: Add DT support for PMU > > riscv: add definition of hpmcounter CSRs > > riscv: perf: Add raw event support > > riscv: perf: introduce DT mechanism > > riscv: remove PMU menu of Kconfig > > > > DT-based PMU registration looks good to me. Together with Anup's feedback, > we can anticipate that the following items will be: > > - rewrite RISC-V PMU to a platform driver > - propose SBI PMU extention > - fixes: RV32 counter access, namings, etc. > > Yes, all are good directions towards better counting (`perf stat`) function. > But as the original author of RISC-V perf port, please allow me to address > the fundamental problems of RISC-V perf, again [0][1][2][3], that the sampling > (`perf record`) function never earned enough respect. Counting gives you a > shallow view regarding an application, while sampling demystifies one for you. > > The problems are three-fold > (1) Interrupt > Sampling in perf requires that a HPM raises an interrupt when it overflows. > Making RISC-V perf platform driver or not has nothing to do with this. This > requires more discussions in TGs. > (2) S-mode access to PMU CSRs > This is also addressed in this patch set but to me, it is kind of like a > SBI-solves-them-all mindset to me. Perf event is for performance monitoring > thus we should eliminate any possible overhead if we can. Setting event masks > through SBI calls for counting maybe OK, but if we really take sampling and > interrupt handling into consideration, it is questionable if it is still a > viable way. Yes, we should certainly not have any SBI call for reading the PMU counter. The S-mode software should always have direct access to the actual counter value (i.e. CSR for HW counters and memory location for SBI specific counters). The SBI calls that we have been discussing here only deal with describing counters and configuring it. > (3) Registers, registers, registers > There is just no enough CSR/function for perf sampling. The previous proposal > explains why [2]. > > Perf sampling is off-topic but somehow related, so I bring it up here just > for your information. I agree with 1) and 2) limitations mentioned above. We certainly need a RISC-V PMU extension in RISC-V privilege spec. Maybe you can propose creating a working-group for this ?? My worry is that defining RISC-V PMU extension will take time and meanwhile more HW will show-up this year and next year which will have the same set of basic HPMCOUNTER CSRs. We are trying to brainstorm the best thing we can do when we have just HPMCOUNTER CSRs accessible to S-mode. The SBI PMU extension discussed here only tries to complement existing HPMCOUNTER CSRs so that SOC designers can at least provide implementation specific CSRs for configuring HW counters. The SBI PMU extension won't be able to solve the counter overflow detection so we will have to depend on software techniques to detect overflow. > > As this patch set goes v2, the PMU porting guide in [0] should be removed since > it contains no useful information anymore. I agree. This guide should be either updated or removed. > > [0] Documentation/riscv/pmu.rst > [1] https://www.youtube.com/watch?v=Onvlcl4e2IU > [2] https://github.com/riscv/riscv-isa-manual/issues/402 > This proposal has been posted in Privileged Spec Task Group, in > https://lists.riscv.org/g/tech-privileged-archive/message/488?p=,,,20,0,0,0::Created,,Proposal,20,2,40,32306071 > but never receive any feedback. > [3] https://lists.riscv.org/g/tech-unixplatformspec/message/84 > I intended to discuss [2] in the Unixplatform Spec Task Group at the > online meeting, but obviously people were too busy knowing who the new > RISC-V CTO is and what he has done to even follow the agenda. > Regards, Anup _______________________________________________ linux-riscv mailing list linux-riscv@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-riscv ^ permalink raw reply [flat|nested] 38+ messages in thread
end of thread, other threads:[~2020-07-01 11:44 UTC | newest] Thread overview: 38+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2020-06-29 3:19 [RFC PATCH 0/6] Support raw event and DT for perf on RISC-V Zong Li 2020-06-29 3:19 ` [RFC PATCH 1/6] dt-bindings: riscv: Add YAML documentation for PMU Zong Li 2020-06-29 4:09 ` Anup Patel 2020-06-29 4:28 ` Zong Li 2020-06-29 4:37 ` Anup Patel 2020-06-29 6:35 ` Zong Li 2020-06-29 8:31 ` Anup Patel 2020-07-01 3:22 ` Zong Li 2020-06-29 3:19 ` [RFC PATCH 2/6] riscv: dts: sifive: Add DT support " Zong Li 2020-06-29 3:19 ` [RFC PATCH 3/6] riscv: add definition of hpmcounter CSRs Zong Li 2020-06-29 3:19 ` [RFC PATCH 4/6] riscv: perf: Add raw event support Zong Li 2020-06-29 4:17 ` Anup Patel 2020-06-29 4:35 ` Zong Li 2020-06-29 4:40 ` Anup Patel 2020-06-29 3:19 ` [RFC PATCH 5/6] riscv: perf: introduce DT mechanism Zong Li 2020-06-29 4:36 ` Anup Patel 2020-06-29 6:26 ` Zong Li 2020-06-29 3:19 ` [RFC PATCH 6/6] riscv: remove PMU menu of Kconfig Zong Li 2020-06-29 4:52 ` [RFC PATCH 0/6] Support raw event and DT for perf on RISC-V Anup Patel 2020-06-29 5:52 ` Zong Li 2020-06-29 8:27 ` Anup Patel 2020-06-29 12:53 ` Zong Li 2020-06-29 13:23 ` Anup Patel 2020-06-30 6:37 ` Zong Li 2020-06-30 7:39 ` Anup Patel 2020-06-30 8:04 ` Zong Li 2020-06-30 10:18 ` Anup Patel 2020-06-30 11:38 ` Anup Patel 2020-06-30 18:57 ` Atish Patra 2020-07-01 2:14 ` Zong Li 2020-07-01 11:43 ` Anup Patel 2020-07-01 2:11 ` Zong Li 2020-07-01 1:55 ` Zong Li 2020-07-01 0:51 ` Alan Kao 2020-07-01 1:02 ` Atish Patra 2020-07-01 2:45 ` Alan Kao 2020-07-01 3:15 ` Zong Li 2020-07-01 4:13 ` Anup Patel
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).