if (current_nid == numa_node_id())
                count_vm_numa_event(NUMA_HINT_FAULTS_LOCAL);
 
-       target_nid = mpol_misplaced(page, vma, haddr);
-       if (target_nid == -1) {
-               put_page(page);
-               goto clear_pmdnuma;
-       }
+       /*
+        * Acquire the page lock to serialise THP migrations but avoid dropping
+        * page_table_lock if at all possible
+        */
+       if (trylock_page(page))
+               goto got_lock;
 
-       /* Acquire the page lock to serialise THP migrations */
+       /* Serialise against migrationa and check placement check placement */
        spin_unlock(&mm->page_table_lock);
        lock_page(page);
 
                put_page(page);
                goto out_unlock;
        }
-       spin_unlock(&mm->page_table_lock);
+
+got_lock:
+       target_nid = mpol_misplaced(page, vma, haddr);
+       if (target_nid == -1) {
+               unlock_page(page);
+               put_page(page);
+               goto clear_pmdnuma;
+       }
 
        /* Migrate the THP to the requested node */
+       spin_unlock(&mm->page_table_lock);
        migrated = migrate_misplaced_transhuge_page(mm, vma,
                                pmdp, pmd, addr, page, target_nid);
        if (!migrated)