OOM, PM: OOM killed task shouldn't escape PM suspend
[platform/adaptation/renesas_rcar/renesas_kernel.git] / mm / nommu.c
index 8740213..3ee4f74 100644 (file)
@@ -15,6 +15,7 @@
 
 #include <linux/export.h>
 #include <linux/mm.h>
+#include <linux/vmacache.h>
 #include <linux/mman.h>
 #include <linux/swap.h>
 #include <linux/file.h>
@@ -768,16 +769,23 @@ static void add_vma_to_mm(struct mm_struct *mm, struct vm_area_struct *vma)
  */
 static void delete_vma_from_mm(struct vm_area_struct *vma)
 {
+       int i;
        struct address_space *mapping;
        struct mm_struct *mm = vma->vm_mm;
+       struct task_struct *curr = current;
 
        kenter("%p", vma);
 
        protect_vma(vma, 0);
 
        mm->map_count--;
-       if (mm->mmap_cache == vma)
-               mm->mmap_cache = NULL;
+       for (i = 0; i < VMACACHE_SIZE; i++) {
+               /* if the vma is cached, invalidate the entire cache */
+               if (curr->vmacache[i] == vma) {
+                       vmacache_invalidate(curr->mm);
+                       break;
+               }
+       }
 
        /* remove the VMA from the mapping */
        if (vma->vm_file) {
@@ -825,8 +833,8 @@ struct vm_area_struct *find_vma(struct mm_struct *mm, unsigned long addr)
        struct vm_area_struct *vma;
 
        /* check the cache first */
-       vma = ACCESS_ONCE(mm->mmap_cache);
-       if (vma && vma->vm_start <= addr && vma->vm_end > addr)
+       vma = vmacache_find(mm, addr);
+       if (likely(vma))
                return vma;
 
        /* trawl the list (there may be multiple mappings in which addr
@@ -835,7 +843,7 @@ struct vm_area_struct *find_vma(struct mm_struct *mm, unsigned long addr)
                if (vma->vm_start > addr)
                        return NULL;
                if (vma->vm_end > addr) {
-                       mm->mmap_cache = vma;
+                       vmacache_update(addr, vma);
                        return vma;
                }
        }
@@ -874,8 +882,8 @@ static struct vm_area_struct *find_vma_exact(struct mm_struct *mm,
        unsigned long end = addr + len;
 
        /* check the cache first */
-       vma = mm->mmap_cache;
-       if (vma && vma->vm_start == addr && vma->vm_end == end)
+       vma = vmacache_find_exact(mm, addr, end);
+       if (vma)
                return vma;
 
        /* trawl the list (there may be multiple mappings in which addr
@@ -886,7 +894,7 @@ static struct vm_area_struct *find_vma_exact(struct mm_struct *mm,
                if (vma->vm_start > addr)
                        return NULL;
                if (vma->vm_end == end) {
-                       mm->mmap_cache = vma;
+                       vmacache_update(addr, vma);
                        return vma;
                }
        }