* [PATCH] riscv: add tracepoints for page fault
@ 2024-07-15 10:13 Zhu Hengbo
2024-07-15 13:36 ` Matthew Wilcox
2024-07-17 8:27 ` [PATCH v2] " Zhu Hengbo
0 siblings, 2 replies; 9+ messages in thread
From: Zhu Hengbo @ 2024-07-15 10:13 UTC (permalink / raw)
To: Paul Walmsley, Palmer Dabbelt, Albert Ou, Zhu Hengbo,
Suren Baghdasaryan, Alexandre Ghiti, Andrew Morton, Kefeng Wang,
Matthew Wilcox (Oracle), linux-riscv, linux-kernel
Introduce page_fault_user and page_fault_kernel for riscv page fault.
Help to get more detail information when page fault happen.
---
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 826 [007] 894.795520: exceptions:page_fault_user: user page fault, address=0x7fff95af4400 cause=0xd
perf 826 [007] 894.795970: exceptions:page_fault_user: user page fault, address=0x7fff95a73400 cause=0xd
perf 826 [007] 894.796738: exceptions:page_fault_user: user page fault, address=0x7fff959f2400 cause=0xd
perf 826 [007] 894.797088: exceptions:page_fault_user: user page fault, address=0x7fff95971400 cause=0xd
perf 826 [007] 894.797273: exceptions:page_fault_user: user page fault, address=0x7fff958f0400 cause=0xd
perf 826 [007] 894.797445: exceptions:page_fault_user: user page fault, address=0x7fff9586f400 cause=0xd
perf 826 [007] 894.797998: exceptions:page_fault_kernel: kernel page fault, address=0x7fff95870000 cause=0xd
Signed-off-by: Zhu Hengbo <zhuhengbo@iscas.ac.cn>
---
arch/riscv/include/asm/trace/exceptions.h | 60 +++++++++++++++++++++++
arch/riscv/mm/fault.c | 15 ++++++
2 files changed, 75 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..a9a68d471703
--- /dev/null
+++ b/arch/riscv/include/asm/trace/exceptions.h
@@ -0,0 +1,60 @@
+/* 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, cause)
+ ),
+
+ TP_fast_assign(
+ __entry->address = regs->badaddr;
+ __entry->cause = regs->cause;
+ ),
+
+ TP_printk("user page fault, address=%ps cause=0x%lx",
+ (void *)__entry->address, __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, cause)
+ ),
+
+ TP_fast_assign(
+ __entry->address = regs->badaddr;
+ __entry->cause = regs->cause;
+ ),
+
+ TP_printk("kernel page fault, address=%ps cause=0x%lx",
+ (void *)__entry->address, __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
^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [PATCH] riscv: add tracepoints for page fault
2024-07-15 10:13 [PATCH] riscv: add tracepoints for page fault Zhu Hengbo
@ 2024-07-15 13:36 ` Matthew Wilcox
2024-07-17 8:27 ` [PATCH v2] " Zhu Hengbo
1 sibling, 0 replies; 9+ messages in thread
From: Matthew Wilcox @ 2024-07-15 13:36 UTC (permalink / raw)
To: Zhu Hengbo
Cc: Paul Walmsley, Palmer Dabbelt, Albert Ou, Suren Baghdasaryan,
Alexandre Ghiti, Andrew Morton, Kefeng Wang, linux-riscv,
linux-kernel
On Mon, Jul 15, 2024 at 10:13:55AM +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.
Why be different from x86?
TP_printk("address=%ps ip=%ps error_code=0x%lx",
(void *)__entry->address, (void *)__entry->ip,
__entry->error_code) );
adding the instruction pointer (ip) seems like it would be useful.
> + TP_printk("user page fault, address=%ps cause=0x%lx",
> + (void *)__entry->address, __entry->cause)
^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH v2] riscv: add tracepoints for page fault
2024-07-15 10:13 [PATCH] riscv: add tracepoints for page fault Zhu Hengbo
2024-07-15 13:36 ` Matthew Wilcox
@ 2024-07-17 8:27 ` Zhu Hengbo
2024-07-17 14:55 ` Matthew Wilcox
2024-07-20 10:18 ` Jisheng Zhang
1 sibling, 2 replies; 9+ messages in thread
From: Zhu Hengbo @ 2024-07-17 8:27 UTC (permalink / raw)
To: Paul Walmsley, Palmer Dabbelt, Albert Ou, Zhu Hengbo,
Andrew Morton, Suren Baghdasaryan, Alexandre Ghiti, Kefeng Wang,
Matthew Wilcox (Oracle), linux-riscv, linux-kernel
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
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
^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [PATCH v2] riscv: add tracepoints for page fault
2024-07-17 8:27 ` [PATCH v2] " Zhu Hengbo
@ 2024-07-17 14:55 ` Matthew Wilcox
2024-07-18 1:29 ` Zhu Hengbo
2024-07-18 1:34 ` Zhu Hengbo
2024-07-20 10:18 ` Jisheng Zhang
1 sibling, 2 replies; 9+ messages in thread
From: Matthew Wilcox @ 2024-07-17 14:55 UTC (permalink / raw)
To: Zhu Hengbo
Cc: Paul Walmsley, Palmer Dabbelt, Albert Ou, Andrew Morton,
Suren Baghdasaryan, Alexandre Ghiti, Kefeng Wang, linux-riscv,
linux-kernel
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.
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH v2] riscv: add tracepoints for page fault
2024-07-17 14:55 ` Matthew Wilcox
@ 2024-07-18 1:29 ` Zhu Hengbo
2024-07-18 1:34 ` Zhu Hengbo
1 sibling, 0 replies; 9+ messages in thread
From: Zhu Hengbo @ 2024-07-18 1:29 UTC (permalink / raw)
To: Matthew Wilcox
Cc: Paul Walmsley, Palmer Dabbelt, Albert Ou, Andrew Morton,
Suren Baghdasaryan, Alexandre Ghiti, Kefeng Wang, linux-riscv,
linux-kernel
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;
}
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH v2] riscv: add tracepoints for page fault
2024-07-17 14:55 ` Matthew Wilcox
2024-07-18 1:29 ` Zhu Hengbo
@ 2024-07-18 1:34 ` Zhu Hengbo
1 sibling, 0 replies; 9+ messages in thread
From: Zhu Hengbo @ 2024-07-18 1:34 UTC (permalink / raw)
To: Matthew Wilcox
Cc: Paul Walmsley, Palmer Dabbelt, Albert Ou, Andrew Morton,
Suren Baghdasaryan, Alexandre Ghiti, Kefeng Wang, linux-riscv,
linux-kernel
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
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH v2] riscv: add tracepoints for page fault
2024-07-17 8:27 ` [PATCH v2] " Zhu Hengbo
2024-07-17 14:55 ` Matthew Wilcox
@ 2024-07-20 10:18 ` Jisheng Zhang
2024-07-22 3:21 ` Zhu Hengbo
1 sibling, 1 reply; 9+ messages in thread
From: Jisheng Zhang @ 2024-07-20 10:18 UTC (permalink / raw)
To: Zhu Hengbo
Cc: Paul Walmsley, Palmer Dabbelt, Albert Ou, Andrew Morton,
Suren Baghdasaryan, Alexandre Ghiti, Kefeng Wang,
Matthew Wilcox (Oracle), linux-riscv, linux-kernel
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
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH v2] riscv: add tracepoints for page fault
2024-07-20 10:18 ` Jisheng Zhang
@ 2024-07-22 3:21 ` Zhu Hengbo
2024-07-22 3:26 ` Zhu Hengbo
0 siblings, 1 reply; 9+ messages in thread
From: Zhu Hengbo @ 2024-07-22 3:21 UTC (permalink / raw)
To: Jisheng Zhang
Cc: Paul Walmsley, Palmer Dabbelt, Albert Ou, Andrew Morton,
Suren Baghdasaryan, Alexandre Ghiti, Kefeng Wang,
Matthew Wilcox (Oracle), linux-riscv, linux-kernel
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
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH v2] riscv: add tracepoints for page fault
2024-07-22 3:21 ` Zhu Hengbo
@ 2024-07-22 3:26 ` Zhu Hengbo
0 siblings, 0 replies; 9+ messages in thread
From: Zhu Hengbo @ 2024-07-22 3:26 UTC (permalink / raw)
To: Jisheng Zhang
Cc: Paul Walmsley, Palmer Dabbelt, Albert Ou, Andrew Morton,
Suren Baghdasaryan, Alexandre Ghiti, Kefeng Wang,
Matthew Wilcox (Oracle), linux-riscv, linux-kernel
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
^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2024-07-22 3:31 UTC | newest]
Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-07-15 10:13 [PATCH] riscv: add tracepoints for page fault Zhu Hengbo
2024-07-15 13:36 ` Matthew Wilcox
2024-07-17 8:27 ` [PATCH v2] " Zhu Hengbo
2024-07-17 14:55 ` Matthew Wilcox
2024-07-18 1:29 ` Zhu Hengbo
2024-07-18 1:34 ` Zhu Hengbo
2024-07-20 10:18 ` Jisheng Zhang
2024-07-22 3:21 ` Zhu Hengbo
2024-07-22 3:26 ` Zhu Hengbo
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox