aboutsummaryrefslogtreecommitdiffstats
path: root/mm
diff options
context:
space:
mode:
Diffstat (limited to 'mm')
-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 33ee637648ba..e10d780c4781 100644
--- a/mm/huge_memory.c
+++ b/mm/huge_memory.c
@@ -1295,13 +1295,14 @@ int do_huge_pmd_numa_page(struct mm_struct *mm, struct vm_area_struct *vma,
1295 if (current_nid == numa_node_id()) 1295 if (current_nid == numa_node_id())
1296 count_vm_numa_event(NUMA_HINT_FAULTS_LOCAL); 1296 count_vm_numa_event(NUMA_HINT_FAULTS_LOCAL);
1297 1297
1298 target_nid = mpol_misplaced(page, vma, haddr); 1298 /*
1299 if (target_nid == -1) { 1299 * Acquire the page lock to serialise THP migrations but avoid dropping
1300 put_page(page); 1300 * page_table_lock if at all possible
1301 goto clear_pmdnuma; 1301 */
1302 } 1302 if (trylock_page(page))
1303 goto got_lock;
1303 1304
1304 /* Acquire the page lock to serialise THP migrations */ 1305 /* Serialise against migrationa and check placement check placement */
1305 spin_unlock(&mm->page_table_lock); 1306 spin_unlock(&mm->page_table_lock);
1306 lock_page(page); 1307 lock_page(page);
1307 1308
@@ -1312,9 +1313,17 @@ int do_huge_pmd_numa_page(struct mm_struct *mm, struct vm_area_struct *vma,
1312 put_page(page); 1313 put_page(page);
1313 goto out_unlock; 1314 goto out_unlock;
1314 } 1315 }
1315 spin_unlock(&mm->page_table_lock); 1316
1317got_lock:
1318 target_nid = mpol_misplaced(page, vma, haddr);
1319 if (target_nid == -1) {
1320 unlock_page(page);
1321 put_page(page);
1322 goto clear_pmdnuma;
1323 }
1316 1324
1317 /* Migrate the THP to the requested node */ 1325 /* Migrate the THP to the requested node */
1326 spin_unlock(&mm->page_table_lock);
1318 migrated = migrate_misplaced_transhuge_page(mm, vma, 1327 migrated = migrate_misplaced_transhuge_page(mm, vma,
1319 pmdp, pmd, addr, page, target_nid); 1328 pmdp, pmd, addr, page, target_nid);
1320 if (!migrated) 1329 if (!migrated)