mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH] mm/huge_memory: bypass THP tuneables for huge pfnmap mappings
@ 2026-08-27 19:55 Lorenzo Stoakes (ARM)
  2026-08-28  2:52 ` Zi Yan
                   ` (2 more replies)
  0 siblings, 3 replies; 6+ messages in thread
From: Lorenzo Stoakes (ARM) @ 2026-08-27 19:55 UTC (permalink / raw)
  To: Andrew Morton, David Hildenbrand, Zi Yan, Baolin Wang,
	Liam R. Howlett, Nico Pache, Ryan Roberts, Dev Jain, Barry Song,
	Lance Yang, Usama Arif, Peter Xu, Jason Gunthorpe
  Cc: linux-mm, linux-kernel, Cedric Le Goater, Saravanan D, stable,
	Lorenzo Stoakes (ARM)

The sysfs THP tuneables at /sys/kernel/mm/transparent_huge_pages/ rather
confusingly only control the behaviour of THP in some instances.

They are not applicable to MADV_COLLAPSE operations, nor to DAX mappings.

Long-term, THP is predicated upon compaction being able to obtain large
folios to populate THP ranges.

However, vm_normal_folio() returns NULL for PFN map mappings, thus their
reference count is maintained by the driver, not core mm.

As a consequence, the folios are not subject to reclaim nor compaction, so
are not truly part of the THP mechanism at all.

However, since commit 5dd40721f147 ("mm: allow THP orders for PFNMAPs")
introduced the ability to establish huge PFN maps, they have been subject
to THP tuneables.

This is incorrect - if a huge PFN map is available (defined by
vma->vm_ops->huge_fault being non-NULL for a VMA_PFNMAP_BIT VMA), then it
should be mapped huge upon fault-in.

Correct this by explicitly checking for this while ensuring that smaps
continues to accurately report THPeligible statistics.

While here, abstract the entire file-backed THP check in
vma_can_map_huge_file(), with sensible separation of logic into helper
functions.

Note that drm_gem_shmem_mmap() and panthor_gem_mmap() establish huge PFN
maps of shmem folios, however they are marked unevictable in
drm_gem_get_pages(), and in any case would fail the reference check in
__remove_mapping() even if they weren't.

Failing to map huge PFN maps has resulted in significant real-world
performance degradation, see links for details.

Reported-by: Cedric Le Goater <clg@redhat.com>
Closes: https://lore.kernel.org/linux-mm/20260805055544.1568534-1-clg@redhat.com/
Reported-by: Saravanan D <saravanand@crusoe.ai>
Closes: https://lore.kernel.org/linux-mm/20260821070520.25759-1-saravanand@crusoe.ai/
Fixes: 5dd40721f147 ("mm: allow THP orders for PFNMAPs")
Cc: stable@vger.kernel.org
Signed-off-by: Lorenzo Stoakes (ARM) <ljs@kernel.org>
---
 mm/huge_memory.c | 86 +++++++++++++++++++++++++++++++++++++++++---------------
 1 file changed, 64 insertions(+), 22 deletions(-)

diff --git a/mm/huge_memory.c b/mm/huge_memory.c
index afbb5974bd22..4bf7b670586d 100644
--- a/mm/huge_memory.c
+++ b/mm/huge_memory.c
@@ -92,7 +92,7 @@ unsigned long huge_anon_orders_madvise __read_mostly;
 unsigned long huge_anon_orders_inherit __read_mostly;
 static bool anon_orders_configured __initdata;
 
-static inline bool file_thp_enabled(struct vm_area_struct *vma)
+static inline bool file_thp_enabled(const struct vm_area_struct *vma)
 {
 	struct inode *inode;
 
@@ -118,6 +118,67 @@ static bool vma_is_special_huge(const struct vm_area_struct *vma)
 	return vma_test_any(vma, VMA_PFNMAP_BIT, VMA_MIXEDMAP_BIT);
 }
 
