Subject: Re: linux-next: manual merge of the vhost tree with the mm-unstable tree

From: "Michael S. Tsirkin" <[email-masked]>
Date: Thu, 4 Jun 2026 01:23:10 -0400

On Wed, Jun 03, 2026 at 08:02:22PM +0100, Mark Brown wrote:
> Hi all,
> 
> Today's linux-next merge of the vhost tree got conflicts in:
> 
>   include/linux/mm.h
>   include/linux/ptr_ring.h
>   mm/memory.c
>   mm/page_alloc.c
> 
> between at least commits:
> 
>   c0ea52c18c78c ("mm/huge_memory: simplify vma_is_specal_huge()")
>   fba362c17d9d9 ("ptr_ring: move free-space check into separate helper")
>   aa812f234b6c8 ("mm: memory: flatten alloc_anon_folio() retry loop")
> 
> from the mm-unstable tree and commits:
> 
>   dd3984b3bce9d ("ptr_ring: disable KCSAN warnings")
>   fba362c17d9d9 ("ptr_ring: move free-space check into separate helper")
>   f7a2566ae0c03 ("mm: move user page zeroing into the allocator")
> 
> from the vhost tree.  I note that the vhost tree does not appear to have
> anything from Linus' tree beyond v7.0-rc2, are you sure this is
> sensible?

Not at all, somehow I pushed a wrong hash I was experimenting with (
It was never intended for next.

> I am really not convinced about my fixups below.
> 
> I fixed it up (see below) and can carry the fix as necessary. This
> is now fixed as far as linux-next is concerned, but any non trivial
> conflicts should be mentioned to your upstream maintainer when your tree
> is submitted for merging.  You may also want to consider cooperating
> with the maintainer of the conflicting tree to minimise any particularly
> complex conflicts.
> 
> diff --cc include/linux/mm.h
> index 485df9c2dbddb,f600c0428aad9..0000000000000
> --- a/include/linux/mm.h
> +++ b/include/linux/mm.h
> @@@ -5088,6 -4714,25 +5100,9 @@@ long copy_folio_from_user(struct folio 
>   			   const void __user *usr_src,
>   			   bool allow_pagefault);
>   
>  -/**
>  - * vma_is_special_huge - Are transhuge page-table entries considered special?
>  - * @vma: Pointer to the struct vm_area_struct to consider
>  - *
>  - * Whether transhuge page-table entries are considered "special" following
>  - * the definition in vm_normal_page().
>  - *
>  - * Return: true if transhuge page-table entries should be considered special,
>  - * false otherwise.
>  - */
>  -static inline bool vma_is_special_huge(const struct vm_area_struct *vma)
>  -{
>  -	return vma_is_dax(vma) || (vma->vm_file &&
>  -				   (vma->vm_flags & (VM_PFNMAP | VM_MIXEDMAP)));
>  -}
>  -
> + #else /* !CONFIG_TRANSPARENT_HUGEPAGE && !CONFIG_HUGETLBFS */
> + #define folio_zero_user(folio, addr_hint) \
> + 	clear_user_highpages(&(folio)->page, (addr_hint), folio_nr_pages(folio))
>   #endif /* CONFIG_TRANSPARENT_HUGEPAGE || CONFIG_HUGETLBFS */
>   
>   #if MAX_NUMNODES > 1
> diff --cc include/linux/ptr_ring.h
> index c95e891903f05,d2c3629bbe451..0000000000000
> --- a/include/linux/ptr_ring.h
> +++ b/include/linux/ptr_ring.h
> diff --cc mm/memory.c
> index 56be920c56d74,beb6ce312dec6..0000000000000
> --- a/mm/memory.c
> +++ b/mm/memory.c
> diff --cc mm/page_alloc.c
> index 81a9d4d1e6c0a,cb72dd6e0efb3..0000000000000
> --- a/mm/page_alloc.c
> +++ b/mm/page_alloc.c
> @@@ -90,8 -90,12 +90,14 @@@ typedef int __bitwise fpi_t
>   /* Free the page without taking locks. Rely on trylock only. */
>   #define FPI_TRYLOCK		((__force fpi_t)BIT(2))
>   
>  +/* free_pages_prepare() has already been called for page(s) being freed. */
>  +#define FPI_PREPARED		((__force fpi_t)BIT(3))
> + /*
> +  * The page contents are known to be zero (e.g., the host zeroed them
> +  * during balloon deflate).  Set PagePrezeroed after free so the next
> +  * allocation can skip redundant zeroing.
> +  */
>  -#define FPI_PREZEROED		((__force fpi_t)BIT(3))
> ++#define FPI_PREZEROED		((__force fpi_t)BIT(4))
>   
>   /* prevent >1 _updater_ of zone percpu pageset ->high and ->batch fields */
>   static DEFINE_MUTEX(pcp_batch_high_lock);
> @@@ -1806,15 -1881,25 +1850,25 @@@ static inline bool should_skip_init(gfp
>   	return (flags & __GFP_SKIP_ZERO);
>   }
>   
> + 
>   inline void post_alloc_hook(struct page *page, unsigned int order,
> - 				gfp_t gfp_flags)
> + 				gfp_t gfp_flags, bool prezeroed,
> + 				unsigned long user_addr)
>   {
>  +	const bool zero_tags = gfp_flags & __GFP_ZEROTAGS;
>   	bool init = !want_init_on_free() && want_init_on_alloc(gfp_flags) &&
>   			!should_skip_init(gfp_flags);
>  -	bool zero_tags = init && (gfp_flags & __GFP_ZEROTAGS);
>   	int i;
>   
> - 	set_page_private(page, 0);
> + 	__ClearPagePrezeroed(page);
> + 
> + 	/*
> + 	 * If the page is pre-zeroed, skip memory initialization.
> + 	 * We still need to handle tag zeroing separately since the host
> + 	 * does not know about memory tags.
> + 	 */
> + 	if (prezeroed && init && !zero_tags)
> + 		init = false;
>   
>   	arch_alloc_page(page, order);
>   	debug_pagealloc_map_pages(page, 1 << order);
> @@@ -3244,15 -3347,9 +3309,16 @@@ struct page *rmqueue_buddy(struct zone 
>   			}
>   		}
>   		spin_unlock_irqrestore(&zone->lock, flags);
> + 		*prezeroed = __page_test_clear_prezeroed(page);
>   	} while (check_new_pages(page, order));
>   
>  +	/*
>  +	 * If this is a high-order atomic allocation then check
>  +	 * if the pageblock should be reserved for the future
>  +	 */
>  +	if (unlikely(alloc_flags & ALLOC_HIGHATOMIC))
>  +		reserve_highatomic_pageblock(page, order, zone);
>  +
>   	__count_zid_vm_events(PGALLOC, page_zonenum(page), 1 << order);
>   	zone_statistics(preferred_zone, zone, 1);
>   
> @@@ -3376,8 -3461,9 +3443,8 @@@ static struct page *rmqueue_pcplist(str
>   	 */
>   	pcp->free_count >>= 1;
>   	list = &pcp->lists[order_to_pindex(migratetype, order)];
> - 	page = __rmqueue_pcplist(zone, order, migratetype, alloc_flags, pcp, list);
>  -	page = __rmqueue_pcplist(zone, order, migratetype, alloc_flags,
>  -				 pcp, list, prezeroed);
>  -	pcp_spin_unlock(pcp, UP_flags);
> ++	page = __rmqueue_pcplist(zone, order, migratetype, alloc_flags, pcp, list, prezeroed);
>  +	pcp_spin_unlock(pcp);
>   	if (page) {
>   		__count_zid_vm_events(PGALLOC, page_zonenum(page), 1 << order);
>   		zone_statistics(preferred_zone, zone, 1);
> @@@ -3941,10 -4035,19 +4009,12 @@@ check_alloc_wmark
>   
>   try_this_zone:
>   		page = rmqueue(zonelist_zone(ac->preferred_zoneref), zone, order,
> - 				gfp_mask, alloc_flags, ac->migratetype);
> + 					gfp_mask, alloc_flags, ac->migratetype,
> + 					&prezeroed);
>   		if (page) {
> - 			prep_new_page(page, order, gfp_mask, alloc_flags);
> + 			prep_new_page(page, order, gfp_mask, alloc_flags,
> + 				      prezeroed, ac->user_addr);
>   
>  -			/*
>  -			 * If this is a high-order atomic allocation then check
>  -			 * if the pageblock should be reserved for the future
>  -			 */
>  -			if (unlikely(alloc_flags & ALLOC_HIGHATOMIC))
>  -				reserve_highatomic_pageblock(page, order, zone);
>  -
>   			return page;
>   		} else {
>   			if (cond_accept_memory(zone, order, alloc_flags))