[PATCH v2 0/2] mm: fix PMD level mTHP accounting bugs

Nico Pache posted 2 patches 1 week ago
mm/memremap.c | 1 +
mm/migrate.c  | 3 ++-
2 files changed, 3 insertions(+), 1 deletion(-)
[PATCH v2 0/2] mm: fix PMD level mTHP accounting bugs
Posted by Nico Pache 1 week ago
While running selftests I noticed the PMD level per-mTHP stats (nr_anon)
remained elevated after each run. After further investigation I noticed
this accounting error occurs for both the migration.private_anon_htlb_test
and the HMM tests.

In the HMM case this is due to folio_add_new_anon_rmap() incrementing the
mTHP stats, but never containing a corresponding decrement in
free_zone_device_folio(). We solve this by making sure to decrement the
counter when freeing device memory.

In the migration case, we are incrementing this counter without first
checking whether this folio is a hugetlb folio, which relies on a separate
accounting system. We solve this by adding the proper hugetlb check before
incrementing this counter.

With these changes in place, the two tests no longer cause elevated PMD
level accounting issues.

Co-developed-by: David Hildenbrand <david@kernel.org>
Signed-off-by: David Hildenbrand <david@kernel.org>
Signed-off-by: Nico Pache <npache@redhat.com>

V2 Changes:
 - add RB from Zi
 - Drop unnecessary check in __folio_migrate_folio(). HugeTLB has its own
   migration system in hugetlbfs_migrate_folio().

V1: https://lore.kernel.org/all/20260702172548.37075-1-npache@redhat.com/

Nico Pache (2):
  mm: decrement MTHP_STAT_NR_ANON in free_zone_device_folio()
  mm/migrate: exclude hugetlb folios from MTHP_STAT_NR_ANON accounting

 mm/memremap.c | 1 +
 mm/migrate.c  | 3 ++-
 2 files changed, 3 insertions(+), 1 deletion(-)


base-commit: e57d6e9e20b551e4910d7a6331a81775c3ad6693
-- 
2.55.0
Re: [PATCH v2 0/2] mm: fix PMD level mTHP accounting bugs
Posted by Andrew Morton 1 week ago
On Fri, 17 Jul 2026 00:44:58 -0600 Nico Pache <npache@redhat.com> wrote:

> While running selftests I noticed the PMD level per-mTHP stats (nr_anon)
> remained elevated after each run. After further investigation I noticed
> this accounting error occurs for both the migration.private_anon_htlb_test
> and the HMM tests.
> 
> In the HMM case this is due to folio_add_new_anon_rmap() incrementing the
> mTHP stats, but never containing a corresponding decrement in
> free_zone_device_folio(). We solve this by making sure to decrement the
> counter when freeing device memory.
> 
> In the migration case, we are incrementing this counter without first
> checking whether this folio is a hugetlb folio, which relies on a separate
> accounting system. We solve this by adding the proper hugetlb check before
> incrementing this counter.
> 
> With these changes in place, the two tests no longer cause elevated PMD
> level accounting issues.

Thanks, I've updated mm.git's mm-hotfixes-unstable branch to this
version.

