Skip to content

Commit

Permalink
nios2: Port OOM changes to do_page_fault()
Browse files Browse the repository at this point in the history
Commit d065bd8 ("mm: retry page fault when blocking on disk transfer") and
and commit 37b23e0 ("x86,mm: make pagefault killable")

The above commits introduced changes into the nios2 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.

Signed-off-by: Ley Foon Tan <[email protected]>
  • Loading branch information
Ley Foon Tan committed Feb 9, 2015
1 parent ad7ef26 commit 96f3a5c
Showing 1 changed file with 32 additions and 5 deletions.
37 changes: 32 additions & 5 deletions arch/nios2/mm/fault.c
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long cause,
struct mm_struct *mm = tsk->mm;
int code = SEGV_MAPERR;
int fault;
unsigned int flags = 0;
unsigned int flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE;

cause >>= 2;

Expand Down Expand Up @@ -86,6 +86,7 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long cause,
if (!down_read_trylock(&mm->mmap_sem)) {
if (!user_mode(regs) && !search_exception_tables(regs->ea))
goto bad_area_nosemaphore;
retry:
down_read(&mm->mmap_sem);
}

Expand Down Expand Up @@ -132,6 +133,10 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long cause,
* the fault.
*/
fault = handle_mm_fault(mm, vma, address, flags);

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;
Expand All @@ -141,10 +146,32 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long cause,
goto do_sigbus;
BUG();
}
if (fault & VM_FAULT_MAJOR)
tsk->maj_flt++;
else
tsk->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;
flags |= FAULT_FLAG_TRIED;

/*
* 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;
Expand Down

0 comments on commit 96f3a5c

Please sign in to comment.