Re: [PATCH v3 03/12] mm/huge_memory: move THP gfp limit helper into header
From: Zi Yan
Date: Tue Apr 21 2026 - 09:14:23 EST
On 21 Apr 2026, at 2:16, Kairui Song via B4 Relay wrote:
> From: Kairui Song <kasong@xxxxxxxxxxx>
>
> Shmem has some special requirements for THP GFP and has to limit it in
> certain zones or provide a more lenient fallback.
>
> We'll use this helper for generic swap THP allocation, which needs to
> support shmem. For a typical GFP_HIGHUSER_MOVABLE swap-in, this helper
> is basically a no-op. But it's necessary for certain shmem users, mostly
> drivers.
>
> No feature change.
>
> Signed-off-by: Kairui Song <kasong@xxxxxxxxxxx>
> ---
> include/linux/huge_mm.h | 30 ++++++++++++++++++++++++++++++
> mm/shmem.c | 30 +++---------------------------
> 2 files changed, 33 insertions(+), 27 deletions(-)
>
> diff --git a/include/linux/huge_mm.h b/include/linux/huge_mm.h
> index 2949e5acff35..ffe5a120eee4 100644
> --- a/include/linux/huge_mm.h
> +++ b/include/linux/huge_mm.h
> @@ -237,6 +237,31 @@ static inline bool thp_vma_suitable_order(struct vm_area_struct *vma,
> return true;
> }
>
> +/*
> + * Make sure huge_gfp is always more limited than limit_gfp.
> + * Some shmem users want THP allocation to be done less aggressively
> + * and only in certain zone.
> + */
> +static inline gfp_t thp_limit_gfp_mask(gfp_t huge_gfp, gfp_t limit_gfp)
Would it be better to rename it to thp_swap_limit_gfp_mask() or something
more descriptive? I am just worried about misuses in the future due to
the generic thp prefix.
Otherwise, LGTM.
Reviewed-by: Zi Yan <ziy@xxxxxxxxxx>
> +{
> + gfp_t allowflags = __GFP_IO | __GFP_FS | __GFP_RECLAIM;
> + gfp_t denyflags = __GFP_NOWARN | __GFP_NORETRY;
> + gfp_t zoneflags = limit_gfp & GFP_ZONEMASK;
> + gfp_t result = huge_gfp & ~(allowflags | GFP_ZONEMASK);
> +
> + /* Allow allocations only from the originally specified zones. */
> + result |= zoneflags;
> +
> + /*
> + * Minimize the result gfp by taking the union with the deny flags,
> + * and the intersection of the allow flags.
> + */
> + result |= (limit_gfp & denyflags);
> + result |= (huge_gfp & limit_gfp) & allowflags;
> +
> + return result;
> +}
> +
> /*
> * Filter the bitfield of input orders to the ones suitable for use in the vma.
> * See thp_vma_suitable_order().
> @@ -581,6 +606,11 @@ static inline bool thp_vma_suitable_order(struct vm_area_struct *vma,
> return false;
> }
>
> +static inline gfp_t thp_limit_gfp_mask(gfp_t huge_gfp, gfp_t limit_gfp)
> +{
> + return huge_gfp;
> +}
> +
> static inline unsigned long thp_vma_suitable_orders(struct vm_area_struct *vma,
> unsigned long addr, unsigned long orders)
> {
--
Best Regards,
Yan, Zi