aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSeiji Aguchi <seiji.aguchi@hds.com>2013-10-30 16:39:03 -0400
committerH. Peter Anvin <hpa@linux.intel.com>2013-11-08 17:15:49 -0500
commitd34603b07c4255b2b00a546d34f297ccd50ae4c6 (patch)
tree133e7788eb885d11cecc0590184f8825f4c0836f
parentac7956e2699380b8b10146ec2ba8cbe43a03ff7a (diff)
x86, trace: Add page fault tracepoints
This patch introduces page fault tracepoints to x86 architecture by switching IDT. Two events, for user and kernel spaces, are introduced at the beginning of page fault handler for tracing. - User space event There is a request of page fault event for user space as below. https://lkml.kernel.org/r/1368079520-11015-2-git-send-email-fdeslaur+()+gmail+!+com https://lkml.kernel.org/r/1368079520-11015-1-git-send-email-fdeslaur+()+gmail+!+com - Kernel space event: When we measure an overhead in kernel space for investigating performance issues, we can check if it comes from the page fault events. Signed-off-by: Seiji Aguchi <seiji.aguchi@hds.com> Link: http://lkml.kernel.org/r/52716E67.6090705@hds.com Signed-off-by: H. Peter Anvin <hpa@linux.intel.com>
-rw-r--r--arch/x86/include/asm/trace/exceptions.h52
-rw-r--r--arch/x86/mm/Makefile2
-rw-r--r--arch/x86/mm/fault.c13
3 files changed, 67 insertions, 0 deletions
diff --git a/arch/x86/include/asm/trace/exceptions.h b/arch/x86/include/asm/trace/exceptions.h
new file mode 100644
index 000000000000..86540c094ecc
--- /dev/null
+++ b/arch/x86/include/asm/trace/exceptions.h
@@ -0,0 +1,52 @@
1#undef TRACE_SYSTEM
2#define TRACE_SYSTEM exceptions
3
4#if !defined(_TRACE_PAGE_FAULT_H) || defined(TRACE_HEADER_MULTI_READ)
5#define _TRACE_PAGE_FAULT_H
6
7#include <linux/tracepoint.h>
8
9extern void trace_irq_vector_regfunc(void);
10extern void trace_irq_vector_unregfunc(void);
11
12DECLARE_EVENT_CLASS(x86_exceptions,
13
14 TP_PROTO(unsigned long address, struct pt_regs *regs,
15 unsigned long error_code),
16
17 TP_ARGS(address, regs, error_code),
18
19 TP_STRUCT__entry(
20 __field( unsigned long, address )
21 __field( unsigned long, ip )
22 __field( unsigned long, error_code )
23 ),
24
25 TP_fast_assign(
26 __entry->address = address;
27 __entry->ip = regs->ip;
28 __entry->error_code = error_code;
29 ),
30
31 TP_printk("address=%pf ip=%pf error_code=0x%lx",
32 (void *)__entry->address, (void *)__entry->ip,
33 __entry->error_code) );
34
35#define DEFINE_PAGE_FAULT_EVENT(name) \
36DEFINE_EVENT_FN(x86_exceptions, name, \
37 TP_PROTO(unsigned long address, struct pt_regs *regs, \
38 unsigned long error_code), \
39 TP_ARGS(address, regs, error_code), \
40 trace_irq_vector_regfunc, \
41 trace_irq_vector_unregfunc);
42
43DEFINE_PAGE_FAULT_EVENT(user_page_fault);
44DEFINE_PAGE_FAULT_EVENT(kernel_page_fault);
45
46#undef TRACE_INCLUDE_PATH
47#define TRACE_INCLUDE_PATH .
48#define TRACE_INCLUDE_FILE exceptions
49#endif /* _TRACE_PAGE_FAULT_H */
50
51/* This part must be outside protection */
52#include <trace/define_trace.h>
diff --git a/arch/x86/mm/Makefile b/arch/x86/mm/Makefile
index 23d8e5fecf76..6a19ad9f370d 100644
--- a/arch/x86/mm/Makefile
+++ b/arch/x86/mm/Makefile
@@ -6,6 +6,8 @@ nostackp := $(call cc-option, -fno-stack-protector)
6CFLAGS_physaddr.o := $(nostackp) 6CFLAGS_physaddr.o := $(nostackp)
7CFLAGS_setup_nx.o := $(nostackp) 7CFLAGS_setup_nx.o := $(nostackp)
8 8
9CFLAGS_fault.o := -I$(src)/../include/asm/trace
10
9obj-$(CONFIG_X86_PAT) += pat_rbtree.o 11obj-$(CONFIG_X86_PAT) += pat_rbtree.o
10obj-$(CONFIG_SMP) += tlb.o 12obj-$(CONFIG_SMP) += tlb.o
11 13
diff --git a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c
index fd3e281fbc70..f2730cbce0b5 100644
--- a/arch/x86/mm/fault.c
+++ b/arch/x86/mm/fault.c
@@ -20,6 +20,9 @@
20#include <asm/kmemcheck.h> /* kmemcheck_*(), ... */ 20#include <asm/kmemcheck.h> /* kmemcheck_*(), ... */
21#include <asm/fixmap.h> /* VSYSCALL_START */ 21#include <asm/fixmap.h> /* VSYSCALL_START */
22 22
23#define CREATE_TRACE_POINTS
24#include <asm/trace/exceptions.h>
25
23/* 26/*
24 * Page fault error code bits: 27 * Page fault error code bits:
25 * 28 *
@@ -1232,12 +1235,22 @@ do_page_fault(struct pt_regs *regs, unsigned long error_code)
1232 exception_exit(prev_state); 1235 exception_exit(prev_state);
1233} 1236}
1234 1237
1238static void trace_page_fault_entries(struct pt_regs *regs,
1239 unsigned long error_code)
1240{
1241 if (user_mode(regs))
1242 trace_user_page_fault(read_cr2(), regs, error_code);
1243 else
1244 trace_kernel_page_fault(read_cr2(), regs, error_code);
1245}
1246
1235dotraplinkage void __kprobes 1247dotraplinkage void __kprobes
1236trace_do_page_fault(struct pt_regs *regs, unsigned long error_code) 1248trace_do_page_fault(struct pt_regs *regs, unsigned long error_code)
1237{ 1249{
1238 enum ctx_state prev_state; 1250 enum ctx_state prev_state;
1239 1251
1240 prev_state = exception_enter(); 1252 prev_state = exception_enter();
1253 trace_page_fault_entries(regs, error_code);
1241 __do_page_fault(regs, error_code); 1254 __do_page_fault(regs, error_code);
1242 exception_exit(prev_state); 1255 exception_exit(prev_state);
1243} 1256}