riscv now supports mmaping hardware counters so add what's needed to
take advantage of that in libperf.
Signed-off-by: Alexandre Ghiti <[email protected]>
Reviewed-by: Andrew Jones <[email protected]>
Reviewed-by: Atish Patra <[email protected]>
---
tools/lib/perf/mmap.c | 66 +++++++++++++++++++++++++++++++++++++++++++
1 file changed, 66 insertions(+)
diff --git a/tools/lib/perf/mmap.c b/tools/lib/perf/mmap.c
index 0d1634cedf44..2184814b37dd 100644
--- a/tools/lib/perf/mmap.c
+++ b/tools/lib/perf/mmap.c
@@ -392,6 +392,72 @@ static u64 read_perf_counter(unsigned int counter)
static u64 read_timestamp(void) { return read_sysreg(cntvct_el0); }
+/* __riscv_xlen contains the witdh of the native base integer, here 64-bit */
+#elif defined(__riscv) && __riscv_xlen == 64
+
+/* TODO: implement rv32 support */
+
+#define CSR_CYCLE 0xc00
+#define CSR_TIME 0xc01
+
+#define csr_read(csr) \
+({ \
+ register unsigned long __v; \
+ __asm__ __volatile__ ("csrr %0, %1" \
+ : "=r" (__v) \
+ : "i" (csr) : ); \
+ __v; \
+})
+
+static unsigned long csr_read_num(int csr_num)
+{
+#define switchcase_csr_read(__csr_num, __val) {\
+ case __csr_num: \
+ __val = csr_read(__csr_num); \
+ break; }
+#define switchcase_csr_read_2(__csr_num, __val) {\
+ switchcase_csr_read(__csr_num + 0, __val) \
+ switchcase_csr_read(__csr_num + 1, __val)}
+#define switchcase_csr_read_4(__csr_num, __val) {\
+ switchcase_csr_read_2(__csr_num + 0, __val) \
+ switchcase_csr_read_2(__csr_num + 2, __val)}
+#define switchcase_csr_read_8(__csr_num, __val) {\
+ switchcase_csr_read_4(__csr_num + 0, __val) \
+ switchcase_csr_read_4(__csr_num + 4, __val)}
+#define switchcase_csr_read_16(__csr_num, __val) {\
+ switchcase_csr_read_8(__csr_num + 0, __val) \
+ switchcase_csr_read_8(__csr_num + 8, __val)}
+#define switchcase_csr_read_32(__csr_num, __val) {\
+ switchcase_csr_read_16(__csr_num + 0, __val) \
+ switchcase_csr_read_16(__csr_num + 16, __val)}
+
+ unsigned long ret = 0;
+
+ switch (csr_num) {
+ switchcase_csr_read_32(CSR_CYCLE, ret)
+ default:
+ break;
+ }
+
+ return ret;
+#undef switchcase_csr_read_32
+#undef switchcase_csr_read_16
+#undef switchcase_csr_read_8
+#undef switchcase_csr_read_4
+#undef switchcase_csr_read_2
+#undef switchcase_csr_read
+}
+
+static u64 read_perf_counter(unsigned int counter)
+{
+ return csr_read_num(CSR_CYCLE + counter);
+}
+
+static u64 read_timestamp(void)
+{
+ return csr_read_num(CSR_TIME);
+}
+
#else
static u64 read_perf_counter(unsigned int counter __maybe_unused) { return 0; }
static u64 read_timestamp(void) { return 0; }
--
2.39.2
On Wed, Aug 02, 2023 at 10:03:27AM +0200, Alexandre Ghiti wrote:
> riscv now supports mmaping hardware counters so add what's needed to
> take advantage of that in libperf.
>
> Signed-off-by: Alexandre Ghiti <[email protected]>
> Reviewed-by: Andrew Jones <[email protected]>
> Reviewed-by: Atish Patra <[email protected]>
> ---
> tools/lib/perf/mmap.c | 66 +++++++++++++++++++++++++++++++++++++++++++
> 1 file changed, 66 insertions(+)
>
> diff --git a/tools/lib/perf/mmap.c b/tools/lib/perf/mmap.c
> index 0d1634cedf44..2184814b37dd 100644
> --- a/tools/lib/perf/mmap.c
> +++ b/tools/lib/perf/mmap.c
> @@ -392,6 +392,72 @@ static u64 read_perf_counter(unsigned int counter)
>
> static u64 read_timestamp(void) { return read_sysreg(cntvct_el0); }
>
> +/* __riscv_xlen contains the witdh of the native base integer, here 64-bit */
> +#elif defined(__riscv) && __riscv_xlen == 64
> +
> +/* TODO: implement rv32 support */
> +
> +#define CSR_CYCLE 0xc00
> +#define CSR_TIME 0xc01
> +
> +#define csr_read(csr) \
> +({ \
> + register unsigned long __v; \
> + __asm__ __volatile__ ("csrr %0, %1" \
> + : "=r" (__v) \
> + : "i" (csr) : ); \
> + __v; \
nit: no need for the indentation or line wrap,
({
register unsigned long __v;
__asm__ __volatile__ ("csrr %0, %1" : "=r" (__v) : "i" (csr));
__v;
})
Thanks,
drew
On Wed, Aug 02, 2023 at 10:03:27AM +0200, Alexandre Ghiti wrote:
> riscv now supports mmaping hardware counters so add what's needed to
> take advantage of that in libperf.
>
> Signed-off-by: Alexandre Ghiti <[email protected]>
> Reviewed-by: Andrew Jones <[email protected]>
> Reviewed-by: Atish Patra <[email protected]>
> ---
> tools/lib/perf/mmap.c | 66 +++++++++++++++++++++++++++++++++++++++++++
> 1 file changed, 66 insertions(+)
>
> diff --git a/tools/lib/perf/mmap.c b/tools/lib/perf/mmap.c
> index 0d1634cedf44..2184814b37dd 100644
> --- a/tools/lib/perf/mmap.c
> +++ b/tools/lib/perf/mmap.c
> @@ -392,6 +392,72 @@ static u64 read_perf_counter(unsigned int counter)
>
> static u64 read_timestamp(void) { return read_sysreg(cntvct_el0); }
>
> +/* __riscv_xlen contains the witdh of the native base integer, here 64-bit */
> +#elif defined(__riscv) && __riscv_xlen == 64
> +
> +/* TODO: implement rv32 support */
It'd be easy to implement the rv32 support now (even if it's premature for
use), in order to avoid the TODO (which will likely be forgotten). I think
we just need to drop the __riscv_xlen == 64 above and then extend the
csr_read() macro something like the untested code below. (I'm not sure if
a TODO or premature, likely untested, code is worse though.)
> +
> +#define CSR_CYCLE 0xc00
> +#define CSR_TIME 0xc01
> +
> +#define csr_read(csr) \
> +({ \
u64 __value;
> + register unsigned long __v; \
> + __asm__ __volatile__ ("csrr %0, %1" \
> + : "=r" (__v) \
> + : "i" (csr) : ); \
__value = __v;
#if __riscv_xlen == 32
{
int csrh = (csr) - CSR_CYCLE + CSR_CYCLEH;
__asm__ __volatile__ ("csrr %0, %1" : "=r" (__v) : "i" (csrh));
__value |= (u64)__v << 32;
}
#endif
__value;
> +})
> +
> +static unsigned long csr_read_num(int csr_num)
static u64 csr_read_num(int csr_num)
> +{
> +#define switchcase_csr_read(__csr_num, __val) {\
> + case __csr_num: \
> + __val = csr_read(__csr_num); \
> + break; }
> +#define switchcase_csr_read_2(__csr_num, __val) {\
> + switchcase_csr_read(__csr_num + 0, __val) \
> + switchcase_csr_read(__csr_num + 1, __val)}
> +#define switchcase_csr_read_4(__csr_num, __val) {\
> + switchcase_csr_read_2(__csr_num + 0, __val) \
> + switchcase_csr_read_2(__csr_num + 2, __val)}
> +#define switchcase_csr_read_8(__csr_num, __val) {\
> + switchcase_csr_read_4(__csr_num + 0, __val) \
> + switchcase_csr_read_4(__csr_num + 4, __val)}
> +#define switchcase_csr_read_16(__csr_num, __val) {\
> + switchcase_csr_read_8(__csr_num + 0, __val) \
> + switchcase_csr_read_8(__csr_num + 8, __val)}
> +#define switchcase_csr_read_32(__csr_num, __val) {\
> + switchcase_csr_read_16(__csr_num + 0, __val) \
> + switchcase_csr_read_16(__csr_num + 16, __val)}
> +
> + unsigned long ret = 0;
> +
> + switch (csr_num) {
> + switchcase_csr_read_32(CSR_CYCLE, ret)
> + default:
> + break;
> + }
> +
> + return ret;
> +#undef switchcase_csr_read_32
> +#undef switchcase_csr_read_16
> +#undef switchcase_csr_read_8
> +#undef switchcase_csr_read_4
> +#undef switchcase_csr_read_2
> +#undef switchcase_csr_read
> +}
> +
> +static u64 read_perf_counter(unsigned int counter)
> +{
> + return csr_read_num(CSR_CYCLE + counter);
> +}
> +
> +static u64 read_timestamp(void)
> +{
> + return csr_read_num(CSR_TIME);
> +}
> +
> #else
> static u64 read_perf_counter(unsigned int counter __maybe_unused) { return 0; }
> static u64 read_timestamp(void) { return 0; }
> --
> 2.39.2
>
Thanks,
drew
Hi Andrew,
On Wed, Aug 2, 2023 at 11:32 AM Andrew Jones <[email protected]> wrote:
>
> On Wed, Aug 02, 2023 at 10:03:27AM +0200, Alexandre Ghiti wrote:
> > riscv now supports mmaping hardware counters so add what's needed to
> > take advantage of that in libperf.
> >
> > Signed-off-by: Alexandre Ghiti <[email protected]>
> > Reviewed-by: Andrew Jones <[email protected]>
> > Reviewed-by: Atish Patra <[email protected]>
> > ---
> > tools/lib/perf/mmap.c | 66 +++++++++++++++++++++++++++++++++++++++++++
> > 1 file changed, 66 insertions(+)
> >
> > diff --git a/tools/lib/perf/mmap.c b/tools/lib/perf/mmap.c
> > index 0d1634cedf44..2184814b37dd 100644
> > --- a/tools/lib/perf/mmap.c
> > +++ b/tools/lib/perf/mmap.c
> > @@ -392,6 +392,72 @@ static u64 read_perf_counter(unsigned int counter)
> >
> > static u64 read_timestamp(void) { return read_sysreg(cntvct_el0); }
> >
> > +/* __riscv_xlen contains the witdh of the native base integer, here 64-bit */
> > +#elif defined(__riscv) && __riscv_xlen == 64
> > +
> > +/* TODO: implement rv32 support */
> > +
> > +#define CSR_CYCLE 0xc00
> > +#define CSR_TIME 0xc01
> > +
> > +#define csr_read(csr) \
> > +({ \
> > + register unsigned long __v; \
> > + __asm__ __volatile__ ("csrr %0, %1" \
> > + : "=r" (__v) \
> > + : "i" (csr) : ); \
> > + __v; \
>
> nit: no need for the indentation or line wrap,
>
> ({
> register unsigned long __v;
> __asm__ __volatile__ ("csrr %0, %1" : "=r" (__v) : "i" (csr));
> __v;
> })
>
> Thanks,
> drew
Sorry I didn't answer sooner, I was busy finishing everything before
my holidays :) I won't have time to implement what you proposed, and
more importantly I don't have a setup for rv32 to test quickly. I'll
let Palmer decide if we can keep the TODO so that someone can do that
later on top of this series.
Thanks anyway for your reviews!
Alex
Em Mon, Aug 14, 2023 at 09:44:29AM -0700, Ian Rogers escreveu:
> On Wed, Aug 2, 2023 at 1:13 AM Alexandre Ghiti <[email protected]> wrote:
> >
> > riscv now supports mmaping hardware counters so add what's needed to
> > take advantage of that in libperf.
> >
> > Signed-off-by: Alexandre Ghiti <[email protected]>
> > Reviewed-by: Andrew Jones <[email protected]>
> > Reviewed-by: Atish Patra <[email protected]>
>
> Reviewed-by: Ian Rogers <[email protected]>
Thanks, applied.
- Arnaldo
> Thanks,
> Ian
>
> > ---
> > tools/lib/perf/mmap.c | 66 +++++++++++++++++++++++++++++++++++++++++++
> > 1 file changed, 66 insertions(+)
> >
> > diff --git a/tools/lib/perf/mmap.c b/tools/lib/perf/mmap.c
> > index 0d1634cedf44..2184814b37dd 100644
> > --- a/tools/lib/perf/mmap.c
> > +++ b/tools/lib/perf/mmap.c
> > @@ -392,6 +392,72 @@ static u64 read_perf_counter(unsigned int counter)
> >
> > static u64 read_timestamp(void) { return read_sysreg(cntvct_el0); }
> >
> > +/* __riscv_xlen contains the witdh of the native base integer, here 64-bit */
> > +#elif defined(__riscv) && __riscv_xlen == 64
> > +
> > +/* TODO: implement rv32 support */
> > +
> > +#define CSR_CYCLE 0xc00
> > +#define CSR_TIME 0xc01
> > +
> > +#define csr_read(csr) \
> > +({ \
> > + register unsigned long __v; \
> > + __asm__ __volatile__ ("csrr %0, %1" \
> > + : "=r" (__v) \
> > + : "i" (csr) : ); \
> > + __v; \
> > +})
> > +
> > +static unsigned long csr_read_num(int csr_num)
> > +{
> > +#define switchcase_csr_read(__csr_num, __val) {\
> > + case __csr_num: \
> > + __val = csr_read(__csr_num); \
> > + break; }
> > +#define switchcase_csr_read_2(__csr_num, __val) {\
> > + switchcase_csr_read(__csr_num + 0, __val) \
> > + switchcase_csr_read(__csr_num + 1, __val)}
> > +#define switchcase_csr_read_4(__csr_num, __val) {\
> > + switchcase_csr_read_2(__csr_num + 0, __val) \
> > + switchcase_csr_read_2(__csr_num + 2, __val)}
> > +#define switchcase_csr_read_8(__csr_num, __val) {\
> > + switchcase_csr_read_4(__csr_num + 0, __val) \
> > + switchcase_csr_read_4(__csr_num + 4, __val)}
> > +#define switchcase_csr_read_16(__csr_num, __val) {\
> > + switchcase_csr_read_8(__csr_num + 0, __val) \
> > + switchcase_csr_read_8(__csr_num + 8, __val)}
> > +#define switchcase_csr_read_32(__csr_num, __val) {\
> > + switchcase_csr_read_16(__csr_num + 0, __val) \
> > + switchcase_csr_read_16(__csr_num + 16, __val)}
> > +
> > + unsigned long ret = 0;
> > +
> > + switch (csr_num) {
> > + switchcase_csr_read_32(CSR_CYCLE, ret)
> > + default:
> > + break;
> > + }
> > +
> > + return ret;
> > +#undef switchcase_csr_read_32
> > +#undef switchcase_csr_read_16
> > +#undef switchcase_csr_read_8
> > +#undef switchcase_csr_read_4
> > +#undef switchcase_csr_read_2
> > +#undef switchcase_csr_read
> > +}
> > +
> > +static u64 read_perf_counter(unsigned int counter)
> > +{
> > + return csr_read_num(CSR_CYCLE + counter);
> > +}
> > +
> > +static u64 read_timestamp(void)
> > +{
> > + return csr_read_num(CSR_TIME);
> > +}
> > +
> > #else
> > static u64 read_perf_counter(unsigned int counter __maybe_unused) { return 0; }
> > static u64 read_timestamp(void) { return 0; }
> > --
> > 2.39.2
> >
--
- Arnaldo