mm: Export migrate_page_move_mapping and migrate_page_copy
[pandora-kernel.git] / mm / migrate.c
index 180d97f..f2d86f2 100644 (file)
@@ -141,13 +141,16 @@ static int remove_migration_pte(struct page *new, struct vm_area_struct *vma,
 
        get_page(new);
        pte = pte_mkold(mk_pte(new, vma->vm_page_prot));
+
+       /* Recheck VMA as permissions can change since migration started  */
        if (is_write_migration_entry(entry))
-               pte = pte_mkwrite(pte);
+               pte = maybe_mkwrite(pte, vma);
+
 #ifdef CONFIG_HUGETLB_PAGE
        if (PageHuge(new))
                pte = pte_mkhuge(pte);
 #endif
-       flush_cache_page(vma, addr, pte_pfn(pte));
+       flush_dcache_page(new);
        set_pte_at(mm, addr, ptep, pte);
 
        if (PageHuge(new)) {
@@ -184,15 +187,14 @@ static void remove_migration_ptes(struct page *old, struct page *new)
  *
  * This function is called from do_swap_page().
  */
-void migration_entry_wait(struct mm_struct *mm, pmd_t *pmd,
-                               unsigned long address)
+static void __migration_entry_wait(struct mm_struct *mm, pte_t *ptep,
+                               spinlock_t *ptl)
 {
-       pte_t *ptep, pte;
-       spinlock_t *ptl;
+       pte_t pte;
        swp_entry_t entry;
        struct page *page;
 
-       ptep = pte_offset_map_lock(mm, pmd, address, &ptl);
+       spin_lock(ptl);
        pte = *ptep;
        if (!is_swap_pte(pte))
                goto out;
@@ -220,6 +222,20 @@ out:
        pte_unmap_unlock(ptep, ptl);
 }
 
+void migration_entry_wait(struct mm_struct *mm, pmd_t *pmd,
+                               unsigned long address)
+{
+       spinlock_t *ptl = pte_lockptr(mm, pmd);
+       pte_t *ptep = pte_offset_map(pmd, address);
+       __migration_entry_wait(mm, ptep, ptl);
+}
+
+void migration_entry_wait_huge(struct mm_struct *mm, pte_t *pte)
+{
+       spinlock_t *ptl = &(mm)->page_table_lock;
+       __migration_entry_wait(mm, pte, ptl);
+}
+
 #ifdef CONFIG_BLOCK
 /* Returns true if all buffers are successfully locked */
 static bool buffer_migrate_lock_buffers(struct buffer_head *head,
@@ -278,7 +294,7 @@ static inline bool buffer_migrate_lock_buffers(struct buffer_head *head,
  * 2 for pages with a mapping
  * 3 for pages with a mapping and PagePrivate/PagePrivate2 set.
  */
-static int migrate_page_move_mapping(struct address_space *mapping,
+int migrate_page_move_mapping(struct address_space *mapping,
                struct page *newpage, struct page *page,
                struct buffer_head *head, enum migrate_mode mode)
 {
@@ -361,6 +377,7 @@ static int migrate_page_move_mapping(struct address_space *mapping,
 
        return 0;
 }
+EXPORT_SYMBOL(migrate_page_move_mapping);
 
 /*
  * The expected number of remaining references is the same as that
@@ -460,6 +477,7 @@ void migrate_page_copy(struct page *newpage, struct page *page)
        if (PageWriteback(newpage))
                end_page_writeback(newpage);
 }
+EXPORT_SYMBOL(migrate_page_copy);
 
 /************************************************************
  *                    Migration functions