diff options
Diffstat (limited to 'mm/huge_memory.c')
-rw-r--r-- | mm/huge_memory.c | 23 |
1 files changed, 16 insertions, 7 deletions
diff --git a/mm/huge_memory.c b/mm/huge_memory.c index dab2bab9d33e..f362363c0fad 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 | |
1317 | got_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) |