diff options
author | Anil S Keshavamurthy <anil.s.keshavamurthy@intel.com> | 2006-06-26 03:25:26 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-06-26 12:58:22 -0400 |
commit | ae9a5b85655d7133ab8e7c99b742ef20c8dbb7d2 (patch) | |
tree | 011bf055ef888a4cfb949fec467bd6385a090d12 /arch/ia64/mm | |
parent | b71b5b652852db1b499d22aaabed8f5043acafad (diff) |
[PATCH] Notify page fault call chain for ia64
Overloading of page fault notification with the notify_die() has performance
issues(since the only interested components for page fault is kprobes and/or
kdb) and hence this patch introduces the new notifier call chain exclusively
for page fault notifications their by avoiding notifying unnecessary
components in the do_page_fault() code path.
Signed-off-by: Anil S Keshavamurthy <anil.s.keshavamurthy@intel.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'arch/ia64/mm')
-rw-r--r-- | arch/ia64/mm/fault.c | 36 |
1 files changed, 35 insertions, 1 deletions
diff --git a/arch/ia64/mm/fault.c b/arch/ia64/mm/fault.c index d98ec49570b8..14ef7cceb208 100644 --- a/arch/ia64/mm/fault.c +++ b/arch/ia64/mm/fault.c | |||
@@ -19,6 +19,40 @@ | |||
19 | 19 | ||
20 | extern void die (char *, struct pt_regs *, long); | 20 | extern void die (char *, struct pt_regs *, long); |
21 | 21 | ||
22 | #ifdef CONFIG_KPROBES | ||
23 | ATOMIC_NOTIFIER_HEAD(notify_page_fault_chain); | ||
24 | |||
25 | /* Hook to register for page fault notifications */ | ||
26 | int register_page_fault_notifier(struct notifier_block *nb) | ||
27 | { | ||
28 | return atomic_notifier_chain_register(¬ify_page_fault_chain, nb); | ||
29 | } | ||
30 | |||
31 | int unregister_page_fault_notifier(struct notifier_block *nb) | ||
32 | { | ||
33 | return atomic_notifier_chain_unregister(¬ify_page_fault_chain, nb); | ||
34 | } | ||
35 | |||
36 | static inline int notify_page_fault(enum die_val val, const char *str, | ||
37 | struct pt_regs *regs, long err, int trap, int sig) | ||
38 | { | ||
39 | struct die_args args = { | ||
40 | .regs = regs, | ||
41 | .str = str, | ||
42 | .err = err, | ||
43 | .trapnr = trap, | ||
44 | .signr = sig | ||
45 | }; | ||
46 | return atomic_notifier_call_chain(¬ify_page_fault_chain, val, &args); | ||
47 | } | ||
48 | #else | ||
49 | static inline int notify_page_fault(enum die_val val, const char *str, | ||
50 | struct pt_regs *regs, long err, int trap, int sig) | ||
51 | { | ||
52 | return NOTIFY_DONE; | ||
53 | } | ||
54 | #endif | ||
55 | |||
22 | /* | 56 | /* |
23 | * Return TRUE if ADDRESS points at a page in the kernel's mapped segment | 57 | * Return TRUE if ADDRESS points at a page in the kernel's mapped segment |
24 | * (inside region 5, on ia64) and that page is present. | 58 | * (inside region 5, on ia64) and that page is present. |
@@ -84,7 +118,7 @@ ia64_do_page_fault (unsigned long address, unsigned long isr, struct pt_regs *re | |||
84 | /* | 118 | /* |
85 | * This is to handle the kprobes on user space access instructions | 119 | * This is to handle the kprobes on user space access instructions |
86 | */ | 120 | */ |
87 | if (notify_die(DIE_PAGE_FAULT, "page fault", regs, code, TRAP_BRKPT, | 121 | if (notify_page_fault(DIE_PAGE_FAULT, "page fault", regs, code, TRAP_BRKPT, |
88 | SIGSEGV) == NOTIFY_STOP) | 122 | SIGSEGV) == NOTIFY_STOP) |
89 | return; | 123 | return; |
90 | 124 | ||