+static bool vma_bypass_thp_tuneables_file(const struct vm_area_struct *vma,
+		enum tva_type type)
+{
+	const bool has_huge_fault = vma->vm_ops->huge_fault;
+
+	/* MADV_COLLAPSE ignores tuneables. */
+	if (type == TVA_FORCED_COLLAPSE)
+		return true;
+	/* Huge PFN mappings are uncompactable so the policy doesn't apply. */
+	if (vma_test(vma, VMA_PFNMAP_BIT) && has_huge_fault)
+		return true;
+	return false;
+}
+
+static bool vma_thp_tuneables_allow_file(vm_flags_t vm_flags)
+{
+	/* THP=always? */
+	if (hugepage_global_always())
+		return true;
+	/* THP=madvise and marked MADV_HUGEPAGE? */
+	if (hugepage_global_enabled() && (vm_flags & VM_HUGEPAGE))
+		return true;
+	return false;
+}
+
+static bool vma_check_thp_tuneables_file(const struct vm_area_struct *vma,
+		vm_flags_t vm_flags, enum tva_type type)
+{
+	return vma_bypass_thp_tuneables_file(vma, type) ||
+		vma_thp_tuneables_allow_file(vm_flags);
+}
+
+static bool vma_can_map_huge_file(const struct vm_area_struct *vma,
+		vm_flags_t vm_flags, enum tva_type type)
+{
+	const bool has_huge_fault = vma->vm_ops->huge_fault;
+
+	/*
+	 * Enforce THP collapse requirements as necessary. Anonymous vmas
+	 * were already handled in thp_vma_allowable_orders().
+	 */
+	if (!vma_check_thp_tuneables_file(vma, vm_flags, type))
+		return false;
+
+	switch (type) {
+	case TVA_PAGEFAULT:
+		/*
+		 * Trust that ->huge_fault() handlers know what they are doing
+		 * in fault path.
+		 */
+		return has_huge_fault;
+	case TVA_SMAPS:
+		if (has_huge_fault)
+			return true;
+		fallthrough;
+	default:
+		/* Only regular file is valid in collapse path. */
+		return file_thp_enabled(vma);
+	}
+}
+
 unsigned long __thp_vma_allowable_orders(struct vm_area_struct *vma,
 					 vm_flags_t vm_flags,
 					 enum tva_type type,
@@ -190,27 +251,8 @@ unsigned long __thp_vma_allowable_orders(struct vm_area_struct *vma,
 						   vma, vma_start_pgoff(vma), 0,
 						   forced_collapse);
 
-	if (!vma_is_anonymous(vma)) {
-		/*
-		 * Enforce THP collapse requirements as necessary. Anonymous vmas
-		 * were already handled in thp_vma_allowable_orders().
-		 */
-		if (!forced_collapse &&
-		    (!hugepage_global_enabled() || (!(vm_flags & VM_HUGEPAGE) &&
-						    !hugepage_global_always())))
-			return 0;
-
-		/*
-		 * Trust that ->huge_fault() handlers know what they are doing
-		 * in fault path.
-		 */
-		if (((in_pf || smaps)) && vma->vm_ops->huge_fault)
-			return orders;
-		/* Only regular file is valid in collapse path */
-		if (((!in_pf || smaps)) && file_thp_enabled(vma))
-			return orders;
-		return 0;
-	}
+	if (!vma_is_anonymous(vma))
+		return vma_can_map_huge_file(vma, vm_flags, type) ? orders : 0;
 
 	if (vma_is_temporary_stack(vma))
 		return 0;

---
base-commit: 234e77148199ae43b83a0a03a3f481e03460a286
change-id: 20260827-hugepfn-allowable-orders-ff323f85fc57

Best regards,
-- 
Lorenzo Stoakes (ARM) <ljs@kernel.org>


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH] mm/huge_memory: bypass THP tuneables for huge pfnmap mappings
  2026-08-27 19:55 [PATCH] mm/huge_memory: bypass THP tuneables for huge pfnmap mappings Lorenzo Stoakes (ARM)
@ 2026-08-28  2:52 ` Zi Yan
  2026-08-28  7:11   ` Lorenzo Stoakes (ARM)
  2026-08-28  4:47 ` Lance Yang
  2026-08-28 16:46 ` Saravanan D
  2 siblings, 1 reply; 6+ messages in thread
From: Zi Yan @ 2026-08-28  2:52 UTC (permalink / raw)
  To: Lorenzo Stoakes (ARM),
	Andrew Morton, David Hildenbrand, Baolin Wang, Liam R. Howlett,
	Nico Pache, Ryan Roberts, Dev Jain, Barry Song, Lance Yang,
	Usama Arif, Peter Xu, Jason Gunthorpe
  Cc: linux-mm, linux-kernel, Cedric Le Goater, Saravanan D, stable