Sashiko is worried about the existing code ("list corruption or a
use-after-free panic"):
	https://sashiko.dev/#/patchset/20260717064502.1980173-1-npache@redhat.com

> 
> V2 Changes:
>  - add RB from Zi
>  - Drop unnecessary check in __folio_migrate_folio(). HugeTLB has its own
>    migration system in hugetlbfs_migrate_folio().

Here's how v2 altered mm.git:

 mm/migrate.c |    3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

--- a/mm/migrate.c~b
+++ a/mm/migrate.c
@@ -624,8 +624,7 @@ static int __folio_migrate_mapping(struc
 	 */
 	newfolio->index = folio->index;
 	newfolio->mapping = folio->mapping;
-	if (folio_test_anon(folio) && folio_test_large(folio) &&
-	    !folio_test_hugetlb(folio))
+	if (folio_test_anon(folio) && folio_test_large(folio))
 		mod_mthp_stat(folio_order(folio), MTHP_STAT_NR_ANON, 1);
 	folio_ref_add(newfolio, nr); /* add cache reference */
 	if (folio_test_swapbacked(folio))
_
Re: [PATCH v2 0/2] mm: fix PMD level mTHP accounting bugs
Posted by Nico Pache 3 days, 15 hours ago
On Fri, Jul 17, 2026 at 7:29 PM Andrew Morton <akpm@linux-foundation.org> wrote:
>
> On Fri, 17 Jul 2026 00:44:58 -0600 Nico Pache <npache@redhat.com> wrote:
>
> > While running selftests I noticed the PMD level per-mTHP stats (nr_anon)
> > remained elevated after each run. After further investigation I noticed
> > this accounting error occurs for both the migration.private_anon_htlb_test
> > and the HMM tests.
> >
> > In the HMM case this is due to folio_add_new_anon_rmap() incrementing the
> > mTHP stats, but never containing a corresponding decrement in
> > free_zone_device_folio(). We solve this by making sure to decrement the
> > counter when freeing device memory.
> >
> > In the migration case, we are incrementing this counter without first
> > checking whether this folio is a hugetlb folio, which relies on a separate
> > accounting system. We solve this by adding the proper hugetlb check before
> > incrementing this counter.
> >
> > With these changes in place, the two tests no longer cause elevated PMD
> > level accounting issues.
>
> Thanks, I've updated mm.git's mm-hotfixes-unstable branch to this
> version.

Thanks!

>
> Sashiko is worried about the existing code ("list corruption or a
> use-after-free panic"):
>         https://sashiko.dev/#/patchset/20260717064502.1980173-1-npache@redhat.com

https://sashiko.dev/#/patchset/20260717064502.1980173-1-npache@redhat.com

I dug into this, although I'm not very familiar with device memory.

It seems we have two options:

a) free_zone_device_folio() unqueue — unqueue zone device folios at
free time, preventing the corruptions/use-after-free.

b) deferred_split_folio() zone-device guard — block at queue time;
covers all callers; stopping the shrinker from ever touching/splitting
a live device folio; makes (a) redundant for this bug, but it could
still be kept as defense.

I added a few people who may be able to help.

Thanks,
-- Nico





>
> >
> > V2 Changes:
> >  - add RB from Zi
> >  - Drop unnecessary check in __folio_migrate_folio(). HugeTLB has its own
> >    migration system in hugetlbfs_migrate_folio().
>
> Here's how v2 altered mm.git:
>
>  mm/migrate.c |    3 +--
>  1 file changed, 1 insertion(+), 2 deletions(-)
>
> --- a/mm/migrate.c~b
> +++ a/mm/migrate.c
> @@ -624,8 +624,7 @@ static int __folio_migrate_mapping(struc
>          */
>         newfolio->index = folio->index;
>         newfolio->mapping = folio->mapping;
> -       if (folio_test_anon(folio) && folio_test_large(folio) &&
> -           !folio_test_hugetlb(folio))
> +       if (folio_test_anon(folio) && folio_test_large(folio))
>                 mod_mthp_stat(folio_order(folio), MTHP_STAT_NR_ANON, 1);
>         folio_ref_add(newfolio, nr); /* add cache reference */
>         if (folio_test_swapbacked(folio))
> _
>
Re: [PATCH v2 0/2] mm: fix PMD level mTHP accounting bugs
Posted by David Hildenbrand (Arm) 3 days, 14 hours ago
On 7/21/26 15:57, Nico Pache wrote:
> On Fri, Jul 17, 2026 at 7:29 PM Andrew Morton <akpm@linux-foundation.org> wrote:
>>
>> On Fri, 17 Jul 2026 00:44:58 -0600 Nico Pache <npache@redhat.com> wrote:
>>
>>> While running selftests I noticed the PMD level per-mTHP stats (nr_anon)
>>> remained elevated after each run. After further investigation I noticed
>>> this accounting error occurs for both the migration.private_anon_htlb_test
>>> and the HMM tests.
>>>
>>> In the HMM case this is due to folio_add_new_anon_rmap() incrementing the
>>> mTHP stats, but never containing a corresponding decrement in
>>> free_zone_device_folio(). We solve this by making sure to decrement the
>>> counter when freeing device memory.
>>>
>>> In the migration case, we are incrementing this counter without first
>>> checking whether this folio is a hugetlb folio, which relies on a separate
>>> accounting system. We solve this by adding the proper hugetlb check before
>>> incrementing this counter.
>>>
>>> With these changes in place, the two tests no longer cause elevated PMD
>>> level accounting issues.
>>
>> Thanks, I've updated mm.git's mm-hotfixes-unstable branch to this
>> version.
> 
> Thanks!
> 
>>
>> Sashiko is worried about the existing code ("list corruption or a
>> use-after-free panic"):
>>         https://sashiko.dev/#/patchset/20260717064502.1980173-1-npache@redhat.com
> 
> https://sashiko.dev/#/patchset/20260717064502.1980173-1-npache@redhat.com
> 
> I dug into this, although I'm not very familiar with device memory.

In general: Don't let a tool waste your time on unrelated things if it wasn't
you that asked the tool for it. Someone else asked the tool to find unrelated
things.

I thought we only support anonymous THP for device-private, not device-coherent.

Maybe lib/test_hmm.c could somehow trigger it by selecting
MIGRATE_VMA_SELECT_COMPOUND?

But in migrate_device_coherent_folio() we have

	WARN_ON_ONCE(folio_test_large(folio));

So this would already be pretty broken and I wouldn't spend any more time on it.

-- 
Cheers,

David
Re: [PATCH v2 0/2] mm: fix PMD level mTHP accounting bugs
Posted by Nico Pache 2 days, 10 hours ago
On Tue, Jul 21, 2026 at 8:34 AM David Hildenbrand (Arm)
<david@kernel.org> wrote:
>
> On 7/21/26 15:57, Nico Pache wrote:
> > On Fri, Jul 17, 2026 at 7:29 PM Andrew Morton <akpm@linux-foundation.org> wrote:
> >>
> >> On Fri, 17 Jul 2026 00:44:58 -0600 Nico Pache <npache@redhat.com> wrote:
> >>
> >>> While running selftests I noticed the PMD level per-mTHP stats (nr_anon)
> >>> remained elevated after each run. After further investigation I noticed
> >>> this accounting error occurs for both the migration.private_anon_htlb_test
> >>> and the HMM tests.
> >>>
> >>> In the HMM case this is due to folio_add_new_anon_rmap() incrementing the
> >>> mTHP stats, but never containing a corresponding decrement in
> >>> free_zone_device_folio(). We solve this by making sure to decrement the
> >>> counter when freeing device memory.
> >>>
> >>> In the migration case, we are incrementing this counter without first
> >>> checking whether this folio is a hugetlb folio, which relies on a separate
> >>> accounting system. We solve this by adding the proper hugetlb check before
> >>> incrementing this counter.
> >>>
> >>> With these changes in place, the two tests no longer cause elevated PMD
> >>> level accounting issues.
> >>
> >> Thanks, I've updated mm.git's mm-hotfixes-unstable branch to this
> >> version.
> >
> > Thanks!
> >
> >>
> >> Sashiko is worried about the existing code ("list corruption or a
> >> use-after-free panic"):
> >>         https://sashiko.dev/#/patchset/20260717064502.1980173-1-npache@redhat.com
> >
> > https://sashiko.dev/#/patchset/20260717064502.1980173-1-npache@redhat.com
> >
> > I dug into this, although I'm not very familiar with device memory.
>
> In general: Don't let a tool waste your time on unrelated things if it wasn't
> you that asked the tool for it. Someone else asked the tool to find unrelated
> things.

Ok sounds good. It flagged the same issue in both of my submissions so
I figured I'd investigate. It also helped me better understand the
code by forcing me to dig.

>
> I thought we only support anonymous THP for device-private, not device-coherent.

Device-coherent has PMD support; albiet I dont think there are many
users of using the MIGRATE_VMA_SELECT_COMPOUND flag.

I think Matthew is fixing this from a different perspective. Teach the
split code how to handle this.
https://lore.kernel.org/lkml/20260722044220.1110278-1-matthew.brost@intel.com/#t

Zi made some comments about it there.

-- Nico

>
> Maybe lib/test_hmm.c could somehow trigger it by selecting
> MIGRATE_VMA_SELECT_COMPOUND?
>
> But in migrate_device_coherent_folio() we have
>
>         WARN_ON_ONCE(folio_test_large(folio));
>
> So this would already be pretty broken and I wouldn't spend any more time on it.



>
> --
> Cheers,
>
> David
>