m68k/mm/fault.c: Port OOM changes to do_page_fault
PATCH v2 7/19 m68k/mm/fault.c: Port OOM changes to do_page_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 m68k.
Signed-off-by Kautuk Consul <[email protected]>
Acked-by <Geert Uytterhoeven <[email protected]>
--- arch/m68k/mm/fault.c | 40 ++++++++++++++++++++++++++++++++-------- 1 files changed, 32 insertions(+), 8 deletions(-)
arch/m68k/mm/fault.c +32 -8
@@ -72,7 +72,8 @@ int do_page_fault(struct pt_regs *regs, unsigned long address, {struct mm_struct *mm = current->mm;struct vm_area_struct * vma; -int write, fault; +int fault; +unsigned int flags =FAULT_FLAG_ALLOW_RETRY |FAULT_FLAG_KILLABLE ;#ifdef DEBUG printk ("do page fault:\nregs->sr=%#x, regs->pc=%#lx, address=%#lx, %ld, %p\n",
@@ -87,6 +88,7 @@ int do_page_fault(struct pt_regs *regs, unsigned long address,if (in_atomic () || !mm) goto no_context; +retry:down_read (&mm->mmap_sem); vma =find_vma (mm, address);
@@ -117,14 +119,13 @@ good_area:#ifdef DEBUG printk ("do_page_fault: good_area\n" );#endif - write =0 ;switch (error_code &3 ) {default :/* 3: write, present */ /* fall through */ case 2 :/* write, not present */ if (!(vma->vm_flags &VM_WRITE )) goto acc_err; - write++; + flags |=FAULT_FLAG_WRITE ;break ;case 1 :/* read, present */ goto acc_err;
@@ -139,10 +140,14 @@ good_area:* the fault. */ - fault =handle_mm_fault (mm, vma, address, write ?FAULT_FLAG_WRITE :0 ); + fault =handle_mm_fault (mm, vma, address, flags);#ifdef DEBUG printk ("handle_mm_fault returns %d\n" ,fault);#endif + +if ((fault &VM_FAULT_RETRY ) &&fatal_signal_pending (current)) +return 0 ; +if (unlikely (fault &VM_FAULT_ERROR )) {if (fault &VM_FAULT_OOM ) goto out_of_memory;
@@ -150,10 +155,29 @@ good_area: goto bus_err;BUG (); } -if (fault &VM_FAULT_MAJOR ) - current->maj_flt++; -else - current->min_flt++; + +/* Major/minor page fault accounting is only done on the +* initial attempt. If we go through a retry, it is extremely +* likely that the page will be found in page cache at that point. +*/ +if (flags &FAULT_FLAG_ALLOW_RETRY ) { +if (fault &VM_FAULT_MAJOR ) + current->maj_flt++; +else + current->min_flt++; +if (fault &VM_FAULT_RETRY ) { +/* Clear FAULT_FLAG_ALLOW_RETRY to avoid any risk +* of starvation. */ + 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);return 0 ;
Signature · 1 line
1.7.5.4