diff options
author | Mark Brown <broonie@kernel.org> | 2014-11-21 18:53:32 +0000 |
---|---|---|
committer | Mark Brown <broonie@kernel.org> | 2014-11-21 18:53:32 +0000 |
commit | 42f11d14ce8d2d9ac2b8044b97522fbe51642468 (patch) | |
tree | 9dd1766c16664dbd2b4250ef8d1537ea4958ad3e /mm/memory.c | |
parent | 7ce02d568e2acb97373fa675ceaeb556ed8e7835 (diff) | |
parent | 09cc926e9a6002790e69ed213217ef9874888624 (diff) |
Merge branch 'linux-linaro-lsk' into linux-linaro-lsk-rt
Diffstat (limited to 'mm/memory.c')
-rw-r--r-- | mm/memory.c | 49 |
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. |