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 | |
| 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')
| -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 | ||
