Merge branch 'for-5.11/elecom' into for-linus
[linux-2.6-microblaze.git] / mm / migrate.c
index 5ca5842..5795cb8 100644 (file)
@@ -1328,34 +1328,38 @@ static int unmap_and_move_huge_page(new_page_t get_new_page,
                goto put_anon;
 
        if (page_mapped(hpage)) {
-               /*
-                * try_to_unmap could potentially call huge_pmd_unshare.
-                * Because of this, take semaphore in write mode here and
-                * set TTU_RMAP_LOCKED to let lower levels know we have
-                * taken the lock.
-                */
-               mapping = hugetlb_page_mapping_lock_write(hpage);
-               if (unlikely(!mapping))
-                       goto unlock_put_anon;
+               bool mapping_locked = false;
+               enum ttu_flags ttu = TTU_MIGRATION|TTU_IGNORE_MLOCK|
+                                       TTU_IGNORE_ACCESS;
+
+               if (!PageAnon(hpage)) {
+                       /*
+                        * In shared mappings, try_to_unmap could potentially
+                        * call huge_pmd_unshare.  Because of this, take
+                        * semaphore in write mode here and set TTU_RMAP_LOCKED
+                        * to let lower levels know we have taken the lock.
+                        */
+                       mapping = hugetlb_page_mapping_lock_write(hpage);
+                       if (unlikely(!mapping))
+                               goto unlock_put_anon;
+
+                       mapping_locked = true;
+                       ttu |= TTU_RMAP_LOCKED;
+               }
 
-               try_to_unmap(hpage,
-                       TTU_MIGRATION|TTU_IGNORE_MLOCK|TTU_IGNORE_ACCESS|
-                       TTU_RMAP_LOCKED);
+               try_to_unmap(hpage, ttu);
                page_was_mapped = 1;
-               /*
-                * Leave mapping locked until after subsequent call to
-                * remove_migration_ptes()
-                */
+
+               if (mapping_locked)
+                       i_mmap_unlock_write(mapping);
        }
 
        if (!page_mapped(hpage))
                rc = move_to_new_page(new_hpage, hpage, mode);
 
-       if (page_was_mapped) {
+       if (page_was_mapped)
                remove_migration_ptes(hpage,
-                       rc == MIGRATEPAGE_SUCCESS ? new_hpage : hpage, true);
-               i_mmap_unlock_write(mapping);
-       }
+                       rc == MIGRATEPAGE_SUCCESS ? new_hpage : hpage, false);
 
 unlock_put_anon:
        unlock_page(new_hpage);