On Thu Aug 27, 2026 at 3:55 PM EDT, Lorenzo Stoakes (ARM) wrote:
> The sysfs THP tuneables at /sys/kernel/mm/transparent_huge_pages/ rather
> confusingly only control the behaviour of THP in some instances.
>
> They are not applicable to MADV_COLLAPSE operations, nor to DAX mappings.
>
> Long-term, THP is predicated upon compaction being able to obtain large
> folios to populate THP ranges.
>
> However, vm_normal_folio() returns NULL for PFN map mappings, thus their
> reference count is maintained by the driver, not core mm.
>
> As a consequence, the folios are not subject to reclaim nor compaction, so
> are not truly part of the THP mechanism at all.
>
> However, since commit 5dd40721f147 ("mm: allow THP orders for PFNMAPs")
> introduced the ability to establish huge PFN maps, they have been subject
> to THP tuneables.
>
> This is incorrect - if a huge PFN map is available (defined by
> vma->vm_ops->huge_fault being non-NULL for a VMA_PFNMAP_BIT VMA), then it
> should be mapped huge upon fault-in.
>
> Correct this by explicitly checking for this while ensuring that smaps
> continues to accurately report THPeligible statistics.
>
> While here, abstract the entire file-backed THP check in
> vma_can_map_huge_file(), with sensible separation of logic into helper
> functions.
>
> Note that drm_gem_shmem_mmap() and panthor_gem_mmap() establish huge PFN
> maps of shmem folios, however they are marked unevictable in
> drm_gem_get_pages(), and in any case would fail the reference check in
> __remove_mapping() even if they weren't.
>
> Failing to map huge PFN maps has resulted in significant real-world
> performance degradation, see links for details.
>
> Reported-by: Cedric Le Goater <clg@redhat.com>
> Closes: https://lore.kernel.org/linux-mm/20260805055544.1568534-1-clg@redhat.com/
> Reported-by: Saravanan D <saravanand@crusoe.ai>
> Closes: https://lore.kernel.org/linux-mm/20260821070520.25759-1-saravanand@crusoe.ai/
> Fixes: 5dd40721f147 ("mm: allow THP orders for PFNMAPs")
> Cc: stable@vger.kernel.org
> Signed-off-by: Lorenzo Stoakes (ARM) <ljs@kernel.org>
> ---
>  mm/huge_memory.c | 86 +++++++++++++++++++++++++++++++++++++++++---------------
>  1 file changed, 64 insertions(+), 22 deletions(-)

I checked the code logic and find everything matches except the intended
pfnmap check for the fix.

Reviewed-by: Zi Yan <ziy@nvidia.com>

Some nits on the function names below, but feel free to ignore.

