* [PATCH v2] riscv: Add tracepoints for SBI calls and returns
@ 2024-03-21 23:01 Samuel Holland
2024-03-22 9:27 ` Alexandre Ghiti
` (2 more replies)
0 siblings, 3 replies; 7+ messages in thread
From: Samuel Holland @ 2024-03-21 23:01 UTC (permalink / raw)
To: Palmer Dabbelt, linux-riscv
Cc: Samuel Holland, Andrew Jones, Albert Ou, Alexandre Ghiti,
Anup Patel, Marc Zyngier, Paul Walmsley, linux-kernel
These are useful for measuring the latency of SBI calls. The SBI HSM
extension is excluded because those functions are called from contexts
such as cpuidle where instrumentation is not allowed.
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
Signed-off-by: Samuel Holland <samuel.holland@sifive.com>
---
Changes in v2:
- Remove some blank lines
arch/riscv/include/asm/trace.h | 54 ++++++++++++++++++++++++++++++++++
arch/riscv/kernel/sbi.c | 7 +++++
2 files changed, 61 insertions(+)
create mode 100644 arch/riscv/include/asm/trace.h
diff --git a/arch/riscv/include/asm/trace.h b/arch/riscv/include/asm/trace.h
new file mode 100644
index 000000000000..6151cee5450c
--- /dev/null
+++ b/arch/riscv/include/asm/trace.h
@@ -0,0 +1,54 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM riscv
+
+#if !defined(_TRACE_RISCV_H) || defined(TRACE_HEADER_MULTI_READ)
+#define _TRACE_RISCV_H
+
+#include <linux/tracepoint.h>
+
+TRACE_EVENT_CONDITION(sbi_call,
+ TP_PROTO(int ext, int fid),
+ TP_ARGS(ext, fid),
+ TP_CONDITION(ext != SBI_EXT_HSM),
+
+ TP_STRUCT__entry(
+ __field(int, ext)
+ __field(int, fid)
+ ),
+
+ TP_fast_assign(
+ __entry->ext = ext;
+ __entry->fid = fid;
+ ),
+
+ TP_printk("ext=0x%x fid=%d", __entry->ext, __entry->fid)
+);
+
+TRACE_EVENT_CONDITION(sbi_return,
+ TP_PROTO(int ext, long error, long value),
+ TP_ARGS(ext, error, value),
+ TP_CONDITION(ext != SBI_EXT_HSM),
+
+ TP_STRUCT__entry(
+ __field(long, error)
+ __field(long, value)
+ ),
+
+ TP_fast_assign(
+ __entry->error = error;
+ __entry->value = value;
+ ),
+
+ TP_printk("error=%ld value=0x%lx", __entry->error, __entry->value)
+);
+
+#endif /* _TRACE_RISCV_H */
+
+#undef TRACE_INCLUDE_PATH
+#undef TRACE_INCLUDE_FILE
+
+#define TRACE_INCLUDE_PATH asm
+#define TRACE_INCLUDE_FILE trace
+
+#include <trace/define_trace.h>
diff --git a/arch/riscv/kernel/sbi.c b/arch/riscv/kernel/sbi.c
index e66e0999a800..a1d21d8f5293 100644
--- a/arch/riscv/kernel/sbi.c
+++ b/arch/riscv/kernel/sbi.c
@@ -14,6 +14,9 @@
#include <asm/smp.h>
#include <asm/tlbflush.h>
+#define CREATE_TRACE_POINTS
+#include <asm/trace.h>
+
/* default SBI version is 0.1 */
unsigned long sbi_spec_version __ro_after_init = SBI_SPEC_VERSION_DEFAULT;
EXPORT_SYMBOL(sbi_spec_version);
@@ -31,6 +34,8 @@ struct sbiret sbi_ecall(int ext, int fid, unsigned long arg0,
{
struct sbiret ret;
+ trace_sbi_call(ext, fid);
+
register uintptr_t a0 asm ("a0") = (uintptr_t)(arg0);
register uintptr_t a1 asm ("a1") = (uintptr_t)(arg1);
register uintptr_t a2 asm ("a2") = (uintptr_t)(arg2);
@@ -46,6 +51,8 @@ struct sbiret sbi_ecall(int ext, int fid, unsigned long arg0,
ret.error = a0;
ret.value = a1;
+ trace_sbi_return(ext, ret.error, ret.value);
+
return ret;
}
EXPORT_SYMBOL(sbi_ecall);
--
2.43.1
^ permalink raw reply related [flat|nested] 7+ messages in thread* Re: [PATCH v2] riscv: Add tracepoints for SBI calls and returns 2024-03-21 23:01 [PATCH v2] riscv: Add tracepoints for SBI calls and returns Samuel Holland @ 2024-03-22 9:27 ` Alexandre Ghiti 2024-03-26 3:39 ` Samuel Holland 2024-07-12 10:20 ` patchwork-bot+linux-riscv 2024-08-13 20:26 ` Conor Dooley 2 siblings, 1 reply; 7+ messages in thread From: Alexandre Ghiti @ 2024-03-22 9:27 UTC (permalink / raw) To: Samuel Holland Cc: Palmer Dabbelt, linux-riscv, Andrew Jones, Albert Ou, Anup Patel, Marc Zyngier, Paul Walmsley, linux-kernel Hi Samuel, On Fri, Mar 22, 2024 at 12:01 AM Samuel Holland <samuel.holland@sifive.com> wrote: > > These are useful for measuring the latency of SBI calls. The SBI HSM > extension is excluded because those functions are called from contexts > such as cpuidle where instrumentation is not allowed. > > Reviewed-by: Andrew Jones <ajones@ventanamicro.com> > Signed-off-by: Samuel Holland <samuel.holland@sifive.com> > --- > > Changes in v2: > - Remove some blank lines > > arch/riscv/include/asm/trace.h | 54 ++++++++++++++++++++++++++++++++++ > arch/riscv/kernel/sbi.c | 7 +++++ > 2 files changed, 61 insertions(+) > create mode 100644 arch/riscv/include/asm/trace.h > > diff --git a/arch/riscv/include/asm/trace.h b/arch/riscv/include/asm/trace.h > new file mode 100644 > index 000000000000..6151cee5450c > --- /dev/null > +++ b/arch/riscv/include/asm/trace.h > @@ -0,0 +1,54 @@ > +/* SPDX-License-Identifier: GPL-2.0 */ > +#undef TRACE_SYSTEM > +#define TRACE_SYSTEM riscv > + > +#if !defined(_TRACE_RISCV_H) || defined(TRACE_HEADER_MULTI_READ) > +#define _TRACE_RISCV_H > + > +#include <linux/tracepoint.h> > + > +TRACE_EVENT_CONDITION(sbi_call, > + TP_PROTO(int ext, int fid), > + TP_ARGS(ext, fid), > + TP_CONDITION(ext != SBI_EXT_HSM), > + > + TP_STRUCT__entry( > + __field(int, ext) > + __field(int, fid) > + ), > + > + TP_fast_assign( > + __entry->ext = ext; > + __entry->fid = fid; > + ), > + > + TP_printk("ext=0x%x fid=%d", __entry->ext, __entry->fid) > +); > + > +TRACE_EVENT_CONDITION(sbi_return, > + TP_PROTO(int ext, long error, long value), > + TP_ARGS(ext, error, value), > + TP_CONDITION(ext != SBI_EXT_HSM), > + > + TP_STRUCT__entry( > + __field(long, error) > + __field(long, value) > + ), > + > + TP_fast_assign( > + __entry->error = error; > + __entry->value = value; > + ), > + > + TP_printk("error=%ld value=0x%lx", __entry->error, __entry->value) > +); > + > +#endif /* _TRACE_RISCV_H */ > + > +#undef TRACE_INCLUDE_PATH > +#undef TRACE_INCLUDE_FILE > + > +#define TRACE_INCLUDE_PATH asm > +#define TRACE_INCLUDE_FILE trace > + > +#include <trace/define_trace.h> > diff --git a/arch/riscv/kernel/sbi.c b/arch/riscv/kernel/sbi.c > index e66e0999a800..a1d21d8f5293 100644 > --- a/arch/riscv/kernel/sbi.c > +++ b/arch/riscv/kernel/sbi.c > @@ -14,6 +14,9 @@ > #include <asm/smp.h> > #include <asm/tlbflush.h> > > +#define CREATE_TRACE_POINTS > +#include <asm/trace.h> > + > /* default SBI version is 0.1 */ > unsigned long sbi_spec_version __ro_after_init = SBI_SPEC_VERSION_DEFAULT; > EXPORT_SYMBOL(sbi_spec_version); > @@ -31,6 +34,8 @@ struct sbiret sbi_ecall(int ext, int fid, unsigned long arg0, > { > struct sbiret ret; > > + trace_sbi_call(ext, fid); > + > register uintptr_t a0 asm ("a0") = (uintptr_t)(arg0); > register uintptr_t a1 asm ("a1") = (uintptr_t)(arg1); > register uintptr_t a2 asm ("a2") = (uintptr_t)(arg2); > @@ -46,6 +51,8 @@ struct sbiret sbi_ecall(int ext, int fid, unsigned long arg0, > ret.error = a0; > ret.value = a1; > > + trace_sbi_return(ext, ret.error, ret.value); > + > return ret; > } > EXPORT_SYMBOL(sbi_ecall); > -- > 2.43.1 > sbi_ecall() is used by flush_icache_all() so I was a bit scared we would need to patch 2 instructions using a tracepoint and then to use flush_icache_all() which could bug if only one of the patched instruction was seen. But I took a look at the disassembled code, and tracepoints happen to only need to patch 1 nop into an unconditional jump, which is not a problem then. But then when disassembling, I noticed that the addition of the tracepoint comes with "quite" some overhead: Before: Dump of assembler code for function sbi_ecall: 0xffffffff800085e0 <+0>: add sp,sp,-32 0xffffffff800085e2 <+2>: sd s0,24(sp) 0xffffffff800085e4 <+4>: mv t1,a0 0xffffffff800085e6 <+6>: add s0,sp,32 0xffffffff800085e8 <+8>: mv t3,a1 0xffffffff800085ea <+10>: mv a0,a2 0xffffffff800085ec <+12>: mv a1,a3 0xffffffff800085ee <+14>: mv a2,a4 0xffffffff800085f0 <+16>: mv a3,a5 0xffffffff800085f2 <+18>: mv a4,a6 0xffffffff800085f4 <+20>: mv a5,a7 0xffffffff800085f6 <+22>: mv a6,t3 0xffffffff800085f8 <+24>: mv a7,t1 0xffffffff800085fa <+26>: ecall 0xffffffff800085fe <+30>: ld s0,24(sp) 0xffffffff80008600 <+32>: add sp,sp,32 0xffffffff80008602 <+34>: ret After: Dump of assembler code for function sbi_ecall: 0xffffffff8000bbf2 <+0>: add sp,sp,-112 0xffffffff8000bbf4 <+2>: sd s0,96(sp) 0xffffffff8000bbf6 <+4>: sd s1,88(sp) 0xffffffff8000bbf8 <+6>: sd s3,72(sp) 0xffffffff8000bbfa <+8>: sd s4,64(sp) 0xffffffff8000bbfc <+10>: sd s5,56(sp) 0xffffffff8000bbfe <+12>: sd s6,48(sp) 0xffffffff8000bc00 <+14>: sd s7,40(sp) 0xffffffff8000bc02 <+16>: sd s8,32(sp) 0xffffffff8000bc04 <+18>: sd s9,24(sp) 0xffffffff8000bc06 <+20>: sd ra,104(sp) 0xffffffff8000bc08 <+22>: sd s2,80(sp) 0xffffffff8000bc0a <+24>: add s0,sp,112 0xffffffff8000bc0c <+26>: mv s1,a0 0xffffffff8000bc0e <+28>: mv s3,a1 0xffffffff8000bc10 <+30>: mv s9,a2 0xffffffff8000bc12 <+32>: mv s8,a3 0xffffffff8000bc14 <+34>: mv s7,a4 0xffffffff8000bc16 <+36>: mv s6,a5 0xffffffff8000bc18 <+38>: mv s5,a6 0xffffffff8000bc1a <+40>: mv s4,a7 0xffffffff8000bc1c <+42>: nop 0xffffffff8000bc20 <+46>: mv a0,s9 0xffffffff8000bc22 <+48>: mv a1,s8 0xffffffff8000bc24 <+50>: mv a2,s7 0xffffffff8000bc26 <+52>: mv a3,s6 0xffffffff8000bc28 <+54>: mv a4,s5 0xffffffff8000bc2a <+56>: mv a5,s4 0xffffffff8000bc2c <+58>: mv a6,s3 0xffffffff8000bc2e <+60>: mv a7,s1 0xffffffff8000bc30 <+62>: ecall 0xffffffff8000bc34 <+66>: mv s4,a0 0xffffffff8000bc36 <+68>: mv s3,a1 0xffffffff8000bc38 <+70>: nop 0xffffffff8000bc3c <+74>: ld ra,104(sp) 0xffffffff8000bc3e <+76>: ld s0,96(sp) 0xffffffff8000bc40 <+78>: ld s1,88(sp) 0xffffffff8000bc42 <+80>: ld s2,80(sp) 0xffffffff8000bc44 <+82>: ld s5,56(sp) 0xffffffff8000bc46 <+84>: ld s6,48(sp) 0xffffffff8000bc48 <+86>: ld s7,40(sp) 0xffffffff8000bc4a <+88>: ld s8,32(sp) 0xffffffff8000bc4c <+90>: ld s9,24(sp) 0xffffffff8000bc4e <+92>: mv a0,s4 0xffffffff8000bc50 <+94>: mv a1,s3 0xffffffff8000bc52 <+96>: ld s4,64(sp) 0xffffffff8000bc54 <+98>: ld s3,72(sp) 0xffffffff8000bc56 <+100>: add sp,sp,112 0xffffffff8000bc58 <+102>: ret Not sure this is really problematic though, let me know what you think. FYI, I'm about to send a patch to reorder the arguments of sbi_ecall() to avoid the mv-dance before the ecall. Thanks, Alex ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH v2] riscv: Add tracepoints for SBI calls and returns 2024-03-22 9:27 ` Alexandre Ghiti @ 2024-03-26 3:39 ` Samuel Holland 2024-07-10 20:29 ` Palmer Dabbelt 0 siblings, 1 reply; 7+ messages in thread From: Samuel Holland @ 2024-03-26 3:39 UTC (permalink / raw) To: Alexandre Ghiti Cc: Palmer Dabbelt, linux-riscv, Andrew Jones, Albert Ou, Anup Patel, Marc Zyngier, Paul Walmsley, linux-kernel Hi Alex, On 2024-03-22 4:27 AM, Alexandre Ghiti wrote: > On Fri, Mar 22, 2024 at 12:01 AM Samuel Holland > <samuel.holland@sifive.com> wrote: >> >> These are useful for measuring the latency of SBI calls. The SBI HSM >> extension is excluded because those functions are called from contexts >> such as cpuidle where instrumentation is not allowed. >> >> Reviewed-by: Andrew Jones <ajones@ventanamicro.com> >> Signed-off-by: Samuel Holland <samuel.holland@sifive.com> >> --- >> >> Changes in v2: >> - Remove some blank lines >> >> arch/riscv/include/asm/trace.h | 54 ++++++++++++++++++++++++++++++++++ >> arch/riscv/kernel/sbi.c | 7 +++++ >> 2 files changed, 61 insertions(+) >> create mode 100644 arch/riscv/include/asm/trace.h >> >> diff --git a/arch/riscv/include/asm/trace.h b/arch/riscv/include/asm/trace.h >> new file mode 100644 >> index 000000000000..6151cee5450c >> --- /dev/null >> +++ b/arch/riscv/include/asm/trace.h >> @@ -0,0 +1,54 @@ >> +/* SPDX-License-Identifier: GPL-2.0 */ >> +#undef TRACE_SYSTEM >> +#define TRACE_SYSTEM riscv >> + >> +#if !defined(_TRACE_RISCV_H) || defined(TRACE_HEADER_MULTI_READ) >> +#define _TRACE_RISCV_H >> + >> +#include <linux/tracepoint.h> >> + >> +TRACE_EVENT_CONDITION(sbi_call, >> + TP_PROTO(int ext, int fid), >> + TP_ARGS(ext, fid), >> + TP_CONDITION(ext != SBI_EXT_HSM), >> + >> + TP_STRUCT__entry( >> + __field(int, ext) >> + __field(int, fid) >> + ), >> + >> + TP_fast_assign( >> + __entry->ext = ext; >> + __entry->fid = fid; >> + ), >> + >> + TP_printk("ext=0x%x fid=%d", __entry->ext, __entry->fid) >> +); >> + >> +TRACE_EVENT_CONDITION(sbi_return, >> + TP_PROTO(int ext, long error, long value), >> + TP_ARGS(ext, error, value), >> + TP_CONDITION(ext != SBI_EXT_HSM), >> + >> + TP_STRUCT__entry( >> + __field(long, error) >> + __field(long, value) >> + ), >> + >> + TP_fast_assign( >> + __entry->error = error; >> + __entry->value = value; >> + ), >> + >> + TP_printk("error=%ld value=0x%lx", __entry->error, __entry->value) >> +); >> + >> +#endif /* _TRACE_RISCV_H */ >> + >> +#undef TRACE_INCLUDE_PATH >> +#undef TRACE_INCLUDE_FILE >> + >> +#define TRACE_INCLUDE_PATH asm >> +#define TRACE_INCLUDE_FILE trace >> + >> +#include <trace/define_trace.h> >> diff --git a/arch/riscv/kernel/sbi.c b/arch/riscv/kernel/sbi.c >> index e66e0999a800..a1d21d8f5293 100644 >> --- a/arch/riscv/kernel/sbi.c >> +++ b/arch/riscv/kernel/sbi.c >> @@ -14,6 +14,9 @@ >> #include <asm/smp.h> >> #include <asm/tlbflush.h> >> >> +#define CREATE_TRACE_POINTS >> +#include <asm/trace.h> >> + >> /* default SBI version is 0.1 */ >> unsigned long sbi_spec_version __ro_after_init = SBI_SPEC_VERSION_DEFAULT; >> EXPORT_SYMBOL(sbi_spec_version); >> @@ -31,6 +34,8 @@ struct sbiret sbi_ecall(int ext, int fid, unsigned long arg0, >> { >> struct sbiret ret; >> >> + trace_sbi_call(ext, fid); >> + >> register uintptr_t a0 asm ("a0") = (uintptr_t)(arg0); >> register uintptr_t a1 asm ("a1") = (uintptr_t)(arg1); >> register uintptr_t a2 asm ("a2") = (uintptr_t)(arg2); >> @@ -46,6 +51,8 @@ struct sbiret sbi_ecall(int ext, int fid, unsigned long arg0, >> ret.error = a0; >> ret.value = a1; >> >> + trace_sbi_return(ext, ret.error, ret.value); >> + >> return ret; >> } >> EXPORT_SYMBOL(sbi_ecall); >> -- >> 2.43.1 >> > > sbi_ecall() is used by flush_icache_all() so I was a bit scared we > would need to patch 2 instructions using a tracepoint and then to use > flush_icache_all() which could bug if only one of the patched > instruction was seen. But I took a look at the disassembled code, and > tracepoints happen to only need to patch 1 nop into an unconditional > jump, which is not a problem then. Right, tracepoints use the static branch infrastructure, which uses a single instruction. > But then when disassembling, I noticed that the addition of the > tracepoint comes with "quite" some overhead: > > Before: > > Dump of assembler code for function sbi_ecall: > 0xffffffff800085e0 <+0>: add sp,sp,-32 > 0xffffffff800085e2 <+2>: sd s0,24(sp) > 0xffffffff800085e4 <+4>: mv t1,a0 > 0xffffffff800085e6 <+6>: add s0,sp,32 > 0xffffffff800085e8 <+8>: mv t3,a1 > 0xffffffff800085ea <+10>: mv a0,a2 > 0xffffffff800085ec <+12>: mv a1,a3 > 0xffffffff800085ee <+14>: mv a2,a4 > 0xffffffff800085f0 <+16>: mv a3,a5 > 0xffffffff800085f2 <+18>: mv a4,a6 > 0xffffffff800085f4 <+20>: mv a5,a7 > 0xffffffff800085f6 <+22>: mv a6,t3 > 0xffffffff800085f8 <+24>: mv a7,t1 > 0xffffffff800085fa <+26>: ecall > 0xffffffff800085fe <+30>: ld s0,24(sp) > 0xffffffff80008600 <+32>: add sp,sp,32 > 0xffffffff80008602 <+34>: ret > > After: > > Dump of assembler code for function sbi_ecall: > 0xffffffff8000bbf2 <+0>: add sp,sp,-112 > 0xffffffff8000bbf4 <+2>: sd s0,96(sp) > 0xffffffff8000bbf6 <+4>: sd s1,88(sp) > 0xffffffff8000bbf8 <+6>: sd s3,72(sp) > 0xffffffff8000bbfa <+8>: sd s4,64(sp) > 0xffffffff8000bbfc <+10>: sd s5,56(sp) > 0xffffffff8000bbfe <+12>: sd s6,48(sp) > 0xffffffff8000bc00 <+14>: sd s7,40(sp) > 0xffffffff8000bc02 <+16>: sd s8,32(sp) > 0xffffffff8000bc04 <+18>: sd s9,24(sp) > 0xffffffff8000bc06 <+20>: sd ra,104(sp) > 0xffffffff8000bc08 <+22>: sd s2,80(sp) > 0xffffffff8000bc0a <+24>: add s0,sp,112 > 0xffffffff8000bc0c <+26>: mv s1,a0 > 0xffffffff8000bc0e <+28>: mv s3,a1 > 0xffffffff8000bc10 <+30>: mv s9,a2 > 0xffffffff8000bc12 <+32>: mv s8,a3 > 0xffffffff8000bc14 <+34>: mv s7,a4 > 0xffffffff8000bc16 <+36>: mv s6,a5 > 0xffffffff8000bc18 <+38>: mv s5,a6 > 0xffffffff8000bc1a <+40>: mv s4,a7 > 0xffffffff8000bc1c <+42>: nop > 0xffffffff8000bc20 <+46>: mv a0,s9 > 0xffffffff8000bc22 <+48>: mv a1,s8 > 0xffffffff8000bc24 <+50>: mv a2,s7 > 0xffffffff8000bc26 <+52>: mv a3,s6 > 0xffffffff8000bc28 <+54>: mv a4,s5 > 0xffffffff8000bc2a <+56>: mv a5,s4 > 0xffffffff8000bc2c <+58>: mv a6,s3 > 0xffffffff8000bc2e <+60>: mv a7,s1 > 0xffffffff8000bc30 <+62>: ecall > 0xffffffff8000bc34 <+66>: mv s4,a0 > 0xffffffff8000bc36 <+68>: mv s3,a1 > 0xffffffff8000bc38 <+70>: nop > 0xffffffff8000bc3c <+74>: ld ra,104(sp) > 0xffffffff8000bc3e <+76>: ld s0,96(sp) > 0xffffffff8000bc40 <+78>: ld s1,88(sp) > 0xffffffff8000bc42 <+80>: ld s2,80(sp) > 0xffffffff8000bc44 <+82>: ld s5,56(sp) > 0xffffffff8000bc46 <+84>: ld s6,48(sp) > 0xffffffff8000bc48 <+86>: ld s7,40(sp) > 0xffffffff8000bc4a <+88>: ld s8,32(sp) > 0xffffffff8000bc4c <+90>: ld s9,24(sp) > 0xffffffff8000bc4e <+92>: mv a0,s4 > 0xffffffff8000bc50 <+94>: mv a1,s3 > 0xffffffff8000bc52 <+96>: ld s4,64(sp) > 0xffffffff8000bc54 <+98>: ld s3,72(sp) > 0xffffffff8000bc56 <+100>: add sp,sp,112 > 0xffffffff8000bc58 <+102>: ret > > Not sure this is really problematic though, let me know what you think. The overhead is only incurred when tracepoints are enabled. But when they are enabled, I do not think it is avoidable, unless we were to hide this tracepoint behind some Kconfig option. I don't think the overhead enough to be a problem, but I suppose it's up to maintainer judgement. Regards, Samuel ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH v2] riscv: Add tracepoints for SBI calls and returns 2024-03-26 3:39 ` Samuel Holland @ 2024-07-10 20:29 ` Palmer Dabbelt 0 siblings, 0 replies; 7+ messages in thread From: Palmer Dabbelt @ 2024-07-10 20:29 UTC (permalink / raw) To: samuel.holland Cc: alexghiti, linux-riscv, ajones, aou, apatel, Marc Zyngier, Paul Walmsley, linux-kernel On Mon, 25 Mar 2024 20:39:27 PDT (-0700), samuel.holland@sifive.com wrote: > Hi Alex, > > On 2024-03-22 4:27 AM, Alexandre Ghiti wrote: >> On Fri, Mar 22, 2024 at 12:01 AM Samuel Holland >> <samuel.holland@sifive.com> wrote: >>> >>> These are useful for measuring the latency of SBI calls. The SBI HSM >>> extension is excluded because those functions are called from contexts >>> such as cpuidle where instrumentation is not allowed. >>> >>> Reviewed-by: Andrew Jones <ajones@ventanamicro.com> >>> Signed-off-by: Samuel Holland <samuel.holland@sifive.com> >>> --- >>> >>> Changes in v2: >>> - Remove some blank lines >>> >>> arch/riscv/include/asm/trace.h | 54 ++++++++++++++++++++++++++++++++++ >>> arch/riscv/kernel/sbi.c | 7 +++++ >>> 2 files changed, 61 insertions(+) >>> create mode 100644 arch/riscv/include/asm/trace.h >>> >>> diff --git a/arch/riscv/include/asm/trace.h b/arch/riscv/include/asm/trace.h >>> new file mode 100644 >>> index 000000000000..6151cee5450c >>> --- /dev/null >>> +++ b/arch/riscv/include/asm/trace.h >>> @@ -0,0 +1,54 @@ >>> +/* SPDX-License-Identifier: GPL-2.0 */ >>> +#undef TRACE_SYSTEM >>> +#define TRACE_SYSTEM riscv >>> + >>> +#if !defined(_TRACE_RISCV_H) || defined(TRACE_HEADER_MULTI_READ) >>> +#define _TRACE_RISCV_H >>> + >>> +#include <linux/tracepoint.h> >>> + >>> +TRACE_EVENT_CONDITION(sbi_call, >>> + TP_PROTO(int ext, int fid), >>> + TP_ARGS(ext, fid), >>> + TP_CONDITION(ext != SBI_EXT_HSM), >>> + >>> + TP_STRUCT__entry( >>> + __field(int, ext) >>> + __field(int, fid) >>> + ), >>> + >>> + TP_fast_assign( >>> + __entry->ext = ext; >>> + __entry->fid = fid; >>> + ), >>> + >>> + TP_printk("ext=0x%x fid=%d", __entry->ext, __entry->fid) >>> +); >>> + >>> +TRACE_EVENT_CONDITION(sbi_return, >>> + TP_PROTO(int ext, long error, long value), >>> + TP_ARGS(ext, error, value), >>> + TP_CONDITION(ext != SBI_EXT_HSM), >>> + >>> + TP_STRUCT__entry( >>> + __field(long, error) >>> + __field(long, value) >>> + ), >>> + >>> + TP_fast_assign( >>> + __entry->error = error; >>> + __entry->value = value; >>> + ), >>> + >>> + TP_printk("error=%ld value=0x%lx", __entry->error, __entry->value) >>> +); >>> + >>> +#endif /* _TRACE_RISCV_H */ >>> + >>> +#undef TRACE_INCLUDE_PATH >>> +#undef TRACE_INCLUDE_FILE >>> + >>> +#define TRACE_INCLUDE_PATH asm >>> +#define TRACE_INCLUDE_FILE trace >>> + >>> +#include <trace/define_trace.h> >>> diff --git a/arch/riscv/kernel/sbi.c b/arch/riscv/kernel/sbi.c >>> index e66e0999a800..a1d21d8f5293 100644 >>> --- a/arch/riscv/kernel/sbi.c >>> +++ b/arch/riscv/kernel/sbi.c >>> @@ -14,6 +14,9 @@ >>> #include <asm/smp.h> >>> #include <asm/tlbflush.h> >>> >>> +#define CREATE_TRACE_POINTS >>> +#include <asm/trace.h> >>> + >>> /* default SBI version is 0.1 */ >>> unsigned long sbi_spec_version __ro_after_init = SBI_SPEC_VERSION_DEFAULT; >>> EXPORT_SYMBOL(sbi_spec_version); >>> @@ -31,6 +34,8 @@ struct sbiret sbi_ecall(int ext, int fid, unsigned long arg0, >>> { >>> struct sbiret ret; >>> >>> + trace_sbi_call(ext, fid); >>> + >>> register uintptr_t a0 asm ("a0") = (uintptr_t)(arg0); >>> register uintptr_t a1 asm ("a1") = (uintptr_t)(arg1); >>> register uintptr_t a2 asm ("a2") = (uintptr_t)(arg2); >>> @@ -46,6 +51,8 @@ struct sbiret sbi_ecall(int ext, int fid, unsigned long arg0, >>> ret.error = a0; >>> ret.value = a1; >>> >>> + trace_sbi_return(ext, ret.error, ret.value); >>> + >>> return ret; >>> } >>> EXPORT_SYMBOL(sbi_ecall); >>> -- >>> 2.43.1 >>> >> >> sbi_ecall() is used by flush_icache_all() so I was a bit scared we >> would need to patch 2 instructions using a tracepoint and then to use >> flush_icache_all() which could bug if only one of the patched >> instruction was seen. But I took a look at the disassembled code, and >> tracepoints happen to only need to patch 1 nop into an unconditional >> jump, which is not a problem then. > > Right, tracepoints use the static branch infrastructure, which uses a single > instruction. > >> But then when disassembling, I noticed that the addition of the >> tracepoint comes with "quite" some overhead: >> >> Before: >> >> Dump of assembler code for function sbi_ecall: >> 0xffffffff800085e0 <+0>: add sp,sp,-32 >> 0xffffffff800085e2 <+2>: sd s0,24(sp) >> 0xffffffff800085e4 <+4>: mv t1,a0 >> 0xffffffff800085e6 <+6>: add s0,sp,32 >> 0xffffffff800085e8 <+8>: mv t3,a1 >> 0xffffffff800085ea <+10>: mv a0,a2 >> 0xffffffff800085ec <+12>: mv a1,a3 >> 0xffffffff800085ee <+14>: mv a2,a4 >> 0xffffffff800085f0 <+16>: mv a3,a5 >> 0xffffffff800085f2 <+18>: mv a4,a6 >> 0xffffffff800085f4 <+20>: mv a5,a7 >> 0xffffffff800085f6 <+22>: mv a6,t3 >> 0xffffffff800085f8 <+24>: mv a7,t1 >> 0xffffffff800085fa <+26>: ecall >> 0xffffffff800085fe <+30>: ld s0,24(sp) >> 0xffffffff80008600 <+32>: add sp,sp,32 >> 0xffffffff80008602 <+34>: ret >> >> After: >> >> Dump of assembler code for function sbi_ecall: >> 0xffffffff8000bbf2 <+0>: add sp,sp,-112 >> 0xffffffff8000bbf4 <+2>: sd s0,96(sp) >> 0xffffffff8000bbf6 <+4>: sd s1,88(sp) >> 0xffffffff8000bbf8 <+6>: sd s3,72(sp) >> 0xffffffff8000bbfa <+8>: sd s4,64(sp) >> 0xffffffff8000bbfc <+10>: sd s5,56(sp) >> 0xffffffff8000bbfe <+12>: sd s6,48(sp) >> 0xffffffff8000bc00 <+14>: sd s7,40(sp) >> 0xffffffff8000bc02 <+16>: sd s8,32(sp) >> 0xffffffff8000bc04 <+18>: sd s9,24(sp) >> 0xffffffff8000bc06 <+20>: sd ra,104(sp) >> 0xffffffff8000bc08 <+22>: sd s2,80(sp) >> 0xffffffff8000bc0a <+24>: add s0,sp,112 >> 0xffffffff8000bc0c <+26>: mv s1,a0 >> 0xffffffff8000bc0e <+28>: mv s3,a1 >> 0xffffffff8000bc10 <+30>: mv s9,a2 >> 0xffffffff8000bc12 <+32>: mv s8,a3 >> 0xffffffff8000bc14 <+34>: mv s7,a4 >> 0xffffffff8000bc16 <+36>: mv s6,a5 >> 0xffffffff8000bc18 <+38>: mv s5,a6 >> 0xffffffff8000bc1a <+40>: mv s4,a7 >> 0xffffffff8000bc1c <+42>: nop >> 0xffffffff8000bc20 <+46>: mv a0,s9 >> 0xffffffff8000bc22 <+48>: mv a1,s8 >> 0xffffffff8000bc24 <+50>: mv a2,s7 >> 0xffffffff8000bc26 <+52>: mv a3,s6 >> 0xffffffff8000bc28 <+54>: mv a4,s5 >> 0xffffffff8000bc2a <+56>: mv a5,s4 >> 0xffffffff8000bc2c <+58>: mv a6,s3 >> 0xffffffff8000bc2e <+60>: mv a7,s1 >> 0xffffffff8000bc30 <+62>: ecall >> 0xffffffff8000bc34 <+66>: mv s4,a0 >> 0xffffffff8000bc36 <+68>: mv s3,a1 >> 0xffffffff8000bc38 <+70>: nop >> 0xffffffff8000bc3c <+74>: ld ra,104(sp) >> 0xffffffff8000bc3e <+76>: ld s0,96(sp) >> 0xffffffff8000bc40 <+78>: ld s1,88(sp) >> 0xffffffff8000bc42 <+80>: ld s2,80(sp) >> 0xffffffff8000bc44 <+82>: ld s5,56(sp) >> 0xffffffff8000bc46 <+84>: ld s6,48(sp) >> 0xffffffff8000bc48 <+86>: ld s7,40(sp) >> 0xffffffff8000bc4a <+88>: ld s8,32(sp) >> 0xffffffff8000bc4c <+90>: ld s9,24(sp) >> 0xffffffff8000bc4e <+92>: mv a0,s4 >> 0xffffffff8000bc50 <+94>: mv a1,s3 >> 0xffffffff8000bc52 <+96>: ld s4,64(sp) >> 0xffffffff8000bc54 <+98>: ld s3,72(sp) >> 0xffffffff8000bc56 <+100>: add sp,sp,112 >> 0xffffffff8000bc58 <+102>: ret >> >> Not sure this is really problematic though, let me know what you think. > > The overhead is only incurred when tracepoints are enabled. But when they are > enabled, I do not think it is avoidable, unless we were to hide this tracepoint > behind some Kconfig option. I don't think the overhead enough to be a problem, > but I suppose it's up to maintainer judgement. IIUC it's actually just the printk() inside the tracepoint that's adding the overhead, not the tracepoints themselves? We're shimming every SBI call through sbi_ecall(), which fills out every argument, so we end up saving/restoring them all around the printk(). We could convert these over to sbi_ecall_N like we do for syscalls in glibc, then we'd only need to save/restore the arguments that have something useful. I'm going to pick this one up, though, as it's not directly a problem with the patch in question. It's staged and should show up on for-next eventually, stuff might be a bit chaotic until we figure out all the poop... > > Regards, > Samuel ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH v2] riscv: Add tracepoints for SBI calls and returns 2024-03-21 23:01 [PATCH v2] riscv: Add tracepoints for SBI calls and returns Samuel Holland 2024-03-22 9:27 ` Alexandre Ghiti @ 2024-07-12 10:20 ` patchwork-bot+linux-riscv 2024-08-13 20:26 ` Conor Dooley 2 siblings, 0 replies; 7+ messages in thread From: patchwork-bot+linux-riscv @ 2024-07-12 10:20 UTC (permalink / raw) To: Samuel Holland Cc: linux-riscv, palmer, ajones, aou, alexghiti, apatel, maz, paul.walmsley, linux-kernel Hello: This patch was applied to riscv/linux.git (for-next) by Palmer Dabbelt <palmer@rivosinc.com>: On Thu, 21 Mar 2024 16:01:25 -0700 you wrote: > These are useful for measuring the latency of SBI calls. The SBI HSM > extension is excluded because those functions are called from contexts > such as cpuidle where instrumentation is not allowed. > > Reviewed-by: Andrew Jones <ajones@ventanamicro.com> > Signed-off-by: Samuel Holland <samuel.holland@sifive.com> > > [...] Here is the summary with links: - [v2] riscv: Add tracepoints for SBI calls and returns https://git.kernel.org/riscv/c/56c1c1a09ab9 You are awesome, thank you! -- Deet-doot-dot, I am a bot. https://korg.docs.kernel.org/patchwork/pwbot.html ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH v2] riscv: Add tracepoints for SBI calls and returns 2024-03-21 23:01 [PATCH v2] riscv: Add tracepoints for SBI calls and returns Samuel Holland 2024-03-22 9:27 ` Alexandre Ghiti 2024-07-12 10:20 ` patchwork-bot+linux-riscv @ 2024-08-13 20:26 ` Conor Dooley 2024-08-16 17:29 ` Alexandre Ghiti 2 siblings, 1 reply; 7+ messages in thread From: Conor Dooley @ 2024-08-13 20:26 UTC (permalink / raw) To: Samuel Holland Cc: Palmer Dabbelt, linux-riscv, Andrew Jones, Albert Ou, Alexandre Ghiti, Anup Patel, Marc Zyngier, Paul Walmsley, linux-kernel [-- Attachment #1: Type: text/plain, Size: 1230 bytes --] On Thu, Mar 21, 2024 at 04:01:25PM -0700, Samuel Holland wrote: > These are useful for measuring the latency of SBI calls. The SBI HSM > extension is excluded because those functions are called from contexts > such as cpuidle where instrumentation is not allowed. > > Reviewed-by: Andrew Jones <ajones@ventanamicro.com> > Signed-off-by: Samuel Holland <samuel.holland@sifive.com> I seem to have bisected a boot failure on v6.11-rc# to this commit, with a crash before the kernel ever gets to output anything - even on the bootconsole. For one of these crashes I got the below (which is actually U-Boots exception handler), but most of the time - nothing at all. I'll try to decodecode that tomorrow and fish out a config, because this is either config or toolchain dependant (I saw it in work, with a slightly different config etc to what I have here). Starting kernel ... Unhandled exception: Load access fault EPC: 000000008020e09c RA: 000000008020e510 TVAL: ffffffff81cbf1f0 EPC: 00000000408a009c RA: 00000000408a0510 reloc adjusted Code: 3597 01a4 b583 1f45 5613 0035 9a61 95b2 (618c) resetting ... reset not supported yet ### ERROR ### Please RESET the board ### Cheers, Conor. [-- Attachment #2: signature.asc --] [-- Type: application/pgp-signature, Size: 228 bytes --] ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH v2] riscv: Add tracepoints for SBI calls and returns 2024-08-13 20:26 ` Conor Dooley @ 2024-08-16 17:29 ` Alexandre Ghiti 0 siblings, 0 replies; 7+ messages in thread From: Alexandre Ghiti @ 2024-08-16 17:29 UTC (permalink / raw) To: Conor Dooley, Samuel Holland Cc: Palmer Dabbelt, linux-riscv, Andrew Jones, Albert Ou, Alexandre Ghiti, Anup Patel, Marc Zyngier, Paul Walmsley, linux-kernel On 13/08/2024 22:26, Conor Dooley wrote: > On Thu, Mar 21, 2024 at 04:01:25PM -0700, Samuel Holland wrote: >> These are useful for measuring the latency of SBI calls. The SBI HSM >> extension is excluded because those functions are called from contexts >> such as cpuidle where instrumentation is not allowed. >> >> Reviewed-by: Andrew Jones <ajones@ventanamicro.com> >> Signed-off-by: Samuel Holland <samuel.holland@sifive.com> > I seem to have bisected a boot failure on v6.11-rc# to this commit, > with a crash before the kernel ever gets to output anything - even on > the bootconsole. For one of these crashes I got the below (which is > actually U-Boots exception handler), but most of the time - nothing at > all. I'll try to decodecode that tomorrow and fish out a config, because > this is either config or toolchain dependant (I saw it in work, with a > slightly different config etc to what I have here). > > > Starting kernel ... > > Unhandled exception: Load access fault > EPC: 000000008020e09c RA: 000000008020e510 TVAL: ffffffff81cbf1f0 > EPC: 00000000408a009c RA: 00000000408a0510 reloc adjusted > > Code: 3597 01a4 b583 1f45 5613 0035 9a61 95b2 (618c) > > > resetting ... > reset not supported yet > ### ERROR ### Please RESET the board ### > > > Cheers, > Conor. So I have just hit a similar issue while debugging the syzkaller failure. The problem is visible with KASAN, TRACEPOINTS and RISCV_ALTERNATIVE_EARLY. The latter is important since this is where the very early sbi call is made in riscv_fill_cpu_mfr_info() (https://elixir.bootlin.com/linux/v6.11-rc3/source/arch/riscv/kernel/alternative.c#L32). And since kernel/sbi.c is compiled with KASAN instrumentation, it fails to access the KASAN region as it is not yet set up (the MMU is not up yet). So the following fixes the issue: diff --git a/arch/riscv/kernel/Makefile b/arch/riscv/kernel/Makefile index 06d407f1b30b..3b926c9444d0 100644 --- a/arch/riscv/kernel/Makefile +++ b/arch/riscv/kernel/Makefile @@ -31,6 +31,7 @@ endif ifdef CONFIG_KASAN KASAN_SANITIZE_alternative.o := n KASAN_SANITIZE_cpufeature.o := n +KASAN_SANITIZE_sbi.o := n endif endif But I don't like this solution as it removes instrumentation everywhere in this file. I'd rather move the __sbi_ecall() into its own file and remove the instrumentation here. @Conor Can you give the diff above a try and see if it fixes your issue? Thanks, Alex > > _______________________________________________ > linux-riscv mailing list > linux-riscv@lists.infradead.org > http://lists.infradead.org/mailman/listinfo/linux-riscv ^ permalink raw reply related [flat|nested] 7+ messages in thread
end of thread, other threads:[~2024-08-16 17:30 UTC | newest] Thread overview: 7+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2024-03-21 23:01 [PATCH v2] riscv: Add tracepoints for SBI calls and returns Samuel Holland 2024-03-22 9:27 ` Alexandre Ghiti 2024-03-26 3:39 ` Samuel Holland 2024-07-10 20:29 ` Palmer Dabbelt 2024-07-12 10:20 ` patchwork-bot+linux-riscv 2024-08-13 20:26 ` Conor Dooley 2024-08-16 17:29 ` Alexandre Ghiti
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox