mm: madvise: fix MADV_WILLNEED on shmem swapouts
[platform/adaptation/renesas_rcar/renesas_kernel.git] / mm / rmap.c
index 962e2a1..cdbd312 100644 (file)
--- a/mm/rmap.c
+++ b/mm/rmap.c
@@ -103,6 +103,7 @@ static inline void anon_vma_free(struct anon_vma *anon_vma)
         * LOCK should suffice since the actual taking of the lock must
         * happen _before_ what follows.
         */
+       might_sleep();
        if (rwsem_is_locked(&anon_vma->root->rwsem)) {
                anon_vma_lock_write(anon_vma);
                anon_vma_unlock_write(anon_vma);
@@ -426,8 +427,9 @@ struct anon_vma *page_get_anon_vma(struct page *page)
         * above cannot corrupt).
         */
        if (!page_mapped(page)) {
+               rcu_read_unlock();
                put_anon_vma(anon_vma);
-               anon_vma = NULL;
+               return NULL;
        }
 out:
        rcu_read_unlock();
@@ -477,9 +479,9 @@ struct anon_vma *page_lock_anon_vma_read(struct page *page)
        }
 
        if (!page_mapped(page)) {
+               rcu_read_unlock();
                put_anon_vma(anon_vma);
-               anon_vma = NULL;
-               goto out;
+               return NULL;
        }
 
        /* we pinned the anon_vma, its safe to sleep */
@@ -848,9 +850,9 @@ out:
 static bool invalid_mkclean_vma(struct vm_area_struct *vma, void *arg)
 {
        if (vma->vm_flags & VM_SHARED)
-               return 0;
+               return false;
 
-       return 1;
+       return true;
 }
 
 int page_mkclean(struct page *page)
@@ -894,9 +896,9 @@ void page_move_anon_rmap(struct page *page,
 {
        struct anon_vma *anon_vma = vma->anon_vma;
 
-       VM_BUG_ON(!PageLocked(page));
+       VM_BUG_ON_PAGE(!PageLocked(page), page);
        VM_BUG_ON(!anon_vma);
-       VM_BUG_ON(page->index != linear_page_index(vma, address));
+       VM_BUG_ON_PAGE(page->index != linear_page_index(vma, address), page);
 
        anon_vma = (void *) anon_vma + PAGE_MAPPING_ANON;
        page->mapping = (struct address_space *) anon_vma;
@@ -995,7 +997,7 @@ void do_page_add_anon_rmap(struct page *page,
        if (unlikely(PageKsm(page)))
                return;
 
-       VM_BUG_ON(!PageLocked(page));
+       VM_BUG_ON_PAGE(!PageLocked(page), page);
        /* address might be in next vma when migration races vma_adjust */
        if (first)
                __page_set_anon_rmap(page, vma, address, exclusive);
@@ -1322,9 +1324,19 @@ static int try_to_unmap_cluster(unsigned long cursor, unsigned int *mapcount,
                BUG_ON(!page || PageAnon(page));
 
                if (locked_vma) {
-                       mlock_vma_page(page);   /* no-op if already mlocked */
-                       if (page == check_page)
+                       if (page == check_page) {
+                               /* we know we have check_page locked */
+                               mlock_vma_page(page);
                                ret = SWAP_MLOCK;
+                       } else if (trylock_page(page)) {
+                               /*
+                                * If we can lock the page, perform mlock.
+                                * Otherwise leave the page alone, it will be
+                                * eventually encountered again later.
+                                */
+                               mlock_vma_page(page);
+                               unlock_page(page);
+                       }
                        continue;       /* don't unmap */
                }
 
@@ -1360,8 +1372,9 @@ static int try_to_unmap_cluster(unsigned long cursor, unsigned int *mapcount,
 }
 
 static int try_to_unmap_nonlinear(struct page *page,
-               struct address_space *mapping, struct vm_area_struct *vma)
+               struct address_space *mapping, void *arg)
 {
+       struct vm_area_struct *vma;
        int ret = SWAP_AGAIN;
        unsigned long cursor;
        unsigned long max_nl_cursor = 0;
@@ -1481,7 +1494,7 @@ int try_to_unmap(struct page *page, enum ttu_flags flags)
                .anon_lock = page_lock_anon_vma_read,
        };
 
-       VM_BUG_ON(!PageHuge(page) && PageTransHuge(page));
+       VM_BUG_ON_PAGE(!PageHuge(page) && PageTransHuge(page), page);
 
        /*
         * During exec, a temporary VMA is setup and later moved.
@@ -1533,7 +1546,7 @@ int try_to_munlock(struct page *page)
 
        };
 
-       VM_BUG_ON(!PageLocked(page) || PageLRU(page));
+       VM_BUG_ON_PAGE(!PageLocked(page) || PageLRU(page), page);
 
        ret = rmap_walk(page, &rwc);
        return ret;
@@ -1543,10 +1556,9 @@ void __put_anon_vma(struct anon_vma *anon_vma)
 {
        struct anon_vma *root = anon_vma->root;
 
+       anon_vma_free(anon_vma);
        if (root != anon_vma && atomic_dec_and_test(&root->refcount))
                anon_vma_free(root);
-
-       anon_vma_free(anon_vma);
 }
 
 static struct anon_vma *rmap_walk_anon_lock(struct page *page,
@@ -1663,7 +1675,7 @@ static int rmap_walk_file(struct page *page, struct rmap_walk_control *rwc)
        if (list_empty(&mapping->i_mmap_nonlinear))
                goto done;
 
-       ret = rwc->file_nonlinear(page, mapping, vma);
+       ret = rwc->file_nonlinear(page, mapping, rwc->arg);
 
 done:
        mutex_unlock(&mapping->i_mmap_mutex);