You've already forked linux-apfs
mirror of
https://github.com/linux-apfs/linux-apfs.git
synced 2026-05-01 15:00:59 -07:00
sparc/mm/fault_64.c: Port OOM changes to do_sparc64_fault
Commitd065bd810b(mm: retry page fault when blocking on disk transfer) and commit37b23e0525(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. Signed-off-by: Kautuk Consul <consul.kautuk@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
committed by
David S. Miller
parent
64ebe98731
commit
7358e51082
@@ -279,6 +279,7 @@ asmlinkage void __kprobes do_sparc64_fault(struct pt_regs *regs)
|
|||||||
unsigned int insn = 0;
|
unsigned int insn = 0;
|
||||||
int si_code, fault_code, fault;
|
int si_code, fault_code, fault;
|
||||||
unsigned long address, mm_rss;
|
unsigned long address, mm_rss;
|
||||||
|
unsigned int flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE;
|
||||||
|
|
||||||
fault_code = get_thread_fault_code();
|
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);
|
insn = get_fault_insn(regs, insn);
|
||||||
goto handle_kernel_fault;
|
goto handle_kernel_fault;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
retry:
|
||||||
down_read(&mm->mmap_sem);
|
down_read(&mm->mmap_sem);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -423,7 +426,12 @@ good_area:
|
|||||||
goto bad_area;
|
goto bad_area;
|
||||||
}
|
}
|
||||||
|
|
||||||
fault = handle_mm_fault(mm, vma, address, (fault_code & FAULT_CODE_WRITE) ? FAULT_FLAG_WRITE : 0);
|
flags |= ((fault_code & FAULT_CODE_WRITE) ? FAULT_FLAG_WRITE : 0);
|
||||||
|
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 (unlikely(fault & VM_FAULT_ERROR)) {
|
||||||
if (fault & VM_FAULT_OOM)
|
if (fault & VM_FAULT_OOM)
|
||||||
goto out_of_memory;
|
goto out_of_memory;
|
||||||
@@ -431,12 +439,27 @@ good_area:
|
|||||||
goto do_sigbus;
|
goto do_sigbus;
|
||||||
BUG();
|
BUG();
|
||||||
}
|
}
|
||||||
if (fault & VM_FAULT_MAJOR) {
|
|
||||||
current->maj_flt++;
|
if (flags & FAULT_FLAG_ALLOW_RETRY) {
|
||||||
perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MAJ, 1, regs, address);
|
if (fault & VM_FAULT_MAJOR) {
|
||||||
} else {
|
current->maj_flt++;
|
||||||
current->min_flt++;
|
perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MAJ,
|
||||||
perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MIN, 1, regs, address);
|
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);
|
up_read(&mm->mmap_sem);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user