Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

KOSAKI Motohiro and committed by
Ingo Molnar
b80ef10e de66ee97

+20 -15
+20 -15
arch/x86/mm/fault.c
··· 823 823 force_sig_info_fault(SIGBUS, code, address, tsk, fault); 824 824 } 825 825 826 - static noinline void 826 + static noinline int 827 827 mm_fault_error(struct pt_regs *regs, unsigned long error_code, 828 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 844 if (fault & VM_FAULT_OOM) { 831 845 /* Kernel mode? Handle exceptions or die: */ 832 846 if (!(error_code & PF_USER)) { 833 847 up_read(&current->mm->mmap_sem); 834 848 no_context(regs, error_code, address); 835 - return; 849 + return 1; 836 850 } 837 851 838 852 out_of_memory(regs, error_code, address); ··· 857 843 else 858 844 BUG(); 859 845 } 846 + return 1; 860 847 } 861 848 862 849 static int spurious_fault_check(unsigned long error_code, pte_t *pte) ··· 1148 1133 */ 1149 1134 fault = handle_mm_fault(mm, vma, address, flags); 1150 1135 1151 - if (unlikely(fault & VM_FAULT_ERROR)) { 1152 - mm_fault_error(regs, error_code, address, fault); 1153 - return; 1154 - } 1155 - 1156 - /* 1157 - * Pagefault was interrupted by SIGKILL. We have no reason to 1158 - * continue pagefault. 1159 - */ 1160 - if ((fault & VM_FAULT_RETRY) && fatal_signal_pending(current)) { 1161 - if (!(error_code & PF_USER)) 1162 - no_context(regs, error_code, address); 1163 - return; 1136 + if (unlikely(fault & (VM_FAULT_RETRY|VM_FAULT_ERROR))) { 1137 + if (mm_fault_error(regs, error_code, address, fault)) 1138 + return; 1164 1139 } 1165 1140 1166 1141 /*