tools headers UAPI: Sync linux/prctl.h with the kernel sources
[linux-2.6-microblaze.git] / mm / migrate.c
index 47df0df..b234c3f 100644 (file)
 
 #include "internal.h"
 
-/*
- * migrate_prep() needs to be called before we start compiling a list of pages
- * to be migrated using isolate_lru_page(). If scheduling work on other CPUs is
- * undesirable, use migrate_prep_local()
- */
-void migrate_prep(void)
-{
-       /*
-        * Clear the LRU lists so pages can be isolated.
-        * Note that pages may be moved off the LRU after we have
-        * drained them. Those pages will fail to migrate like other
-        * pages that may be busy.
-        */
-       lru_add_drain_all();
-}
-
-/* Do the necessary work of migrate_prep but not if it involves other CPUs */
-void migrate_prep_local(void)
-{
-       lru_add_drain();
-}
-
 int isolate_movable_page(struct page *page, isolate_mode_t mode)
 {
        struct address_space *mapping;
@@ -140,15 +118,10 @@ out:
        return -EBUSY;
 }
 
-/* It should be called on page which is PG_movable */
-void putback_movable_page(struct page *page)
+static void putback_movable_page(struct page *page)
 {
        struct address_space *mapping;
 
-       VM_BUG_ON_PAGE(!PageLocked(page), page);
-       VM_BUG_ON_PAGE(!PageMovable(page), page);
-       VM_BUG_ON_PAGE(!PageIsolated(page), page);
-
        mapping = page_mapping(page);
        mapping->a_ops->putback_page(page);
        __ClearPageIsolated(page);
@@ -1375,7 +1348,7 @@ out_unlock:
 out:
        if (rc == MIGRATEPAGE_SUCCESS)
                putback_active_hugepage(hpage);
-       else if (rc != -EAGAIN && rc != MIGRATEPAGE_SUCCESS)
+       else if (rc != -EAGAIN)
                list_move_tail(&hpage->lru, ret);
 
        /*
@@ -1445,6 +1418,8 @@ int migrate_pages(struct list_head *from, new_page_t get_new_page,
        int rc, nr_subpages;
        LIST_HEAD(ret_pages);
 
+       trace_mm_migrate_pages_start(mode, reason);
+
        if (!swapwrite)
                current->flags |= PF_SWAPWRITE;
 
@@ -1769,7 +1744,7 @@ static int do_pages_move(struct mm_struct *mm, nodemask_t task_nodes,
        int start, i;
        int err = 0, err1;
 
-       migrate_prep();
+       lru_cache_disable();
 
        for (i = start = 0; i < nr_pages; i++) {
                const void __user *p;
@@ -1838,6 +1813,7 @@ out_flush:
        if (err >= 0)
                err = err1;
 out:
+       lru_cache_enable();
        return err;
 }
 
@@ -2110,17 +2086,6 @@ bool pmd_trans_migrating(pmd_t pmd)
        return PageLocked(page);
 }
 
-static inline bool is_shared_exec_page(struct vm_area_struct *vma,
-                                      struct page *page)
-{
-       if (page_mapcount(page) != 1 &&
-           (page_is_file_lru(page) || vma_is_shmem(vma)) &&
-           (vma->vm_flags & VM_EXEC))
-               return true;
-
-       return false;
-}
-
 /*
  * Attempt to migrate a misplaced page to the specified destination
  * node. Caller is expected to have an elevated reference count on
@@ -2138,7 +2103,8 @@ int migrate_misplaced_page(struct page *page, struct vm_area_struct *vma,
         * Don't migrate file pages that are mapped in multiple processes
         * with execute permissions as they are probably shared libraries.
         */
-       if (is_shared_exec_page(vma, page))
+       if (page_mapcount(page) != 1 && page_is_file_lru(page) &&
+           (vma->vm_flags & VM_EXEC))
                goto out;
 
        /*
@@ -2193,9 +2159,6 @@ int migrate_misplaced_transhuge_page(struct mm_struct *mm,
        int page_lru = page_is_file_lru(page);
        unsigned long start = address & HPAGE_PMD_MASK;
 
-       if (is_shared_exec_page(vma, page))
-               goto out;
-
        new_page = alloc_pages_node(node,
                (GFP_TRANSHUGE_LIGHT | __GFP_THISNODE),
                HPAGE_PMD_ORDER);
@@ -2307,7 +2270,6 @@ out_fail:
 
 out_unlock:
        unlock_page(page);
-out:
        put_page(page);
        return 0;
 }
@@ -2316,44 +2278,38 @@ out:
 #endif /* CONFIG_NUMA */
 
 #ifdef CONFIG_DEVICE_PRIVATE
-static int migrate_vma_collect_hole(unsigned long start,
+static int migrate_vma_collect_skip(unsigned long start,
                                    unsigned long end,
-                                   __always_unused int depth,
                                    struct mm_walk *walk)
 {
        struct migrate_vma *migrate = walk->private;
        unsigned long addr;
 
-       /* Only allow populating anonymous memory. */
-       if (!vma_is_anonymous(walk->vma)) {
-               for (addr = start; addr < end; addr += PAGE_SIZE) {
-                       migrate->src[migrate->npages] = 0;
-                       migrate->dst[migrate->npages] = 0;
-                       migrate->npages++;
-               }
-               return 0;
-       }
-
        for (addr = start; addr < end; addr += PAGE_SIZE) {
-               migrate->src[migrate->npages] = MIGRATE_PFN_MIGRATE;
                migrate->dst[migrate->npages] = 0;
-               migrate->npages++;
-               migrate->cpages++;
+               migrate->src[migrate->npages++] = 0;
        }
 
        return 0;
 }
 
-static int migrate_vma_collect_skip(unsigned long start,
+static int migrate_vma_collect_hole(unsigned long start,
                                    unsigned long end,
+                                   __always_unused int depth,
                                    struct mm_walk *walk)
 {
        struct migrate_vma *migrate = walk->private;
        unsigned long addr;
 
+       /* Only allow populating anonymous memory. */
+       if (!vma_is_anonymous(walk->vma))
+               return migrate_vma_collect_skip(start, end, walk);
+
        for (addr = start; addr < end; addr += PAGE_SIZE) {
+               migrate->src[migrate->npages] = MIGRATE_PFN_MIGRATE;
                migrate->dst[migrate->npages] = 0;
-               migrate->src[migrate->npages++] = 0;
+               migrate->npages++;
+               migrate->cpages++;
        }
 
        return 0;
@@ -2823,11 +2779,11 @@ restore:
  *
  * For empty entries inside CPU page table (pte_none() or pmd_none() is true) we
  * do set MIGRATE_PFN_MIGRATE flag inside the corresponding source array thus
- * allowing the caller to allocate device memory for those unback virtual
- * address.  For this the caller simply has to allocate device memory and
+ * allowing the caller to allocate device memory for those unbacked virtual
+ * addresses.  For this the caller simply has to allocate device memory and
  * properly set the destination entry like for regular migration.  Note that
- * this can still fails and thus inside the device driver must check if the
- * migration was successful for those entries after calling migrate_vma_pages()
+ * this can still fail, and thus inside the device driver you must check if the
+ * migration was successful for those entries after calling migrate_vma_pages(),
  * just like for regular migration.
  *
  * After that, the callers must call migrate_vma_pages() to go over each entry
@@ -2973,6 +2929,13 @@ static void migrate_vma_insert_page(struct migrate_vma *migrate,
 
                        swp_entry = make_device_private_entry(page, vma->vm_flags & VM_WRITE);
                        entry = swp_entry_to_pte(swp_entry);
+               } else {
+                       /*
+                        * For now we only support migrating to un-addressable
+                        * device memory.
+                        */
+                       pr_warn_once("Unsupported ZONE_DEVICE page type.\n");
+                       goto abort;
                }
        } else {
                entry = mk_pte(page, vma->vm_page_prot);