aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86
diff options
context:
space:
mode:
authorKOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com>2011-05-26 04:12:12 -0400
committerIngo Molnar <mingo@elte.hu>2011-05-26 07:54:03 -0400
commitb80ef10e84d85a06bcd0b3a24a752ec32d0e0e40 (patch)
tree39a1d5b97203b99ab736f1b804a7782d6b3a05a5 /arch/x86
parentde66ee979d0ea45171cc2501750e9f9f22f5a690 (diff)
x86: Move do_page_fault()'s error path under unlikely()
Ingo suggested SIGKILL check should be moved into slowpath function. This will reduce the page fault fastpath impact of this recent commit: 37b23e0525d3: x86,mm: make pagefault killable Suggested-by: Ingo Molnar <mingo@elte.hu> Signed-off-by: KOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com> Cc: kamezawa.hiroyu@jp.fujitsu.com Cc: minchan.kim@gmail.com Cc: willy@linux.intel.com Cc: Andrew Morton <akpm@linux-foundation.org> Cc: Linus Torvalds <torvalds@linux-foundation.org> Link: http://lkml.kernel.org/r/4DDE0B5C.9050907@jp.fujitsu.com Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'arch/x86')
-rw-r--r--arch/x86/mm/fault.c35
1 files changed, 20 insertions, 15 deletions
diff --git a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c
index f7a2a054a3c0..2dbf6bf4c7e5 100644
--- a/arch/x86/mm/fault.c
+++ b/arch/x86/mm/fault.c
@@ -823,16 +823,30 @@ do_sigbus(struct pt_regs *regs, unsigned long error_code, unsigned long address,
823 force_sig_info_fault(SIGBUS, code, address, tsk, fault); 823 force_sig_info_fault(SIGBUS, code, address, tsk, fault);
824} 824}
825 825
826static noinline void 826static noinline int
827mm_fault_error(struct pt_regs *regs, unsigned long error_code, 827mm_fault_error(struct pt_regs *regs, unsigned long error_code,
828 unsigned long address, unsigned int fault) 828 unsigned long address, unsigned int fault)
829{ 829{
830 /*
831 * Pagefault was interrupted by SIGKILL. We have no reason to
832 * continue pagefault.
833 */
834 if (fatal_signal_pending(current)) {
835 if (!(fault & VM_FAULT_RETRY))
836 up_read(&current->mm->mmap_sem);
837 if (!(error_code & PF_USER))
838 no_context(regs, error_code, address);
839 return 1;
840 }
841 if (!(fault & VM_FAULT_ERROR))
842 return 0;
843
830 if (fault & VM_FAULT_OOM) { 844 if (fault & VM_FAULT_OOM) {
831 /* Kernel mode? Handle exceptions or die: */ 845 /* Kernel mode? Handle exceptions or die: */
832 if (!(error_code & PF_USER)) { 846 if (!(error_code & PF_USER)) {
833 up_read(&current->mm->mmap_sem); 847 up_read(&current->mm->mmap_sem);
834 no_context(regs, error_code, address); 848 no_context(regs, error_code, address);
835 return; 849 return 1;
836 } 850 }
837 851
838 out_of_memory(regs, error_code, address); 852 out_of_memory(regs, error_code, address);
@@ -843,6 +857,7 @@ mm_fault_error(struct pt_regs *regs, unsigned long error_code,
843 else 857 else
844 BUG(); 858 BUG();
845 } 859 }
860 return 1;
846} 861}
847 862
848static int spurious_fault_check(unsigned long error_code, pte_t *pte) 863static int spurious_fault_check(unsigned long error_code, pte_t *pte)
@@ -1133,19 +1148,9 @@ good_area:
1133 */ 1148 */
1134 fault = handle_mm_fault(mm, vma, address, flags); 1149 fault = handle_mm_fault(mm, vma, address, flags);
1135 1150
1136 if (unlikely(fault & VM_FAULT_ERROR)) { 1151 if (unlikely(fault & (VM_FAULT_RETRY|VM_FAULT_ERROR))) {
1137 mm_fault_error(regs, error_code, address, fault); 1152 if (mm_fault_error(regs, error_code, address, fault))
1138 return; 1153 return;
1139 }
1140
1141 /*
1142 * Pagefault was interrupted by SIGKILL. We have no reason to
1143 * continue pagefault.
1144 */
1145 if ((fault & VM_FAULT_RETRY) && fatal_signal_pending(current)) {
1146 if (!(error_code & PF_USER))
1147 no_context(regs, error_code, address);
1148 return;
1149 } 1154 }
1150 1155
1151 /* 1156 /*