>
> diff --git a/mm/huge_memory.c b/mm/huge_memory.c
> index afbb5974bd22..4bf7b670586d 100644
> --- a/mm/huge_memory.c
> +++ b/mm/huge_memory.c
> @@ -92,7 +92,7 @@ unsigned long huge_anon_orders_madvise __read_mostly;
>  unsigned long huge_anon_orders_inherit __read_mostly;
>  static bool anon_orders_configured __initdata;
>  
> -static inline bool file_thp_enabled(struct vm_area_struct *vma)
> +static inline bool file_thp_enabled(const struct vm_area_struct *vma)
>  {
>  	struct inode *inode;
>  
> @@ -118,6 +118,67 @@ static bool vma_is_special_huge(const struct vm_area_struct *vma)
>  	return vma_test_any(vma, VMA_PFNMAP_BIT, VMA_MIXEDMAP_BIT);
>  }
>  
> +static bool vma_bypass_thp_tuneables_file(const struct vm_area_struct *vma,
> +		enum tva_type type)
> +{
> +	const bool has_huge_fault = vma->vm_ops->huge_fault;
> +
> +	/* MADV_COLLAPSE ignores tuneables. */
> +	if (type == TVA_FORCED_COLLAPSE)
> +		return true;
> +	/* Huge PFN mappings are uncompactable so the policy doesn't apply. */
> +	if (vma_test(vma, VMA_PFNMAP_BIT) && has_huge_fault)
> +		return true;
> +	return false;
> +}
> +
> +static bool vma_thp_tuneables_allow_file(vm_flags_t vm_flags)
> +{
> +	/* THP=always? */
> +	if (hugepage_global_always())
> +		return true;
> +	/* THP=madvise and marked MADV_HUGEPAGE? */
> +	if (hugepage_global_enabled() && (vm_flags & VM_HUGEPAGE))
> +		return true;
> +	return false;
> +}
> +
> +static bool vma_check_thp_tuneables_file(const struct vm_area_struct *vma,
> +		vm_flags_t vm_flags, enum tva_type type)
> +{
> +	return vma_bypass_thp_tuneables_file(vma, type) ||
> +		vma_thp_tuneables_allow_file(vm_flags);

Naming is hard, but
1. is vma_allow_thp_tuneables_file() better? Then all three helpers are
vma + a verb + thp_tuneables_file().

2. is vma_file_ a better prefix than putting file at the end?


Another idea is to put all checks in one function and just add some comments
on bypassing ones and allowed ones.

> +}
> +
> +static bool vma_can_map_huge_file(const struct vm_area_struct *vma,
> +		vm_flags_t vm_flags, enum tva_type type)
> +{
> +	const bool has_huge_fault = vma->vm_ops->huge_fault;
> +
> +	/*
> +	 * Enforce THP collapse requirements as necessary. Anonymous vmas
> +	 * were already handled in thp_vma_allowable_orders().
> +	 */
> +	if (!vma_check_thp_tuneables_file(vma, vm_flags, type))
> +		return false;
> +
> +	switch (type) {
> +	case TVA_PAGEFAULT:
> +		/*
> +		 * Trust that ->huge_fault() handlers know what they are doing
> +		 * in fault path.
> +		 */
> +		return has_huge_fault;
> +	case TVA_SMAPS:
> +		if (has_huge_fault)
> +			return true;
> +		fallthrough;
> +	default:
> +		/* Only regular file is valid in collapse path. */
> +		return file_thp_enabled(vma);
> +	}
> +}
> +
>  unsigned long __thp_vma_allowable_orders(struct vm_area_struct *vma,
>  					 vm_flags_t vm_flags,
>  					 enum tva_type type,
> @@ -190,27 +251,8 @@ unsigned long __thp_vma_allowable_orders(struct vm_area_struct *vma,
>  						   vma, vma_start_pgoff(vma), 0,
>  						   forced_collapse);
>  
> -	if (!vma_is_anonymous(vma)) {
> -		/*
> -		 * Enforce THP collapse requirements as necessary. Anonymous vmas
> -		 * were already handled in thp_vma_allowable_orders().
> -		 */
> -		if (!forced_collapse &&
> -		    (!hugepage_global_enabled() || (!(vm_flags & VM_HUGEPAGE) &&
> -						    !hugepage_global_always())))
> -			return 0;
> -
> -		/*
> -		 * Trust that ->huge_fault() handlers know what they are doing
> -		 * in fault path.
> -		 */
> -		if (((in_pf || smaps)) && vma->vm_ops->huge_fault)
> -			return orders;
> -		/* Only regular file is valid in collapse path */
> -		if (((!in_pf || smaps)) && file_thp_enabled(vma))
> -			return orders;
> -		return 0;
> -	}
> +	if (!vma_is_anonymous(vma))
> +		return vma_can_map_huge_file(vma, vm_flags, type) ? orders : 0;
>  
>  	if (vma_is_temporary_stack(vma))
>  		return 0;
>

The rest looks great to me. Thanks.


-- 
Best Regards,
Yan, Zi


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH] mm/huge_memory: bypass THP tuneables for huge pfnmap mappings
  2026-08-27 19:55 [PATCH] mm/huge_memory: bypass THP tuneables for huge pfnmap mappings Lorenzo Stoakes (ARM)
  2026-08-28  2:52 ` Zi Yan
@ 2026-08-28  4:47 ` Lance Yang
  2026-08-28 16:46 ` Saravanan D
  2 siblings, 0 replies; 6+ messages in thread
From: Lance Yang @ 2026-08-28  4:47 UTC (permalink / raw)
  To: Lorenzo Stoakes (ARM)
  Cc: linux-mm, Nico Pache, David Hildenbrand, Barry Song, Baolin Wang,
	linux-kernel, Jason Gunthorpe, Peter Xu, Usama Arif, Dev Jain,
	Ryan Roberts, Liam R. Howlett, Cedric Le Goater, Saravanan D,
	stable, Andrew Morton, Zi Yan



On 2026/8/28 03:55, Lorenzo Stoakes (ARM) wrote:
> The sysfs THP tuneables at /sys/kernel/mm/transparent_huge_pages/ rather
> confusingly only control the behaviour of THP in some instances.
> 
> They are not applicable to MADV_COLLAPSE operations, nor to DAX mappings.
> 
> Long-term, THP is predicated upon compaction being able to obtain large
> folios to populate THP ranges.
> 
> However, vm_normal_folio() returns NULL for PFN map mappings, thus their
> reference count is maintained by the driver, not core mm.
> 
> As a consequence, the folios are not subject to reclaim nor compaction, so
> are not truly part of the THP mechanism at all.
> 
> However, since commit 5dd40721f147 ("mm: allow THP orders for PFNMAPs")
> introduced the ability to establish huge PFN maps, they have been subject
> to THP tuneables.
> 
> This is incorrect - if a huge PFN map is available (defined by
> vma->vm_ops->huge_fault being non-NULL for a VMA_PFNMAP_BIT VMA), then it
> should be mapped huge upon fault-in.
> 
> Correct this by explicitly checking for this while ensuring that smaps
> continues to accurately report THPeligible statistics.
> 
> While here, abstract the entire file-backed THP check in
> vma_can_map_huge_file(), with sensible separation of logic into helper
> functions.
> 
> Note that drm_gem_shmem_mmap() and panthor_gem_mmap() establish huge PFN
> maps of shmem folios, however they are marked unevictable in
> drm_gem_get_pages(), and in any case would fail the reference check in
> __remove_mapping() even if they weren't.
> 
> Failing to map huge PFN maps has resulted in significant real-world
> performance degradation, see links for details.
> 
> Reported-by: Cedric Le Goater <clg@redhat.com>
> Closes: https://lore.kernel.org/linux-mm/20260805055544.1568534-1-clg@redhat.com/
> Reported-by: Saravanan D <saravanand@crusoe.ai>
> Closes: https://lore.kernel.org/linux-mm/20260821070520.25759-1-saravanand@crusoe.ai/
> Fixes: 5dd40721f147 ("mm: allow THP orders for PFNMAPs")
> Cc: stable@vger.kernel.org
> Signed-off-by: Lorenzo Stoakes (ARM) <ljs@kernel.org>
> ---

Cool!

Tested-by: Lance Yang <lance.yang@linux.dev>

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH] mm/huge_memory: bypass THP tuneables for huge pfnmap mappings
  2026-08-28  2:52 ` Zi Yan
