aboutsummaryrefslogtreecommitdiff
path: root/mm/memory.c
diff options
context:
space:
mode:
authorMark Brown <broonie@kernel.org>2014-11-21 18:53:32 +0000
committerMark Brown <broonie@kernel.org>2014-11-21 18:53:32 +0000
commit42f11d14ce8d2d9ac2b8044b97522fbe51642468 (patch)
tree9dd1766c16664dbd2b4250ef8d1537ea4958ad3e /mm/memory.c
parent7ce02d568e2acb97373fa675ceaeb556ed8e7835 (diff)
parent09cc926e9a6002790e69ed213217ef9874888624 (diff)
Merge branch 'linux-linaro-lsk' into linux-linaro-lsk-rt
Diffstat (limited to 'mm/memory.c')
-rw-r--r--mm/memory.c49
1 files changed, 39 insertions, 10 deletions
diff --git a/mm/memory.c b/mm/memory.c
index 5ab544ff26f1..02f8093be672 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -3782,22 +3782,14 @@ EXPORT_SYMBOL(pagefault_enable);
/*
* By the time we get here, we already hold the mm semaphore
*/
-int handle_mm_fault(struct mm_struct *mm, struct vm_area_struct *vma,
- unsigned long address, unsigned int flags)
+static int __handle_mm_fault(struct mm_struct *mm, struct vm_area_struct *vma,
+ unsigned long address, unsigned int flags)
{
pgd_t *pgd;
pud_t *pud;
pmd_t *pmd;
pte_t *pte;
- __set_current_state(TASK_RUNNING);
-
- count_vm_event(PGFAULT);
- mem_cgroup_count_vm_event(mm, PGFAULT);
-
- /* do counter updates before entering really critical section. */
- check_sync_rss_stat(current);
-
if (unlikely(is_vm_hugetlb_page(vma)))
return hugetlb_fault(mm, vma, address, flags);
@@ -3878,6 +3870,43 @@ retry:
return handle_pte_fault(mm, vma, address, pte, pmd, flags);
}
+int handle_mm_fault(struct mm_struct *mm, struct vm_area_struct *vma,
+ unsigned long address, unsigned int flags)
+{
+ int ret;
+
+ __set_current_state(TASK_RUNNING);
+
+ count_vm_event(PGFAULT);
+ mem_cgroup_count_vm_event(mm, PGFAULT);
+
+ /* do counter updates before entering really critical section. */
+ check_sync_rss_stat(current);
+
+ /*
+ * Enable the memcg OOM handling for faults triggered in user
+ * space. Kernel faults are handled more gracefully.
+ */
+ if (flags & FAULT_FLAG_USER)
+ mem_cgroup_oom_enable();
+
+ ret = __handle_mm_fault(mm, vma, address, flags);
+
+ if (flags & FAULT_FLAG_USER) {
+ mem_cgroup_oom_disable();
+ /*
+ * The task may have entered a memcg OOM situation but
+ * if the allocation error was handled gracefully (no
+ * VM_FAULT_OOM), there is no need to kill anything.
+ * Just clean up the OOM state peacefully.
+ */
+ if (task_in_memcg_oom(current) && !(ret & VM_FAULT_OOM))
+ mem_cgroup_oom_synchronize(false);
+ }
+
+ return ret;
+}
+
#ifndef __PAGETABLE_PUD_FOLDED
/*
* Allocate page upper directory.