On Thu, 21 Feb 2019 11:11:06 -0800 Mike Kravetz mike.kravetz@oracle.com wrote:
Sorry for the churn. As I find and fix one issue I seem to discover another. There is still at least one more issue with private pages when COW comes into play. I continue to work that. I wanted to send this patch earlier as it is pretty easy to hit the bugs if you try. If you would prefer another approach, let me know.
No probs, the bug doesn't seem to be causing a lot of bother out there and it's cc:stable; there's time to get this right ;)
Here's the delta I queued:
--- a/mm/hugetlb.c~huegtlbfs-fix-races-and-page-leaks-during-migration-update +++ a/mm/hugetlb.c @@ -3729,6 +3729,7 @@ static vm_fault_t hugetlb_no_page(struct pte_t new_pte; spinlock_t *ptl; unsigned long haddr = address & huge_page_mask(h); + bool new_page = false;
/* * Currently, we are forced to kill the process in the event the @@ -3790,6 +3791,7 @@ retry: } clear_huge_page(page, address, pages_per_huge_page(h)); __SetPageUptodate(page); + new_page = true;
if (vma->vm_flags & VM_MAYSHARE) { int err = huge_add_to_page_cache(page, mapping, idx); @@ -3861,8 +3863,9 @@ retry:
spin_unlock(ptl);
- /* May already be set if not newly allocated page */ - set_page_huge_active(page); + /* Make newly allocated pages active */ + if (new_page) + set_page_huge_active(page);
unlock_page(page); out: --- a/mm/migrate.c~huegtlbfs-fix-races-and-page-leaks-during-migration-update +++ a/mm/migrate.c @@ -1315,6 +1315,16 @@ static int unmap_and_move_huge_page(new_ lock_page(hpage); }
+ /* + * Check for pages which are in the process of being freed. Without + * page_mapping() set, hugetlbfs specific move page routine will not + * be called and we could leak usage counts for subpools. + */ + if (page_private(hpage) && !page_mapping(hpage)) { + rc = -EBUSY; + goto out_unlock; + } + if (PageAnon(hpage)) anon_vma = page_get_anon_vma(hpage);
@@ -1345,6 +1355,7 @@ put_anon: put_new_page = NULL; }
+out_unlock: unlock_page(hpage); out: if (rc != -EAGAIN) _