Commit d98f8f05188b45168db43df8ddc9feeb0b1cd512
Committed by
Linus Torvalds
1 parent
4f9e87c045
Exists in
master
and in
7 other branches
[PATCH] Notify page fault call chain for sparc64
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>
Showing 2 changed files with 37 additions and 1 deletions Side-by-side Diff
arch/sparc64/mm/fault.c
... | ... | @@ -31,6 +31,40 @@ |
31 | 31 | #include <asm/kdebug.h> |
32 | 32 | #include <asm/mmu_context.h> |
33 | 33 | |
34 | +#ifdef CONFIG_KPROBES | |
35 | +ATOMIC_NOTIFIER_HEAD(notify_page_fault_chain); | |
36 | + | |
37 | +/* Hook to register for page fault notifications */ | |
38 | +int register_page_fault_notifier(struct notifier_block *nb) | |
39 | +{ | |
40 | + return atomic_notifier_chain_register(¬ify_page_fault_chain, nb); | |
41 | +} | |
42 | + | |
43 | +int unregister_page_fault_notifier(struct notifier_block *nb) | |
44 | +{ | |
45 | + return atomic_notifier_chain_unregister(¬ify_page_fault_chain, nb); | |
46 | +} | |
47 | + | |
48 | +static inline int notify_page_fault(enum die_val val, const char *str, | |
49 | + struct pt_regs *regs, long err, int trap, int sig) | |
50 | +{ | |
51 | + struct die_args args = { | |
52 | + .regs = regs, | |
53 | + .str = str, | |
54 | + .err = err, | |
55 | + .trapnr = trap, | |
56 | + .signr = sig | |
57 | + }; | |
58 | + return atomic_notifier_call_chain(¬ify_page_fault_chain, val, &args); | |
59 | +} | |
60 | +#else | |
61 | +static inline int notify_page_fault(enum die_val val, const char *str, | |
62 | + struct pt_regs *regs, long err, int trap, int sig) | |
63 | +{ | |
64 | + return NOTIFY_DONE; | |
65 | +} | |
66 | +#endif | |
67 | + | |
34 | 68 | /* |
35 | 69 | * To debug kernel to catch accesses to certain virtual/physical addresses. |
36 | 70 | * Mode = 0 selects physical watchpoints, mode = 1 selects virtual watchpoints. |
... | ... | @@ -263,7 +297,7 @@ |
263 | 297 | |
264 | 298 | fault_code = get_thread_fault_code(); |
265 | 299 | |
266 | - if (notify_die(DIE_PAGE_FAULT, "page_fault", regs, | |
300 | + if (notify_page_fault(DIE_PAGE_FAULT, "page_fault", regs, | |
267 | 301 | fault_code, 0, SIGSEGV) == NOTIFY_STOP) |
268 | 302 | return; |
269 | 303 |
include/asm-sparc64/kdebug.h
... | ... | @@ -17,6 +17,8 @@ |
17 | 17 | |
18 | 18 | extern int register_die_notifier(struct notifier_block *); |
19 | 19 | extern int unregister_die_notifier(struct notifier_block *); |
20 | +extern int register_page_fault_notifier(struct notifier_block *); | |
21 | +extern int unregister_page_fault_notifier(struct notifier_block *); | |
20 | 22 | extern struct atomic_notifier_head sparc64die_chain; |
21 | 23 | |
22 | 24 | extern void bad_trap(struct pt_regs *, long); |