@ 2026-08-28  7:11   ` Lorenzo Stoakes (ARM)
  0 siblings, 0 replies; 6+ messages in thread
From: Lorenzo Stoakes (ARM) @ 2026-08-28  7:11 UTC (permalink / raw)
  To: Zi Yan
  Cc: Andrew Morton, David Hildenbrand, Baolin Wang, Liam R. Howlett,
	Nico Pache, Ryan Roberts, Dev Jain, Barry Song, Lance Yang,
	Usama Arif, Peter Xu, Jason Gunthorpe, linux-mm, linux-kernel,
	Cedric Le Goater, Saravanan D, stable

On Thu, Aug 27, 2026 at 10:52:24PM -0400, Zi Yan wrote:
> On Thu Aug 27, 2026 at 3:55 PM EDT, Lorenzo Stoakes (ARM) wrote:
> > The sysfs THP tuneables at /sys/kernel/mm/transparent_huge_pages/ rather
> > confusingly only control the behaviour of THP in some instances.
> >
> > They are not applicable to MADV_COLLAPSE operations, nor to DAX mappings.
> >
> > Long-term, THP is predicated upon compaction being able to obtain large
> > folios to populate THP ranges.
> >
> > However, vm_normal_folio() returns NULL for PFN map mappings, thus their
> > reference count is maintained by the driver, not core mm.
> >
> > As a consequence, the folios are not subject to reclaim nor compaction, so
> > are not truly part of the THP mechanism at all.
> >
> > However, since commit 5dd40721f147 ("mm: allow THP orders for PFNMAPs")
> > introduced the ability to establish huge PFN maps, they have been subject
> > to THP tuneables.
> >
> > This is incorrect - if a huge PFN map is available (defined by
> > vma->vm_ops->huge_fault being non-NULL for a VMA_PFNMAP_BIT VMA), then it
> > should be mapped huge upon fault-in.
> >
> > Correct this by explicitly checking for this while ensuring that smaps
> > continues to accurately report THPeligible statistics.
> >
> > While here, abstract the entire file-backed THP check in
> > vma_can_map_huge_file(), with sensible separation of logic into helper
> > functions.
> >
> > Note that drm_gem_shmem_mmap() and panthor_gem_mmap() establish huge PFN
> > maps of shmem folios, however they are marked unevictable in
> > drm_gem_get_pages(), and in any case would fail the reference check in
> > __remove_mapping() even if they weren't.
> >
> > Failing to map huge PFN maps has resulted in significant real-world
> > performance degradation, see links for details.
> >
> > Reported-by: Cedric Le Goater <clg@redhat.com>
> > Closes: https://lore.kernel.org/linux-mm/20260805055544.1568534-1-clg@redhat.com/
> > Reported-by: Saravanan D <saravanand@crusoe.ai>
> > Closes: https://lore.kernel.org/linux-mm/20260821070520.25759-1-saravanand@crusoe.ai/
> > Fixes: 5dd40721f147 ("mm: allow THP orders for PFNMAPs")
> > Cc: stable@vger.kernel.org
> > Signed-off-by: Lorenzo Stoakes (ARM) <ljs@kernel.org>
> > ---
> >  mm/huge_memory.c | 86 +++++++++++++++++++++++++++++++++++++++++---------------
> >  1 file changed, 64 insertions(+), 22 deletions(-)
>
> I checked the code logic and find everything matches except the intended
> pfnmap check for the fix.
>
> Reviewed-by: Zi Yan <ziy@nvidia.com>

Thanks! :)

>
> Some nits on the function names below, but feel free to ignore.
>
> >
> > diff --git a/mm/huge_memory.c b/mm/huge_memory.c
> > index afbb5974bd22..4bf7b670586d 100644
> > --- a/mm/huge_memory.c
> > +++ b/mm/huge_memory.c
> > @@ -92,7 +92,7 @@ unsigned long huge_anon_orders_madvise __read_mostly;
> >  unsigned long huge_anon_orders_inherit __read_mostly;
> >  static bool anon_orders_configured __initdata;
> >
> > -static inline bool file_thp_enabled(struct vm_area_struct *vma)
> > +static inline bool file_thp_enabled(const struct vm_area_struct *vma)
> >  {
> >  	struct inode *inode;
> >
> > @@ -118,6 +118,67 @@ static bool vma_is_special_huge(const struct vm_area_struct *vma)
> >  	return vma_test_any(vma, VMA_PFNMAP_BIT, VMA_MIXEDMAP_BIT);
> >  }
> >
> > +static bool vma_bypass_thp_tuneables_file(const struct vm_area_struct *vma,
> > +		enum tva_type type)
> > +{
> > +	const bool has_huge_fault = vma->vm_ops->huge_fault;
> > +
> > +	/* MADV_COLLAPSE ignores tuneables. */
> > +	if (type == TVA_FORCED_COLLAPSE)
> > +		return true;
> > +	/* Huge PFN mappings are uncompactable so the policy doesn't apply. */
> > +	if (vma_test(vma, VMA_PFNMAP_BIT) && has_huge_fault)
> > +		return true;
> > +	return false;
> > +}
> > +
> > +static bool vma_thp_tuneables_allow_file(vm_flags_t vm_flags)
> > +{
> > +	/* THP=always? */
> > +	if (hugepage_global_always())
> > +		return true;
> > +	/* THP=madvise and marked MADV_HUGEPAGE? */
> > +	if (hugepage_global_enabled() && (vm_flags & VM_HUGEPAGE))
> > +		return true;
> > +	return false;
> > +}
> > +
> > +static bool vma_check_thp_tuneables_file(const struct vm_area_struct *vma,
> > +		vm_flags_t vm_flags, enum tva_type type)
> > +{
> > +	return vma_bypass_thp_tuneables_file(vma, type) ||
> > +		vma_thp_tuneables_allow_file(vm_flags);
>
> Naming is hard, but

Yes :)

> 1. is vma_allow_thp_tuneables_file() better? Then all three helpers are
> vma + a verb + thp_tuneables_file().

That's a good idea! Much better thanks.

>
> 2. is vma_file_ a better prefix than putting file at the end?

Yeah, it's an annoying one as kinda want to say 'file-backed VMA' but I think
you're right vma_xxx_file() -> vma_file_xxx() is better.

Andrew - could you fix that up in place?

Obviously if there's further feedback I can respin as well.

>
>
> Another idea is to put all checks in one function and just add some comments
> on bypassing ones and allowed ones.
>
> > +}
> > +
> > +static bool vma_can_map_huge_file(const struct vm_area_struct *vma,
> > +		vm_flags_t vm_flags, enum tva_type type)
> > +{
> > +	const bool has_huge_fault = vma->vm_ops->huge_fault;
> > +
> > +	/*
> > +	 * Enforce THP collapse requirements as necessary. Anonymous vmas
> > +	 * were already handled in thp_vma_allowable_orders().
> > +	 */
> > +	if (!vma_check_thp_tuneables_file(vma, vm_flags, type))
> > +		return false;
> > +
> > +	switch (type) {
> > +	case TVA_PAGEFAULT:
> > +		/*
> > +		 * Trust that ->huge_fault() handlers know what they are doing
> > +		 * in fault path.
> > +		 */
> > +		return has_huge_fault;
> > +	case TVA_SMAPS:
> > +		if (has_huge_fault)
> > +			return true;
> > +		fallthrough;
> > +	default:
> > +		/* Only regular file is valid in collapse path. */
> > +		return file_thp_enabled(vma);
> > +	}
> > +}
> > +
> >  unsigned long __thp_vma_allowable_orders(struct vm_area_struct *vma,
> >  					 vm_flags_t vm_flags,
> >  					 enum tva_type type,
> > @@ -190,27 +251,8 @@ unsigned long __thp_vma_allowable_orders(struct vm_area_struct *vma,
> >  						   vma, vma_start_pgoff(vma), 0,
> >  						   forced_collapse);
> >
> > -	if (!vma_is_anonymous(vma)) {
> > -		/*
> > -		 * Enforce THP collapse requirements as necessary. Anonymous vmas
> > -		 * were already handled in thp_vma_allowable_orders().
> > -		 */
> > -		if (!forced_collapse &&
> > -		    (!hugepage_global_enabled() || (!(vm_flags & VM_HUGEPAGE) &&
> > -						    !hugepage_global_always())))
> > -			return 0;
> > -
> > -		/*
> > -		 * Trust that ->huge_fault() handlers know what they are doing
> > -		 * in fault path.
> > -		 */
> > -		if (((in_pf || smaps)) && vma->vm_ops->huge_fault)
> > -			return orders;
> > -		/* Only regular file is valid in collapse path */
> > -		if (((!in_pf || smaps)) && file_thp_enabled(vma))
> > -			return orders;
> > -		return 0;
> > -	}
> > +	if (!vma_is_anonymous(vma))
> > +		return vma_can_map_huge_file(vma, vm_flags, type) ? orders : 0;
> >
> >  	if (vma_is_temporary_stack(vma))
> >  		return 0;
> >
>
> The rest looks great to me. Thanks.

Thanks!

>
>
> --
> Best Regards,
> Yan, Zi
>

--
Cheers, Lorenzo

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH] mm/huge_memory: bypass THP tuneables for huge pfnmap mappings
  2026-08-27 19:55 [PATCH] mm/huge_memory: bypass THP tuneables for huge pfnmap mappings Lorenzo Stoakes (ARM)
  2026-08-28  2:52 ` Zi Yan
  2026-08-28  4:47 ` Lance Yang
@ 2026-08-28 16:46 ` Saravanan D
  2026-08-28 17:20   ` Lorenzo Stoakes (ARM)
  2 siblings, 1 reply; 6+ messages in thread
From: Saravanan D @ 2026-08-28 16:46 UTC (permalink / raw)
  To: Lorenzo Stoakes (ARM),
	Andrew Morton, David Hildenbrand, Zi Yan, Baolin Wang,
	Liam R. Howlett, Nico Pache, Ryan Roberts, Dev Jain, Barry Song,
	Lance Yang, Usama Arif, Peter Xu, Jason Gunthorpe
  Cc: Saravanan D, linux-mm, linux-kernel, Cedric Le Goater, stable

On Thu, Aug 27, 2026 at 08:55:57PM +0100, Lorenzo Stoakes (ARM) wrote:
> This is incorrect - if a huge PFN map is available (defined by
> vma->vm_ops->huge_fault being non-NULL for a VMA_PFNMAP_BIT VMA), then it
> should be mapped huge upon fault-in.
[...]
> Correct this by explicitly checking for this while ensuring that smaps
> continues to accurately report THPeligible statistics.

I backported this to a 6.17 based kernel and tested it under
cloud-hypervisor with THP left at the Ubuntu default of madvise, on
two GPU generations:

  - 4x H100, 128 GiB BAR1 each
  - 8x B300, 512 GiB BAR1 each

With the patch every BAR faults in entirely at PUD (1 GiB)
granularity, one entry per GiB of BAR, so 128 for each H100 BAR and
512 for each B300 BAR, and smaps reports THPeligible: 1 for every
vfio-device VMA. Total time in the huge_fault path was 4.5 ms on the
H100 node and 130 ms on the B300 node, and the VMs booted in 11.6s
and 32s respectively.

Tested-by: Saravanan D <saravanand@crusoe.ai>

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH] mm/huge_memory: bypass THP tuneables for huge pfnmap mappings
  2026-08-28 16:46 ` Saravanan D
@ 2026-08-28 17:20   ` Lorenzo Stoakes (ARM)
  0 siblings, 0 replies; 6+ messages in thread
From: Lorenzo Stoakes (ARM) @ 2026-08-28 17:20 UTC (permalink / raw)
  To: Saravanan D
  Cc: Andrew Morton, David Hildenbrand, Zi Yan, Baolin Wang,
	Liam R. Howlett, Nico Pache, Ryan Roberts, Dev Jain, Barry Song,
	Lance Yang, Usama Arif, Peter Xu, Jason Gunthorpe, linux-mm,
	linux-kernel, Cedric Le Goater, stable

On Fri, Aug 28, 2026 at 09:46:49AM -0700, Saravanan D wrote:
> On Thu, Aug 27, 2026 at 08:55:57PM +0100, Lorenzo Stoakes (ARM) wrote:
> > This is incorrect - if a huge PFN map is available (defined by
> > vma->vm_ops->huge_fault being non-NULL for a VMA_PFNMAP_BIT VMA), then it
> > should be mapped huge upon fault-in.
> [...]
> > Correct this by explicitly checking for this while ensuring that smaps
> > continues to accurately report THPeligible statistics.
>
> I backported this to a 6.17 based kernel and tested it under
> cloud-hypervisor with THP left at the Ubuntu default of madvise, on
> two GPU generations:
>
>   - 4x H100, 128 GiB BAR1 each
>   - 8x B300, 512 GiB BAR1 each
>
> With the patch every BAR faults in entirely at PUD (1 GiB)
> granularity, one entry per GiB of BAR, so 128 for each H100 BAR and
> 512 for each B300 BAR, and smaps reports THPeligible: 1 for every
> vfio-device VMA. Total time in the huge_fault path was 4.5 ms on the
> H100 node and 130 ms on the B300 node, and the VMs booted in 11.6s
> and 32s respectively.
>
> Tested-by: Saravanan D <saravanand@crusoe.ai>

Thanks! Appreciate the testing :) and glad this helps your usecase.

--
Cheers, Lorenzo

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2026-08-28 17:20 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-08-27 19:55 [PATCH] mm/huge_memory: bypass THP tuneables for huge pfnmap mappings Lorenzo Stoakes (ARM)
2026-08-28  2:52 ` Zi Yan
2026-08-28  7:11   ` Lorenzo Stoakes (ARM)
2026-08-28  4:47 ` Lance Yang
2026-08-28 16:46 ` Saravanan D
2026-08-28 17:20   ` Lorenzo Stoakes (ARM)

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®