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

microblaze: 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 microblaze.

Signed-off-by: Kautuk Consul <consul.kautuk@gmail.com>

authored by

Kautuk Consul and committed by
Michal Simek
f397c077 59516b07

+28 -5
+28 -5
arch/microblaze/mm/fault.c
··· 92 92 int code = SEGV_MAPERR; 93 93 int is_write = error_code & ESR_S; 94 94 int fault; 95 + unsigned int flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE | 96 + (is_write ? FAULT_FLAG_WRITE : 0); 95 97 96 98 regs->ear = address; 97 99 regs->esr = error_code; ··· 140 138 if (kernel_mode(regs) && !search_exception_tables(regs->pc)) 141 139 goto bad_area_nosemaphore; 142 140 141 + retry: 143 142 down_read(&mm->mmap_sem); 144 143 } 145 144 ··· 213 210 * make sure we exit gracefully rather than endlessly redo 214 211 * the fault. 215 212 */ 216 - fault = handle_mm_fault(mm, vma, address, is_write ? FAULT_FLAG_WRITE : 0); 213 + fault = handle_mm_fault(mm, vma, address, flags); 214 + 215 + if ((fault & VM_FAULT_RETRY) && fatal_signal_pending(current)) 216 + return; 217 + 217 218 if (unlikely(fault & VM_FAULT_ERROR)) { 218 219 if (fault & VM_FAULT_OOM) 219 220 goto out_of_memory; ··· 225 218 goto do_sigbus; 226 219 BUG(); 227 220 } 228 - if (unlikely(fault & VM_FAULT_MAJOR)) 229 - current->maj_flt++; 230 - else 231 - current->min_flt++; 221 + 222 + if (flags & FAULT_FLAG_ALLOW_RETRY) { 223 + if (unlikely(fault & VM_FAULT_MAJOR)) 224 + current->maj_flt++; 225 + else 226 + current->min_flt++; 227 + if (fault & VM_FAULT_RETRY) { 228 + flags &= ~FAULT_FLAG_ALLOW_RETRY; 229 + 230 + /* 231 + * No need to up_read(&mm->mmap_sem) as we would 232 + * have already released it in __lock_page_or_retry 233 + * in mm/filemap.c. 234 + */ 235 + 236 + goto retry; 237 + } 238 + } 239 + 232 240 up_read(&mm->mmap_sem); 241 + 233 242 /* 234 243 * keep track of tlb+htab misses that are good addrs but 235 244 * just need pte's created via handle_mm_fault()