aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--mm/huge_memory.c23
1 files changed, 16 insertions, 7 deletions
diff --git a/mm/huge_memory.c b/mm/huge_memory.c
index 7b09fe75799c..0ad946974df4 100644
--- a/mm/huge_memory.c
+++ b/mm/huge_memory.c
@@ -1305,13 +1305,14 @@ int do_huge_pmd_numa_page(struct mm_struct *mm, struct vm_area_struct *vma,
1305 if (current_nid == numa_node_id()) 1305 if (current_nid == numa_node_id())
1306 count_vm_numa_event(NUMA_HINT_FAULTS_LOCAL); 1306 count_vm_numa_event(NUMA_HINT_FAULTS_LOCAL);
1307 1307
1308 target_nid = mpol_misplaced(page, vma, haddr); 1308 /*
1309 if (target_nid == -1) { 1309 * Acquire the page lock to serialise THP migrations but avoid dropping
1310 put_page(page); 1310 * page_table_lock if at all possible
1311 goto clear_pmdnuma; 1311 */
1312 } 1312 if (trylock_page(page))
1313 goto got_lock;
1313 1314
1314 /* Acquire the page lock to serialise THP migrations */ 1315 /* Serialise against migrationa and check placement check placement */
1315 spin_unlock(&mm->page_table_lock); 1316 spin_unlock(&mm->page_table_lock);
1316 lock_page(page); 1317 lock_page(page);
1317 1318
@@ -1322,9 +1323,17 @@ int do_huge_pmd_numa_page(struct mm_struct *mm, struct vm_area_struct *vma,
1322 put_page(page); 1323 put_page(page);
1323 goto out_unlock; 1324 goto out_unlock;
1324 } 1325 }
1325 spin_unlock(&mm->page_table_lock); 1326
1327got_lock:
1328 target_nid = mpol_misplaced(page, vma, haddr);
1329 if (target_nid == -1) {
1330 unlock_page(page);
1331 put_page(page);
1332 goto clear_pmdnuma;
1333 }
1326 1334
1327 /* Migrate the THP to the requested node */ 1335 /* Migrate the THP to the requested node */
1336 spin_unlock(&mm->page_table_lock);
1328 migrated = migrate_misplaced_transhuge_page(mm, vma, 1337 migrated = migrate_misplaced_transhuge_page(mm, vma,
1329 pmdp, pmd, addr, page, target_nid); 1338 pmdp, pmd, addr, page, target_nid);
1330 if (!migrated) 1339 if (!migrated)