diff options
author | Kautuk Consul <consul.kautuk@gmail.com> | 2012-03-20 09:23:33 -0400 |
---|---|---|
committer | Richard Kuo <rkuo@codeaurora.org> | 2012-05-22 19:40:45 -0400 |
commit | 393a86af71b5bc6b11eac8e1594fb8be4c2ce84c (patch) | |
tree | 574fb994836c880a3949118890176d799384ae4d | |
parent | 222c547ee7155045dc20c26d39191b0e9b49f6a8 (diff) |
hexagon/mm/vm_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 hexagon.
Signed-off-by: Kautuk Consul <consul.kautuk@gmail.com>
Signed-off-by: Richard Kuo <rkuo@codeaurora.org>
-rw-r--r-- | arch/hexagon/mm/vm_fault.c | 22 |
1 files changed, 17 insertions, 5 deletions
diff --git a/arch/hexagon/mm/vm_fault.c b/arch/hexagon/mm/vm_fault.c index c10b76ff9d65..06695cc4fe58 100644 --- a/arch/hexagon/mm/vm_fault.c +++ b/arch/hexagon/mm/vm_fault.c | |||
@@ -53,6 +53,8 @@ void do_page_fault(unsigned long address, long cause, struct pt_regs *regs) | |||
53 | int si_code = SEGV_MAPERR; | 53 | int si_code = SEGV_MAPERR; |
54 | int fault; | 54 | int fault; |
55 | const struct exception_table_entry *fixup; | 55 | const struct exception_table_entry *fixup; |
56 | unsigned int flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE | | ||
57 | (cause > 0 ? FAULT_FLAG_WRITE : 0); | ||
56 | 58 | ||
57 | /* | 59 | /* |
58 | * If we're in an interrupt or have no user context, | 60 | * If we're in an interrupt or have no user context, |
@@ -63,6 +65,7 @@ void do_page_fault(unsigned long address, long cause, struct pt_regs *regs) | |||
63 | 65 | ||
64 | local_irq_enable(); | 66 | local_irq_enable(); |
65 | 67 | ||
68 | retry: | ||
66 | down_read(&mm->mmap_sem); | 69 | down_read(&mm->mmap_sem); |
67 | vma = find_vma(mm, address); | 70 | vma = find_vma(mm, address); |
68 | if (!vma) | 71 | if (!vma) |
@@ -96,14 +99,23 @@ good_area: | |||
96 | break; | 99 | break; |
97 | } | 100 | } |
98 | 101 | ||
99 | fault = handle_mm_fault(mm, vma, address, (cause > 0)); | 102 | fault = handle_mm_fault(mm, vma, address, flags); |
103 | |||
104 | if ((fault & VM_FAULT_RETRY) && fatal_signal_pending(current)) | ||
105 | return; | ||
100 | 106 | ||
101 | /* The most common case -- we are done. */ | 107 | /* The most common case -- we are done. */ |
102 | if (likely(!(fault & VM_FAULT_ERROR))) { | 108 | if (likely(!(fault & VM_FAULT_ERROR))) { |
103 | if (fault & VM_FAULT_MAJOR) | 109 | if (flags & FAULT_FLAG_ALLOW_RETRY) { |
104 | current->maj_flt++; | 110 | if (fault & VM_FAULT_MAJOR) |
105 | else | 111 | current->maj_flt++; |
106 | current->min_flt++; | 112 | else |
113 | current->min_flt++; | ||
114 | if (fault & VM_FAULT_RETRY) { | ||
115 | flags &= ~FAULT_FLAG_ALLOW_RETRY; | ||
116 | goto retry; | ||
117 | } | ||
118 | } | ||
107 | 119 | ||
108 | up_read(&mm->mmap_sem); | 120 | up_read(&mm->mmap_sem); |
109 | return; | 121 | return; |