From: "David Hildenbrand (Arm)" <david@kernel.org>
To: Muchun Song <muchun.song@linux.dev>,
Oscar Salvador <osalvador@suse.de>,
Naoya Horiguchi <nao.horiguchi@gmail.com>,
Andrew Morton <akpm@linux-foundation.org>,
Mel Gorman <mgorman@suse.de>, Andy Whitcroft <apw@canonical.com>,
Miaohe Lin <linmiaohe@huawei.com>,
Michal Hocko <mhocko@suse.com>, Rik van Riel <riel@surriel.com>,
Hugh Dickins <hughd@google.com>,
Baolin Wang <baolin.wang@linux.alibaba.com>,
Vivek Kasireddy <vivek.kasireddy@intel.com>,
Dave Airlie <airlied@redhat.com>, Jason Gunthorpe <jgg@ziepe.ca>,
Lorenzo Stoakes <ljs@kernel.org>,
"Liam R. Howlett" <liam@infradead.org>,
Vlastimil Babka <vbabka@kernel.org>,
Mike Rapoport <rppt@kernel.org>,
Suren Baghdasaryan <surenb@google.com>,
Jonathan Corbet <corbet@lwn.net>,
Shuah Khan <skhan@linuxfoundation.org>,
Randy Dunlap <rdunlap@infradead.org>,
Peter Xu <peterx@redhat.com>, Breno Leitao <leitao@debian.org>,
Will Deacon <will@kernel.org>,
"Aneesh Kumar K.V" <aneesh.kumar@kernel.org>,
Nick Piggin <npiggin@gmail.com>,
Peter Zijlstra <peterz@infradead.org>,
Heiko Carstens <hca@linux.ibm.com>,
Vasily Gorbik <gor@linux.ibm.com>,
Alexander Gordeev <agordeev@linux.ibm.com>,
Christian Borntraeger <borntraeger@linux.ibm.com>,
Sven Schnelle <svens@linux.ibm.com>,
Arnd Bergmann <arnd@arndb.de>
Cc: linux-mm@kvack.org, linux-kernel@vger.kernel.org,
Gerd Hoffmann <kraxel@redhat.com>,
linux-doc@vger.kernel.org, linux-arch@vger.kernel.org,
linux-s390@vger.kernel.org,
"David Hildenbrand (Arm)" <david@kernel.org>,
stable@kernel.org, Chris Mason <mason@kernel.org>
Subject: [PATCH 06/15] mm/hugetlb: fix mremap() racing with page migration
Date: Wed, 28 Oct 2026 21:13:34 +0100 [thread overview]
Message-ID: <20261028-fixes_hugetlb-v1-6-a0a033db180f@kernel.org> (raw)
In-Reply-To: <20261028-fixes_hugetlb-v1-0-a0a033db180f@kernel.org>
Migration of anon hugetlb folios walks the anon_vma, so the file's
i_mmap_rwsem does not serialize it against move_hugetlb_page_tables().
There are various issues with that. Most importantly, move_huge_pte()
releases both page table locks before the TLB is flushed. Migration can
then find the destination entry and finish migration, reusing the old
folio while the TLB still has entries cached.
Hold the anon_vma write lock across the move and the final TLB flush.
This also prevents concurrent rmap walks from missing entries moved
during rollback.
When we must allocate a destination page table, flush the TLB before
dropping the anon_vma lock, then reacquire it after allocation.
Dropping the lock only works around lockdep: hugetlb folios are not
reclaimed or migrated by allocation compaction, but their anon_vmas
share the lock class used by ordinary anonymous memory. Having a
separate lock class for hugetlb's anon_vma (like already done for
i_mmap_rwsem via hugetlbfs_i_mmap_rwsem_key) requires more thought.
There is a concern that this can block page migration of anonymous
folios quite a while ... which is not really different to what happens
to page-cache folios today. If ever a problem, we can temporarily
release the lock.
So let's keep it simple for now.
It is a shame that hugetlb has to implement everything core-mm implements
in a different way that just screams for problems.
Fixes: 550a7d60bd5e ("mm, hugepages: add mremap() support for hugepage backed vma")
Cc: stable@kernel.org
Reported-by: Chris Mason <mason@kernel.org>
Signed-off-by: David Hildenbrand (Arm) <david@kernel.org>
---
mm/hugetlb.c | 21 ++++++++++++++++++++-
1 file changed, 20 insertions(+), 1 deletion(-)
diff --git a/mm/hugetlb.c b/mm/hugetlb.c
index 55f7d692ed0d..2fdd72897db8 100644
--- a/mm/hugetlb.c
+++ b/mm/hugetlb.c
@@ -5219,6 +5219,7 @@ int move_hugetlb_page_tables(struct vm_area_struct *vma,
{
struct hstate *h = hstate_vma(vma);
struct address_space *mapping = vma->vm_file->f_mapping;
+ struct anon_vma *anon_vma = vma->anon_vma;
unsigned long sz = huge_page_size(h);
struct mm_struct *mm = vma->vm_mm;
unsigned long old_end = old_addr + len;
@@ -5242,6 +5243,8 @@ int move_hugetlb_page_tables(struct vm_area_struct *vma,
/* Prevent race with file truncation */
hugetlb_vma_lock_write(vma);
i_mmap_lock_write(mapping);
+ if (anon_vma)
+ anon_vma_lock_write(anon_vma);
for (; old_addr < old_end; old_addr += sz, new_addr += sz) {
const unsigned long offset_to_last_entry =
(old_addr | last_addr_mask) - old_addr;
@@ -5261,7 +5264,20 @@ int move_hugetlb_page_tables(struct vm_area_struct *vma,
continue;
}
- dst_pte = huge_pte_alloc(mm, new_vma, new_addr, sz);
+ dst_pte = hugetlb_walk(new_vma, new_addr, sz);
+ if (!dst_pte) {
+ /*
+ * We can allocate memory under anon_vma lock with hugetlb,
+ * but lockdep does not know about that. So for now we simply
+ * flush the TLB and temporarily drop the lock.
+ */
+ tlb_flush_mmu_tlbonly(&tlb);
+ if (anon_vma)
+ anon_vma_unlock_write(anon_vma);
+ dst_pte = huge_pte_alloc(mm, new_vma, new_addr, sz);
+ if (anon_vma)
+ anon_vma_lock_write(anon_vma);
+ }
if (!dst_pte)
break;
@@ -5269,7 +5285,10 @@ int move_hugetlb_page_tables(struct vm_area_struct *vma,
tlb_remove_huge_tlb_entry(h, &tlb, src_pte, old_addr);
}
+ /* Flush pending moves before allowing migration to walk the entries. */
tlb_flush_mmu_tlbonly(&tlb);
+ if (anon_vma)
+ anon_vma_unlock_write(anon_vma);
huge_pmd_unshare_flush(&tlb, vma);
mmu_notifier_invalidate_range_end(&range);
--
2.43.0
next prev parent reply other threads:[~2026-10-28 20:14 UTC|newest]
Thread overview: 21+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-28 20:13 [PATCH 00/15] mm/hugetlb: various fixes David Hildenbrand (Arm)
2026-10-28 20:13 ` [PATCH 01/15] hugetlbfs: fix integer overflow in fallocate() David Hildenbrand (Arm)
2026-10-29 3:37 ` Muchun Song
2026-10-29 9:05 ` Oscar Salvador (SUSE)
2026-10-28 20:13 ` [PATCH 02/15] mm/hugetlb: compare against persistent count when freeing lowmem folios David Hildenbrand (Arm)
2026-10-29 3:39 ` Muchun Song
2026-10-28 20:13 ` [PATCH 03/15] mm/hugetlb: preserve reservations when shrinking on HIGHMEM David Hildenbrand (Arm)
2026-10-29 3:41 ` Muchun Song
2026-10-28 20:13 ` [PATCH 04/15] mm/hugetlb: account temporary folios separately David Hildenbrand (Arm)
2026-10-28 20:13 ` [PATCH 05/15] mm/hugetlb: keep surplus folios when the pool shrinks David Hildenbrand (Arm)
2026-10-29 3:51 ` Muchun Song
2026-10-28 20:13 ` David Hildenbrand (Arm) [this message]
2026-10-28 20:13 ` [PATCH 07/15] hugetlbfs: fix unmapping folios from private VMAs David Hildenbrand (Arm)
2026-10-28 20:13 ` [PATCH 08/15] mm/hugetlb: serialize page-cache allocations with truncation David Hildenbrand (Arm)
2026-10-28 20:13 ` [PATCH 09/15] mm/memfd: recheck the page cache before allocating a hugetlb folio David Hildenbrand (Arm)
2026-10-28 20:13 ` [PATCH 10/15] mm/hugetlb: count again if the reserve map shrank David Hildenbrand (Arm)
2026-10-28 20:13 ` [PATCH 11/15] hugetlbfs: do not grow a sealed file in mmap() David Hildenbrand (Arm)
2026-10-28 20:13 ` [PATCH 12/15] mm/hugetlb: keep surplus folios that are reserved David Hildenbrand (Arm)
2026-10-28 20:13 ` [PATCH 13/15] mm/hugetlb: fix reservation leak on min_size= mounts David Hildenbrand (Arm)
2026-10-28 20:13 ` [PATCH 14/15] RFC: mm/hugetlb: account restored reservations before freeing folios David Hildenbrand (Arm)
2026-10-28 20:13 ` [PATCH 15/15] RFC: mm/hugetlb: delay anon folio rmap removal until after the TLB flush David Hildenbrand (Arm)
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20261028-fixes_hugetlb-v1-6-a0a033db180f@kernel.org \
--to=david@kernel.org \
--cc=agordeev@linux.ibm.com \
--cc=airlied@redhat.com \
--cc=akpm@linux-foundation.org \
--cc=aneesh.kumar@kernel.org \
--cc=apw@canonical.com \
--cc=arnd@arndb.de \
--cc=baolin.wang@linux.alibaba.com \
--cc=borntraeger@linux.ibm.com \
--cc=corbet@lwn.net \
--cc=gor@linux.ibm.com \
--cc=hca@linux.ibm.com \
--cc=hughd@google.com \
--cc=jgg@ziepe.ca \
--cc=kraxel@redhat.com \
--cc=leitao@debian.org \
--cc=liam@infradead.org \
--cc=linmiaohe@huawei.com \
--cc=linux-arch@vger.kernel.org \
--cc=linux-doc@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=linux-s390@vger.kernel.org \
--cc=ljs@kernel.org \
--cc=mason@kernel.org \
--cc=mgorman@suse.de \
--cc=mhocko@suse.com \
--cc=muchun.song@linux.dev \
--cc=nao.horiguchi@gmail.com \
--cc=npiggin@gmail.com \
--cc=osalvador@suse.de \
--cc=peterx@redhat.com \
--cc=peterz@infradead.org \
--cc=rdunlap@infradead.org \
--cc=riel@surriel.com \
--cc=rppt@kernel.org \
--cc=skhan@linuxfoundation.org \
--cc=stable@kernel.org \
--cc=surenb@google.com \
--cc=svens@linux.ibm.com \
--cc=vbabka@kernel.org \
--cc=vivek.kasireddy@intel.com \
--cc=will@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox