On Mon, May 11, 2026 at 05:01:55AM -0400, Michael S. Tsirkin wrote:
> Thread a user virtual address from vma_alloc_folio() down through
> the page allocator to post_alloc_hook(). This is plumbing
> preparation for a subsequent patch that will use user_addr to
> call folio_zero_user() for cache-friendly zeroing of user pages.
> 
> The user_addr is stored in struct alloc_context and flows through:
>   vma_alloc_folio -> folio_alloc_mpol -> __alloc_pages_mpol ->
>   __alloc_frozen_pages -> get_page_from_freelist -> prep_new_page ->
>   post_alloc_hook

This is the nitty-est of all nits, but when doing this can we please
prefer stack style?

  vma_alloc_folio 
    folio_alloc_mpol 
      __alloc_pages_mpol 
        __alloc_frozen_pages 
          get_page_from_freelist 
            prep_new_page 
              post_alloc_hook

Claude has a bad habit of writing changelog changes this way, and it's
painful for a human to try to read.

> 
> USER_ADDR_NONE ((unsigned long)-1) is used for non-user
> allocations, since address 0 is a valid userspace mapping.
> 

> +/*
> + * Sentinel for user_addr: indicates a non-user allocation.
> + * Cannot use 0 because address 0 is a valid userspace mapping.
> + */
> +#define USER_ADDR_NONE       ((unsigned long)-1)

Ehm, hm.  Does -1 hold as a non-user address across all architectures?

What about in linear addressing / no VM mode?

> diff --git a/include/linux/gfp.h b/include/linux/gfp.h
> index 7ccbda35b9ad..ee35c5367abc 100644
> --- a/include/linux/gfp.h
> +++ b/include/linux/gfp.h
> @@ -337,7 +337,7 @@ static inline struct folio *folio_alloc_noprof(gfp_t gfp, 
> unsigned int order)
>  static inline struct folio *folio_alloc_mpol_noprof(gfp_t gfp, unsigned int 
> order,
>               struct mempolicy *mpol, pgoff_t ilx, int nid)
>  {
> -     return folio_alloc_noprof(gfp, order);
> +     return __folio_alloc_noprof(gfp, order, numa_node_id(), NULL);
>  }
>  #endif
>  

This change seems out of place unless i'm missing something.


> diff --git a/mm/hugetlb.c b/mm/hugetlb.c
> index f24bf49be047..a999f3ead852 100644
> --- a/mm/hugetlb.c
> +++ b/mm/hugetlb.c
> @@ -1806,7 +1806,8 @@ struct address_space 
> *hugetlb_folio_mapping_lock_write(struct folio *folio)
>  }
>  
>  static struct folio *alloc_buddy_frozen_folio(int order, gfp_t gfp_mask,
> -             int nid, nodemask_t *nmask, nodemask_t *node_alloc_noretry)
> +             int nid, nodemask_t *nmask, nodemask_t *node_alloc_noretry,
> +             unsigned long addr)

                       user_addr?  uaddr?

> @@ -1823,7 +1824,7 @@ static struct folio *alloc_buddy_frozen_folio(int 
> order, gfp_t gfp_mask,
>       if (alloc_try_hard)
>               gfp_mask |= __GFP_RETRY_MAYFAIL;
>  
> -     folio = (struct folio *)__alloc_frozen_pages(gfp_mask, order, nid, 
> nmask);
> +     folio = (struct folio *)__alloc_frozen_pages(gfp_mask, order, nid, 
> nmask, addr);

Not on you, but the changes in hugetlb.c as a whole are :[

We do all of this to pass USER_ADDR_NONE all over the place, but the
alternative is having a separate function specifically for user-land
bound allocations.

So the trade off is:
   a) churn the current interface for everyone
   b) add a user_ variant and know people will just get it wrong

IIRC you said the consequence of getting wrong here is subtle corruption
if a caller got it wrong, and this was related to cache flushing for the
provided user address?

Stupid question: Does this not apply to kernel allocations as well? Or
is it simply a matter of the cache having stale data that could leak,
and therefore it's not a concern in-kernel?

~Gregory

Reply via email to