Patch "mm: numa: avoid waiting on freed migrated pages" has been added to the 4.11-stable tree
Subsystems (3)
This is a note to let you know that I've just added the patch titled
mm: numa: avoid waiting on freed migrated pages
to the 4.11-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary
The filename of the patch is:
mm-numa-avoid-waiting-on-freed-migrated-pages.patch
and it can be found in the queue-4.11 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.
Quoted 1 line
From
3c226c637b69104f6b9f1c6ec5b08d7b741b3229Mon Sep 17 00:00:00 2001
From: Mark Rutland <[email protected]>
Date: Fri, 16 Jun 2017 14:02:34 -0700
Subject: mm: numa: avoid waiting on freed migrated pages
From: Mark Rutland <[email protected]>
commit 3c226c637b69104f6b9f1c6ec5b08d7b741b3229 upstream.
In do_huge_pmd_numa_page(), we attempt to handle a migrating thp pmd by waiting until the pmd is unlocked before we return and retry. However, we can race with migrate_misplaced_transhuge_page():
// do_huge_pmd_numa_page // migrate_misplaced_transhuge_page()
// Holds 0 refs on page // Holds 2 refs on page
vmf->ptl = pmd_lock(vma->vm_mm, vmf->pmd);
/* ... */
if (pmd_trans_migrating(*vmf->pmd)) {
page = pmd_page(*vmf->pmd);
spin_unlock(vmf->ptl);
ptl = pmd_lock(mm, pmd);
if (page_count(page) != 2)) {
/* roll back */
}
/* ... */
mlock_migrate_page(new_page, page);
/* ... */
spin_unlock(ptl);
put_page(page);
put_page(page); // page freed here
wait_on_page_locked(page);
goto out;
}This can result in the freed page having its waiters flag set unexpectedly, which trips the PAGE_FLAGS_CHECK_AT_PREP checks in the page alloc/free functions. This has been observed on arm64 KVM guests.
We can avoid this by having do_huge_pmd_numa_page() take a reference on the page before dropping the pmd lock, mirroring what we do in __migration_entry_wait().
When we hit the race, migrate_misplaced_transhuge_page() will see the reference and abort the migration, as it may do today in other cases.
--- mm/huge_memory.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)
mm/huge_memory.c +7 -1
@@ -1412,8 +1412,11 @@ int do_huge_pmd_numa_page(struct vm_faul*/ if (unlikely (pmd_trans_migrating (*vmf->pmd))) { page =pmd_page (*vmf->pmd); +if (!get_page_unless_zero (page)) + goto out_unlock;spin_unlock (vmf->ptl);wait_on_page_locked (page); +put_page (page); goto out; }
@@ -1445,9 +1448,12 @@ int do_huge_pmd_numa_page(struct vm_faul/* Migration could have started since the pmd_trans_migrating check */ if (!page_locked) { + page_nid =-1 ; +if (!get_page_unless_zero (page)) + goto out_unlock;spin_unlock (vmf->ptl);wait_on_page_locked (page); - page_nid =-1 ; +put_page (page); goto out; }
Patches currently in stable-queue which might be from [email protected] are
queue-4.11/mm-numa-avoid-waiting-on-freed-migrated-pages.patch