Re: [PATCH v3 06/10] mm: shmem: drop has_transparent_hugepage() usage

Lance Yang
2026-04-11T04:00:45Z

On 2026/4/10 23:59, Lance Yang wrote:
>
> On Wed, Apr 08, 2026 at 04:23:01PM -0400, Luiz Capitulino wrote:
>> Shmem uses has_transparent_hugepage() in the following ways:
>>
>> - shmem_parse_one() and shmem_parse_huge(): Check if THP is built-in and
>> if the CPU supports PMD-sized pages
>>
>> - shmem_init(): Since the CONFIG_TRANSPARENT_HUGEPAGE guard is outside
>> the code block calling has_transparent_hugepage(), the
>> has_transparent_hugepage() call is exclusively checking if the CPU
>> supports PMD-sized pages
>>
>> While it's necessary to check if CONFIG_TRANSPARENT_HUGEPAGE is enabled
>> in all cases, shmem can determine mTHP size support at folio allocation
>> time. Therefore, drop has_transparent_hugepage() usage while keeping the
>> CONFIG_TRANSPARENT_HUGEPAGE checks.
>>
>> Signed-off-by: Luiz Capitulino <luizcap@redhat.com>
>> ---
>> mm/shmem.c | 7 +++----
>> 1 file changed, 3 insertions(+), 4 deletions(-)
>>
>> diff --git a/mm/shmem.c b/mm/shmem.c
>> index b40f3cd48961..6f8b20d77e07 100644
>> --- a/mm/shmem.c
>> +++ b/mm/shmem.c
>> @@ -689,7 +689,7 @@ static int shmem_parse_huge(const char *str)
>> else
>> return -EINVAL;
>>
>> - if (!has_transparent_hugepage() &&
>> + if (!IS_ENABLED(CONFIG_TRANSPARENT_HUGEPAGE) &&
>> huge != SHMEM_HUGE_NEVER && huge != SHMEM_HUGE_DENY)
>> return -EINVAL;
>>
>> @@ -4664,8 +4664,7 @@ static int shmem_parse_one(struct fs_context *fc, struct fs_parameter *param)
>> case Opt_huge:
>> ctx->huge = result.uint_32;
>> if (ctx->huge != SHMEM_HUGE_NEVER &&
>> - !(IS_ENABLED(CONFIG_TRANSPARENT_HUGEPAGE) &&
>> - has_transparent_hugepage()))
>> + !IS_ENABLED(CONFIG_TRANSPARENT_HUGEPAGE))
>> goto unsupported_parameter;
>> ctx->seen |= SHMEM_SEEN_HUGE;
>> break;
>> @@ -5451,7 +5450,7 @@ void __init shmem_init(void)
>> #endif
>>
>> #ifdef CONFIG_TRANSPARENT_HUGEPAGE
>> - if (has_transparent_hugepage() && shmem_huge > SHMEM_HUGE_DENY)
>> + if (shmem_huge > SHMEM_HUGE_DENY)
>> SHMEM_SB(shm_mnt->mnt_sb)->huge = shmem_huge;
>> else
>> shmem_huge = SHMEM_HUGE_NEVER; /* just in case it was patched */
>> --
>
> Although this patch simply drops the early has_transparent_hugepage()
> checks from the shmem parse/init paths, shmem_allowable_huge_orders()
> still returns 0 when thp_disabled_by_hw() is set.
>
> So on hardware without PMD THP support:
>
> unsigned long shmem_allowable_huge_orders(struct inode *inode,
> struct vm_area_struct *vma, pgoff_t index,
> loff_t write_end, bool shmem_huge_force)
> {
> ...
> if (thp_disabled_by_hw() || (vma && vma_thp_disabled(vma, vm_flags, shmem_huge_force)))
> return 0;
> ...
> }
>
> 1) the fault path still falls back to order-0 allocation
> 2) do_set_pmd() still falls back
> 3) khugepaged won't collapse it either

Forgot to add:

4) the buffered write path also falls back for tmpfs mounts

>
> Nothing jumped out at me, thanks!
>
> Reviewed-by: Lance Yang <lance.yang@linux.dev>