Messages in this thread Patch in this message | | | Date | Wed, 8 Apr 2009 13:02:43 -0700 | Subject | [PATCH][2/2]page_fault retry with NOPAGE_RETRY | From | Ying Han <> |
| |
x86 support:
Signed-off-by: Ying Han <yinghan@google.com> Mike Waychison <mikew@google.com>
arch/x86/mm/fault.c | 20 ++++++++++++++
diff --git a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c index 31e8730..0ec60a1 100644 --- a/arch/x86/mm/fault.c +++ b/arch/x86/mm/fault.c @@ -591,6 +591,7 @@ void __kprobes do_page_fault(struct pt_regs *regs, unsigne #ifdef CONFIG_X86_64 unsigned long flags; #endif + unsigned int retry_flag = FAULT_FLAG_RETRY;
tsk = current; mm = tsk->mm; @@ -689,6 +690,7 @@ again: down_read(&mm->mmap_sem); }
+retry: vma = find_vma(mm, address); if (!vma) goto bad_area; @@ -715,6 +717,7 @@ again: good_area: si_code = SEGV_ACCERR; write = 0; + write |= retry_flag; switch (error_code & (PF_PROT|PF_WRITE)) { default: /* 3: write, present */ /* fall through */ @@ -743,6 +746,23 @@ good_area: goto do_sigbus; BUG(); } + + /* + * Here we retry fault once and switch to synchronous mode. The + * main reason is to prevent us from the cases of starvation. + * The retry logic open a starvation hole in which case pages might + * be removed or changed after the retry. + */ + if (fault & VM_FAULT_RETRY) { + if (write & FAULT_FLAG_RETRY) { + retry_flag &= ~FAULT_FLAG_RETRY; + tsk->maj_flt++; + tsk->min_flt--; + goto retry; + } + BUG(); + } + if (fault & VM_FAULT_MAJOR) tsk->maj_flt++; else
| |