]> git.kernelconcepts.de Git - karo-tx-linux.git/blobdiff - mm/huge_memory.c
mm: Wait for THP migrations to complete during NUMA hinting faults
[karo-tx-linux.git] / mm / huge_memory.c
index dab2bab9d33e8a7716823f8a379500f5cb5c9791..f362363c0fad6720e793edfb4a5a4b71c0b8c4e1 100644 (file)
@@ -1295,13 +1295,14 @@ int do_huge_pmd_numa_page(struct mm_struct *mm, struct vm_area_struct *vma,
        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);
 
@@ -1312,9 +1313,17 @@ int do_huge_pmd_numa_page(struct mm_struct *mm, struct vm_area_struct *vma,
                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)