sparc/mm/fault_64.c: Port OOM changes to do_sparc64_fault
PATCH v3 20/20 sparc/mm/fault_64.c: Port OOM changes to do_sparc64_fault
Commit d065bd810b6deb67d4897a14bfe21f8eb526ba99 (mm: retry page fault when blocking on disk transfer) and commit 37b23e0525d393d48a7d59f870b3bc061a30ccdb (x86,mm: make pagefault killable)
The above commits introduced changes into the x86 pagefault handler for making the page fault handler retryable as well as killable.
These changes reduce the mmap_sem hold time, which is crucial during OOM killer invocation.
Port these changes to 64-bit sparc.
--- arch/sparc/mm/fault_64.c | 38 +++++++++++++++++++++++++++++++------- 1 files changed, 31 insertions(+), 7 deletions(-)
arch/sparc/mm/fault_64.c +31 -7
@@ -279,6 +279,7 @@ asmlinkage void __kprobes do_sparc64_fault(struct pt_regs *regs)unsigned int insn =0 ;int si_code, fault_code, fault;unsigned long address, mm_rss; +unsigned int flags =FAULT_FLAG_ALLOW_RETRY |FAULT_FLAG_KILLABLE ; fault_code =get_thread_fault_code ();
@@ -333,6 +334,8 @@ asmlinkage void __kprobes do_sparc64_fault(struct pt_regs *regs) insn =get_fault_insn (regs, insn); goto handle_kernel_fault; } + +retry:down_read (&mm->mmap_sem); }
@@ -423,7 +426,13 @@ good_area: goto bad_area; } - fault =handle_mm_fault (mm, vma, address, (fault_code &FAULT_CODE_WRITE ) ?FAULT_FLAG_WRITE :0 ); + fault =handle_mm_fault (mm, vma, address, + flags | ((fault_code &FAULT_CODE_WRITE ) ? + FAULT_FLAG_WRITE : 0); + +if ((fault &VM_FAULT_RETRY ) &&fatal_signal_pending (current)) +return ; +if (unlikely (fault &VM_FAULT_ERROR )) {if (fault &VM_FAULT_OOM ) goto out_of_memory;
@@ -431,12 +440,27 @@ good_area: goto do_sigbus;BUG (); } -if (fault &VM_FAULT_MAJOR ) { - current->maj_flt++; -perf_sw_event (PERF_COUNT_SW_PAGE_FAULTS_MAJ ,1 , regs, address); - }else { - current->min_flt++; -perf_sw_event (PERF_COUNT_SW_PAGE_FAULTS_MIN ,1 , regs, address); + +if (flags &FAULT_FLAG_ALLOW_RETRY ) { +if (fault &VM_FAULT_MAJOR ) { + current->maj_flt++; +perf_sw_event (PERF_COUNT_SW_PAGE_FAULTS_MAJ , +1 , regs, address); + }else { + current->min_flt++; +perf_sw_event (PERF_COUNT_SW_PAGE_FAULTS_MIN , +1 , regs, address); + } +if (fault &VM_FAULT_RETRY ) { + flags &= ~FAULT_FLAG_ALLOW_RETRY ; + +/* No need to up_read(&mm->mmap_sem) as we would +* have already released it in __lock_page_or_retry +* in mm/filemap.c. +*/ + + goto retry; + } }up_read (&mm->mmap_sem);
Signature · 1 line
1.7.5.4
arch/sparc/mm/fault_64.c asmlinkage void __kprobes do_sparc64_fault(struct pt_regs *regs) · line 285
Quoted 12 lines · Kautuk Consul
arch/sparc/mm/fault_64.c +1
-0@@ -279,6 +279,7 @@ asmlinkage void __kprobes do_sparc64_fault(struct pt_regs *regs)unsigned int insn =0 ;int si_code, fault_code, fault;unsigned long address, mm_rss; +unsigned int flags =FAULT_FLAG_ALLOW_RETRY |FAULT_FLAG_KILLABLE ; fault_code =get_thread_fault_code ();
[]
arch/sparc/mm/fault_64.c good_area: · line 431
Quoted 8 lines
arch/sparc/mm/fault_64.c +3
-1@@ -423,7 +426,13 @@ good_area: goto bad_area; } - fault =handle_mm_fault (mm, vma, address, (fault_code &FAULT_CODE_WRITE ) ?FAULT_FLAG_WRITE :0 ); + fault =handle_mm_fault (mm, vma, address, + flags | ((fault_code &FAULT_CODE_WRITE ) ? + FAULT_FLAG_WRITE : 0);
A bit redundant and very poor style argument alignment Make sure your tab indentation is set to 8.
fault = handle_mm_fault(mm, vma, address, flags | (fault_code & FAULT_CODE_WRITE));
though perhaps fault_code could be unsigned and perhaps you could use the same style initializer for fault_code as patch 19/20.
Okay, I have sent both patches with tab-space as 8 characters and set the multiline C statements after the preceding line's paranthesis.
David Miller
maintainerFrom: Kautuk Consul <[email protected]>
Date: Mon, 26 Mar 2012 11:33:17 -0400
arch/sparc/mm/fault_64.c good_area: · line 431
Quoted 3 lines
arch/sparc/mm/fault_64.c +3
-0+ fault =handle_mm_fault (mm, vma, address, + flags | ((fault_code &FAULT_CODE_WRITE ) ? + FAULT_FLAG_WRITE : 0);
This is so shockingly gross I'm at a loss for words. Why are you tabbing this crap all the way into outer-space?
Make the "flags | ..." line up with the first column after the openning parenthesis of "handle_mm_fault(".
Review
Quoted 2 lines
(quoted diff) +2
-0+ perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MAJ, + 1, regs, address);
Same problem.
arch/sparc/mm/fault_64.c good_area: · line 452
Quoted 2 lines
arch/sparc/mm/fault_64.c +2
-0+perf_sw_event (PERF_COUNT_SW_PAGE_FAULTS_MIN , +1 , regs, address);
Same problem.
You're making the coding style worse each iteration, not better.