Message ID | 20240717082728.84401-1-zhuhengbo@iscas.ac.cn (mailing list archive) |
---|---|
State | Changes Requested |
Headers | show |
Series | [v2] riscv: add tracepoints for page fault | expand |
On Wed, Jul 17, 2024 at 08:27:19AM +0000, Zhu Hengbo wrote: > + TP_STRUCT__entry( > + __field(unsigned long, address) > + __field(unsigned long, epc) > + __field(unsigned long, cause) > + ), > + > + TP_fast_assign( > + __entry->address = regs->badaddr; > + __entry->epc = regs->epc; > + __entry->cause = regs->cause; > + ), > + > + TP_printk("user page fault, address=%ps epc=%ps cause=0x%lx", > + (void *)__entry->address, (void *)__entry->epc, > + __entry->cause) What is "epc"? You've made this gratuitously different from x86. Never do that. Always copy what somebody else has done unless you have a good reason to be different.
On 2024/7/17 22:55, Matthew Wilcox wrote: > On Wed, Jul 17, 2024 at 08:27:19AM +0000, Zhu Hengbo wrote: >> + TP_STRUCT__entry( >> + __field(unsigned long, address) >> + __field(unsigned long, epc) >> + __field(unsigned long, cause) >> + ), >> + >> + TP_fast_assign( >> + __entry->address = regs->badaddr; >> + __entry->epc = regs->epc; >> + __entry->cause = regs->cause; >> + ), >> + >> + TP_printk("user page fault, address=%ps epc=%ps cause=0x%lx", >> + (void *)__entry->address, (void *)__entry->epc, >> + __entry->cause) > What is "epc"? You've made this gratuitously different from x86. > Never do that. Always copy what somebody else has done unless you have > a good reason to be different. “epc” stands for Exception Program Counter, which keeps track of where the CPU is within the code. It is the same as the Instruction Pointer in x86. For example, here is the encapsulation of accessing the instruction pointer in risc-v: /* Helpers for working with the instruction pointer */ static inline unsigned long instruction_pointer(struct pt_regs *regs) { return regs->epc; }
On 2024/7/17 22:55, Matthew Wilcox wrote: > On Wed, Jul 17, 2024 at 08:27:19AM +0000, Zhu Hengbo wrote: >> + TP_STRUCT__entry( >> + __field(unsigned long, address) >> + __field(unsigned long, epc) >> + __field(unsigned long, cause) >> + ), >> + >> + TP_fast_assign( >> + __entry->address = regs->badaddr; >> + __entry->epc = regs->epc; >> + __entry->cause = regs->cause; >> + ), >> + >> + TP_printk("user page fault, address=%ps epc=%ps cause=0x%lx", >> + (void *)__entry->address, (void *)__entry->epc, >> + __entry->cause) > What is "epc"? You've made this gratuitously different from x86. > Never do that. Always copy what somebody else has done unless you have > a good reason to be different. Yes, I have referred to the implementation in x86, but the fields in “struct pt_regs” are quite different between RISC-V and x86
On Wed, Jul 17, 2024 at 08:27:19AM +0000, Zhu Hengbo wrote: > Introduce page_fault_user and page_fault_kernel for riscv page fault. > Help to get more detail information when page fault happen. Just curious what's the expected usage? The mm subsystem has supported page faults perf software event, is it enough? > > Signed-off-by: Zhu Hengbo <zhuhengbo@iscas.ac.cn> > --- > Changes in v2: > - Add print instruction point info > > Simple test go below: > > root@riscv-ubuntu2204 ~ # bin/perf list | grep exceptions > exceptions:page_fault_kernel [Tracepoint event] > exceptions:page_fault_user [Tracepoint event] > > root@riscv-ubuntu2204 ~ # bin/perf record -e exceptions:page_fault_kernel -e exceptions:page_fault_user > [ perf record: Woken up 1 times to write data ] > [ perf record: Captured and wrote 0.091 MB perf.data (19 samples) ] > > perf report tracepoint: > perf 563 [007] 115.824363: exceptions:page_fault_user: user page fault, address=0x7fff94cf6400 epc=0x55558632808e cause=0xd > perf 563 [007] 115.824441: exceptions:page_fault_user: user page fault, address=0x7fff94c75400 epc=0x55558632808e cause=0xd > perf 563 [007] 115.824518: exceptions:page_fault_user: user page fault, address=0x7fff94bf4400 epc=0x55558632808e cause=0xd > perf 563 [007] 115.824907: exceptions:page_fault_kernel: kernel page fault, address=0x7fff94bf5000 epc=fault_in_readable cause=0xd > perf 563 [007] 115.825238: exceptions:page_fault_user: user page fault, address=0x7fff94bf4408 epc=0x5555863281bc cause=0xf > perf 564 [000] 116.247999: exceptions:page_fault_user: user page fault, address=0x7fff94b73400 epc=0x55558632808e cause=0xd > perf 564 [000] 116.248558: exceptions:page_fault_user: user page fault, address=0x7fff94af2400 epc=0x55558632808e cause=0xd > --- > arch/riscv/include/asm/trace/exceptions.h | 66 +++++++++++++++++++++++ > arch/riscv/mm/fault.c | 15 ++++++ > 2 files changed, 81 insertions(+) > create mode 100644 arch/riscv/include/asm/trace/exceptions.h > > diff --git a/arch/riscv/include/asm/trace/exceptions.h b/arch/riscv/include/asm/trace/exceptions.h > new file mode 100644 > index 000000000000..ff258da2f45f > --- /dev/null > +++ b/arch/riscv/include/asm/trace/exceptions.h > @@ -0,0 +1,66 @@ > +/* SPDX-License-Identifier: GPL-2.0 */ > +/* > + * Tracepoints for RISC-V exceptions > + * > + * Copyright (C) 2024 ISCAS. All rights reserved > + * > + */ > + > +#if !defined(_TRACE_PAGE_FAULT_H) || defined(TRACE_HEADER_MULTI_READ) > +#define _TRACE_PAGE_FAULT_H > + > +#include <linux/tracepoint.h> > + > +#undef TRACE_SYSTEM > +#define TRACE_SYSTEM exceptions > + > +TRACE_EVENT(page_fault_user, > + TP_PROTO(struct pt_regs *regs), > + TP_ARGS(regs), > + > + TP_STRUCT__entry( > + __field(unsigned long, address) > + __field(unsigned long, epc) > + __field(unsigned long, cause) > + ), > + > + TP_fast_assign( > + __entry->address = regs->badaddr; > + __entry->epc = regs->epc; > + __entry->cause = regs->cause; > + ), > + > + TP_printk("user page fault, address=%ps epc=%ps cause=0x%lx", > + (void *)__entry->address, (void *)__entry->epc, > + __entry->cause) > +); > + > +TRACE_EVENT(page_fault_kernel, > + TP_PROTO(struct pt_regs *regs), > + TP_ARGS(regs), > + > + TP_STRUCT__entry( > + __field(unsigned long, address) > + __field(unsigned long, epc) > + __field(unsigned long, cause) > + ), > + > + TP_fast_assign( > + __entry->address = regs->badaddr; > + __entry->epc = regs->epc; > + __entry->cause = regs->cause; > + ), > + > + TP_printk("kernel page fault, address=%ps epc=%ps cause=0x%lx", > + (void *)__entry->address, (void *)__entry->epc, > + __entry->cause) > +); > + > +#undef TRACE_INCLUDE_PATH > +#undef TRACE_INCLUDE_FILE > +#define TRACE_INCLUDE_PATH asm/trace/ > +#define TRACE_INCLUDE_FILE exceptions > +#endif /* _TRACE_PAGE_FAULT_H */ > + > +/* This part must be outside protection */ > +#include <trace/define_trace.h> > diff --git a/arch/riscv/mm/fault.c b/arch/riscv/mm/fault.c > index 5224f3733802..22874074c5bc 100644 > --- a/arch/riscv/mm/fault.c > +++ b/arch/riscv/mm/fault.c > @@ -22,6 +22,10 @@ > > #include "../kernel/head.h" > > + > +#define CREATE_TRACE_POINTS > +#include <asm/trace/exceptions.h> > + > static void die_kernel_fault(const char *msg, unsigned long addr, > struct pt_regs *regs) > { > @@ -215,6 +219,15 @@ static inline bool access_error(unsigned long cause, struct vm_area_struct *vma) > return false; > } > > + > +static inline void trace_page_fault(struct pt_regs *regs) > +{ > + if (user_mode(regs)) > + trace_page_fault_user(regs); > + else > + trace_page_fault_kernel(regs); > +} > + > /* > * This routine handles page faults. It determines the address and the > * problem, and then passes it off to one of the appropriate routines. > @@ -235,6 +248,8 @@ void handle_page_fault(struct pt_regs *regs) > tsk = current; > mm = tsk->mm; > > + trace_page_fault(regs); > + > if (kprobe_page_fault(regs, cause)) > return; > > -- > 2.34.1 > > > _______________________________________________ > linux-riscv mailing list > linux-riscv@lists.infradead.org > http://lists.infradead.org/mailman/listinfo/linux-riscv
On 2024/7/20 18:18, Jisheng Zhang wrote: > On Wed, Jul 17, 2024 at 08:27:19AM +0000, Zhu Hengbo wrote: >> Introduce page_fault_user and page_fault_kernel for riscv page fault. >> Help to get more detail information when page fault happen. > Just curious what's the expected usage? The mm subsystem has supported > page faults perf software event, is it enough? I think there will still be situations where we need to use debugfs for debugging in cases where perf is not available. In fact, I am working to achieve parity in functionality for RISC-V with x86 and ARM. In x86, there are both perf software events and tracepoints. >> Signed-off-by: Zhu Hengbo <zhuhengbo@iscas.ac.cn> >> --- >> Changes in v2: >> - Add print instruction point info >> >> Simple test go below: >> >> root@riscv-ubuntu2204 ~ # bin/perf list | grep exceptions >> exceptions:page_fault_kernel [Tracepoint event] >> exceptions:page_fault_user [Tracepoint event] >> >> root@riscv-ubuntu2204 ~ # bin/perf record -e exceptions:page_fault_kernel -e exceptions:page_fault_user >> [ perf record: Woken up 1 times to write data ] >> [ perf record: Captured and wrote 0.091 MB perf.data (19 samples) ] >> >> perf report tracepoint: >> perf 563 [007] 115.824363: exceptions:page_fault_user: user page fault, address=0x7fff94cf6400 epc=0x55558632808e cause=0xd >> perf 563 [007] 115.824441: exceptions:page_fault_user: user page fault, address=0x7fff94c75400 epc=0x55558632808e cause=0xd >> perf 563 [007] 115.824518: exceptions:page_fault_user: user page fault, address=0x7fff94bf4400 epc=0x55558632808e cause=0xd >> perf 563 [007] 115.824907: exceptions:page_fault_kernel: kernel page fault, address=0x7fff94bf5000 epc=fault_in_readable cause=0xd >> perf 563 [007] 115.825238: exceptions:page_fault_user: user page fault, address=0x7fff94bf4408 epc=0x5555863281bc cause=0xf >> perf 564 [000] 116.247999: exceptions:page_fault_user: user page fault, address=0x7fff94b73400 epc=0x55558632808e cause=0xd >> perf 564 [000] 116.248558: exceptions:page_fault_user: user page fault, address=0x7fff94af2400 epc=0x55558632808e cause=0xd >> --- >> arch/riscv/include/asm/trace/exceptions.h | 66 +++++++++++++++++++++++ >> arch/riscv/mm/fault.c | 15 ++++++ >> 2 files changed, 81 insertions(+) >> create mode 100644 arch/riscv/include/asm/trace/exceptions.h >> >> diff --git a/arch/riscv/include/asm/trace/exceptions.h b/arch/riscv/include/asm/trace/exceptions.h >> new file mode 100644 >> index 000000000000..ff258da2f45f >> --- /dev/null >> +++ b/arch/riscv/include/asm/trace/exceptions.h >> @@ -0,0 +1,66 @@ >> +/* SPDX-License-Identifier: GPL-2.0 */ >> +/* >> + * Tracepoints for RISC-V exceptions >> + * >> + * Copyright (C) 2024 ISCAS. All rights reserved >> + * >> + */ >> + >> +#if !defined(_TRACE_PAGE_FAULT_H) || defined(TRACE_HEADER_MULTI_READ) >> +#define _TRACE_PAGE_FAULT_H >> + >> +#include <linux/tracepoint.h> >> + >> +#undef TRACE_SYSTEM >> +#define TRACE_SYSTEM exceptions >> + >> +TRACE_EVENT(page_fault_user, >> + TP_PROTO(struct pt_regs *regs), >> + TP_ARGS(regs), >> + >> + TP_STRUCT__entry( >> + __field(unsigned long, address) >> + __field(unsigned long, epc) >> + __field(unsigned long, cause) >> + ), >> + >> + TP_fast_assign( >> + __entry->address = regs->badaddr; >> + __entry->epc = regs->epc; >> + __entry->cause = regs->cause; >> + ), >> + >> + TP_printk("user page fault, address=%ps epc=%ps cause=0x%lx", >> + (void *)__entry->address, (void *)__entry->epc, >> + __entry->cause) >> +); >> + >> +TRACE_EVENT(page_fault_kernel, >> + TP_PROTO(struct pt_regs *regs), >> + TP_ARGS(regs), >> + >> + TP_STRUCT__entry( >> + __field(unsigned long, address) >> + __field(unsigned long, epc) >> + __field(unsigned long, cause) >> + ), >> + >> + TP_fast_assign( >> + __entry->address = regs->badaddr; >> + __entry->epc = regs->epc; >> + __entry->cause = regs->cause; >> + ), >> + >> + TP_printk("kernel page fault, address=%ps epc=%ps cause=0x%lx", >> + (void *)__entry->address, (void *)__entry->epc, >> + __entry->cause) >> +); >> + >> +#undef TRACE_INCLUDE_PATH >> +#undef TRACE_INCLUDE_FILE >> +#define TRACE_INCLUDE_PATH asm/trace/ >> +#define TRACE_INCLUDE_FILE exceptions >> +#endif /* _TRACE_PAGE_FAULT_H */ >> + >> +/* This part must be outside protection */ >> +#include <trace/define_trace.h> >> diff --git a/arch/riscv/mm/fault.c b/arch/riscv/mm/fault.c >> index 5224f3733802..22874074c5bc 100644 >> --- a/arch/riscv/mm/fault.c >> +++ b/arch/riscv/mm/fault.c >> @@ -22,6 +22,10 @@ >> >> #include "../kernel/head.h" >> >> + >> +#define CREATE_TRACE_POINTS >> +#include <asm/trace/exceptions.h> >> + >> static void die_kernel_fault(const char *msg, unsigned long addr, >> struct pt_regs *regs) >> { >> @@ -215,6 +219,15 @@ static inline bool access_error(unsigned long cause, struct vm_area_struct *vma) >> return false; >> } >> >> + >> +static inline void trace_page_fault(struct pt_regs *regs) >> +{ >> + if (user_mode(regs)) >> + trace_page_fault_user(regs); >> + else >> + trace_page_fault_kernel(regs); >> +} >> + >> /* >> * This routine handles page faults. It determines the address and the >> * problem, and then passes it off to one of the appropriate routines. >> @@ -235,6 +248,8 @@ void handle_page_fault(struct pt_regs *regs) >> tsk = current; >> mm = tsk->mm; >> >> + trace_page_fault(regs); >> + >> if (kprobe_page_fault(regs, cause)) >> return; >> >> -- >> 2.34.1 >> >> >> _______________________________________________ >> linux-riscv mailing list >> linux-riscv@lists.infradead.org >> http://lists.infradead.org/mailman/listinfo/linux-riscv
On 2024/7/22 11:21, Zhu Hengbo wrote: > On 2024/7/20 18:18, Jisheng Zhang wrote: >> On Wed, Jul 17, 2024 at 08:27:19AM +0000, Zhu Hengbo wrote: >>> Introduce page_fault_user and page_fault_kernel for riscv page fault. >>> Help to get more detail information when page fault happen. >> Just curious what's the expected usage? The mm subsystem has supported >> page faults perf software event, is it enough? > > I think there will still be situations where we need to use debugfs for debugging in cases where perf is not available. > > In fact, I am working to achieve parity in functionality for RISC-V with x86 and ARM. > In x86, there are both perf software events and tracepoints. > If this is not needed, that's fine too. Please let me know. Thanks for your attention. >>> Signed-off-by: Zhu Hengbo <zhuhengbo@iscas.ac.cn> >>> --- >>> Changes in v2: >>> - Add print instruction point info >>> >>> Simple test go below: >>> >>> root@riscv-ubuntu2204 ~ # bin/perf list | grep exceptions >>> exceptions:page_fault_kernel [Tracepoint event] >>> exceptions:page_fault_user [Tracepoint event] >>> >>> root@riscv-ubuntu2204 ~ # bin/perf record -e exceptions:page_fault_kernel -e exceptions:page_fault_user >>> [ perf record: Woken up 1 times to write data ] >>> [ perf record: Captured and wrote 0.091 MB perf.data (19 samples) ] >>> >>> perf report tracepoint: >>> perf 563 [007] 115.824363: exceptions:page_fault_user: user page fault, address=0x7fff94cf6400 epc=0x55558632808e cause=0xd >>> perf 563 [007] 115.824441: exceptions:page_fault_user: user page fault, address=0x7fff94c75400 epc=0x55558632808e cause=0xd >>> perf 563 [007] 115.824518: exceptions:page_fault_user: user page fault, address=0x7fff94bf4400 epc=0x55558632808e cause=0xd >>> perf 563 [007] 115.824907: exceptions:page_fault_kernel: kernel page fault, address=0x7fff94bf5000 epc=fault_in_readable cause=0xd >>> perf 563 [007] 115.825238: exceptions:page_fault_user: user page fault, address=0x7fff94bf4408 epc=0x5555863281bc cause=0xf >>> perf 564 [000] 116.247999: exceptions:page_fault_user: user page fault, address=0x7fff94b73400 epc=0x55558632808e cause=0xd >>> perf 564 [000] 116.248558: exceptions:page_fault_user: user page fault, address=0x7fff94af2400 epc=0x55558632808e cause=0xd >>> --- >>> arch/riscv/include/asm/trace/exceptions.h | 66 +++++++++++++++++++++++ >>> arch/riscv/mm/fault.c | 15 ++++++ >>> 2 files changed, 81 insertions(+) >>> create mode 100644 arch/riscv/include/asm/trace/exceptions.h >>> >>> diff --git a/arch/riscv/include/asm/trace/exceptions.h b/arch/riscv/include/asm/trace/exceptions.h >>> new file mode 100644 >>> index 000000000000..ff258da2f45f >>> --- /dev/null >>> +++ b/arch/riscv/include/asm/trace/exceptions.h >>> @@ -0,0 +1,66 @@ >>> +/* SPDX-License-Identifier: GPL-2.0 */ >>> +/* >>> + * Tracepoints for RISC-V exceptions >>> + * >>> + * Copyright (C) 2024 ISCAS. All rights reserved >>> + * >>> + */ >>> + >>> +#if !defined(_TRACE_PAGE_FAULT_H) || defined(TRACE_HEADER_MULTI_READ) >>> +#define _TRACE_PAGE_FAULT_H >>> + >>> +#include <linux/tracepoint.h> >>> + >>> +#undef TRACE_SYSTEM >>> +#define TRACE_SYSTEM exceptions >>> + >>> +TRACE_EVENT(page_fault_user, >>> + TP_PROTO(struct pt_regs *regs), >>> + TP_ARGS(regs), >>> + >>> + TP_STRUCT__entry( >>> + __field(unsigned long, address) >>> + __field(unsigned long, epc) >>> + __field(unsigned long, cause) >>> + ), >>> + >>> + TP_fast_assign( >>> + __entry->address = regs->badaddr; >>> + __entry->epc = regs->epc; >>> + __entry->cause = regs->cause; >>> + ), >>> + >>> + TP_printk("user page fault, address=%ps epc=%ps cause=0x%lx", >>> + (void *)__entry->address, (void *)__entry->epc, >>> + __entry->cause) >>> +); >>> + >>> +TRACE_EVENT(page_fault_kernel, >>> + TP_PROTO(struct pt_regs *regs), >>> + TP_ARGS(regs), >>> + >>> + TP_STRUCT__entry( >>> + __field(unsigned long, address) >>> + __field(unsigned long, epc) >>> + __field(unsigned long, cause) >>> + ), >>> + >>> + TP_fast_assign( >>> + __entry->address = regs->badaddr; >>> + __entry->epc = regs->epc; >>> + __entry->cause = regs->cause; >>> + ), >>> + >>> + TP_printk("kernel page fault, address=%ps epc=%ps cause=0x%lx", >>> + (void *)__entry->address, (void *)__entry->epc, >>> + __entry->cause) >>> +); >>> + >>> +#undef TRACE_INCLUDE_PATH >>> +#undef TRACE_INCLUDE_FILE >>> +#define TRACE_INCLUDE_PATH asm/trace/ >>> +#define TRACE_INCLUDE_FILE exceptions >>> +#endif /* _TRACE_PAGE_FAULT_H */ >>> + >>> +/* This part must be outside protection */ >>> +#include <trace/define_trace.h> >>> diff --git a/arch/riscv/mm/fault.c b/arch/riscv/mm/fault.c >>> index 5224f3733802..22874074c5bc 100644 >>> --- a/arch/riscv/mm/fault.c >>> +++ b/arch/riscv/mm/fault.c >>> @@ -22,6 +22,10 @@ >>> >>> #include "../kernel/head.h" >>> >>> + >>> +#define CREATE_TRACE_POINTS >>> +#include <asm/trace/exceptions.h> >>> + >>> static void die_kernel_fault(const char *msg, unsigned long addr, >>> struct pt_regs *regs) >>> { >>> @@ -215,6 +219,15 @@ static inline bool access_error(unsigned long cause, struct vm_area_struct *vma) >>> return false; >>> } >>> >>> + >>> +static inline void trace_page_fault(struct pt_regs *regs) >>> +{ >>> + if (user_mode(regs)) >>> + trace_page_fault_user(regs); >>> + else >>> + trace_page_fault_kernel(regs); >>> +} >>> + >>> /* >>> * This routine handles page faults. It determines the address and the >>> * problem, and then passes it off to one of the appropriate routines. >>> @@ -235,6 +248,8 @@ void handle_page_fault(struct pt_regs *regs) >>> tsk = current; >>> mm = tsk->mm; >>> >>> + trace_page_fault(regs); >>> + >>> if (kprobe_page_fault(regs, cause)) >>> return; >>> >>> -- >>> 2.34.1 >>> >>> >>> _______________________________________________ >>> linux-riscv mailing list >>> linux-riscv@lists.infradead.org >>> http://lists.infradead.org/mailman/listinfo/linux-riscv > > _______________________________________________ > linux-riscv mailing list > linux-riscv@lists.infradead.org > http://lists.infradead.org/mailman/listinfo/linux-riscv
diff --git a/arch/riscv/include/asm/trace/exceptions.h b/arch/riscv/include/asm/trace/exceptions.h new file mode 100644 index 000000000000..ff258da2f45f --- /dev/null +++ b/arch/riscv/include/asm/trace/exceptions.h @@ -0,0 +1,66 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Tracepoints for RISC-V exceptions + * + * Copyright (C) 2024 ISCAS. All rights reserved + * + */ + +#if !defined(_TRACE_PAGE_FAULT_H) || defined(TRACE_HEADER_MULTI_READ) +#define _TRACE_PAGE_FAULT_H + +#include <linux/tracepoint.h> + +#undef TRACE_SYSTEM +#define TRACE_SYSTEM exceptions + +TRACE_EVENT(page_fault_user, + TP_PROTO(struct pt_regs *regs), + TP_ARGS(regs), + + TP_STRUCT__entry( + __field(unsigned long, address) + __field(unsigned long, epc) + __field(unsigned long, cause) + ), + + TP_fast_assign( + __entry->address = regs->badaddr; + __entry->epc = regs->epc; + __entry->cause = regs->cause; + ), + + TP_printk("user page fault, address=%ps epc=%ps cause=0x%lx", + (void *)__entry->address, (void *)__entry->epc, + __entry->cause) +); + +TRACE_EVENT(page_fault_kernel, + TP_PROTO(struct pt_regs *regs), + TP_ARGS(regs), + + TP_STRUCT__entry( + __field(unsigned long, address) + __field(unsigned long, epc) + __field(unsigned long, cause) + ), + + TP_fast_assign( + __entry->address = regs->badaddr; + __entry->epc = regs->epc; + __entry->cause = regs->cause; + ), + + TP_printk("kernel page fault, address=%ps epc=%ps cause=0x%lx", + (void *)__entry->address, (void *)__entry->epc, + __entry->cause) +); + +#undef TRACE_INCLUDE_PATH +#undef TRACE_INCLUDE_FILE +#define TRACE_INCLUDE_PATH asm/trace/ +#define TRACE_INCLUDE_FILE exceptions +#endif /* _TRACE_PAGE_FAULT_H */ + +/* This part must be outside protection */ +#include <trace/define_trace.h> diff --git a/arch/riscv/mm/fault.c b/arch/riscv/mm/fault.c index 5224f3733802..22874074c5bc 100644 --- a/arch/riscv/mm/fault.c +++ b/arch/riscv/mm/fault.c @@ -22,6 +22,10 @@ #include "../kernel/head.h" + +#define CREATE_TRACE_POINTS +#include <asm/trace/exceptions.h> + static void die_kernel_fault(const char *msg, unsigned long addr, struct pt_regs *regs) { @@ -215,6 +219,15 @@ static inline bool access_error(unsigned long cause, struct vm_area_struct *vma) return false; } + +static inline void trace_page_fault(struct pt_regs *regs) +{ + if (user_mode(regs)) + trace_page_fault_user(regs); + else + trace_page_fault_kernel(regs); +} + /* * This routine handles page faults. It determines the address and the * problem, and then passes it off to one of the appropriate routines. @@ -235,6 +248,8 @@ void handle_page_fault(struct pt_regs *regs) tsk = current; mm = tsk->mm; + trace_page_fault(regs); + if (kprobe_page_fault(regs, cause)) return;
Introduce page_fault_user and page_fault_kernel for riscv page fault. Help to get more detail information when page fault happen. Signed-off-by: Zhu Hengbo <zhuhengbo@iscas.ac.cn> --- Changes in v2: - Add print instruction point info Simple test go below: root@riscv-ubuntu2204 ~ # bin/perf list | grep exceptions exceptions:page_fault_kernel [Tracepoint event] exceptions:page_fault_user [Tracepoint event] root@riscv-ubuntu2204 ~ # bin/perf record -e exceptions:page_fault_kernel -e exceptions:page_fault_user [ perf record: Woken up 1 times to write data ] [ perf record: Captured and wrote 0.091 MB perf.data (19 samples) ] perf report tracepoint: perf 563 [007] 115.824363: exceptions:page_fault_user: user page fault, address=0x7fff94cf6400 epc=0x55558632808e cause=0xd perf 563 [007] 115.824441: exceptions:page_fault_user: user page fault, address=0x7fff94c75400 epc=0x55558632808e cause=0xd perf 563 [007] 115.824518: exceptions:page_fault_user: user page fault, address=0x7fff94bf4400 epc=0x55558632808e cause=0xd perf 563 [007] 115.824907: exceptions:page_fault_kernel: kernel page fault, address=0x7fff94bf5000 epc=fault_in_readable cause=0xd perf 563 [007] 115.825238: exceptions:page_fault_user: user page fault, address=0x7fff94bf4408 epc=0x5555863281bc cause=0xf perf 564 [000] 116.247999: exceptions:page_fault_user: user page fault, address=0x7fff94b73400 epc=0x55558632808e cause=0xd perf 564 [000] 116.248558: exceptions:page_fault_user: user page fault, address=0x7fff94af2400 epc=0x55558632808e cause=0xd --- arch/riscv/include/asm/trace/exceptions.h | 66 +++++++++++++++++++++++ arch/riscv/mm/fault.c | 15 ++++++ 2 files changed, 81 insertions(+) create mode 100644 arch/riscv/include/asm/trace/exceptions.h