mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* linux-next: manual merge of the liveupdate tree with the mm tree
@ 2026-09-24 17:08 Mark Brown
  2026-09-24 17:36 ` Mike Rapoport
  0 siblings, 1 reply; 3+ messages in thread
From: Mark Brown @ 2026-09-24 17:08 UTC (permalink / raw)
  To: Mike Rapoport, Andrew Morton, Pasha Tatashin, Pratyush Yadav
  Cc: Linux Kernel Mailing List, Linux Next Mailing List, Muchun Song,
	Muchun Song

[-- Attachment #1: Type: text/plain, Size: 15823 bytes --]

Hi all,

Today's linux-next merge of the liveupdate tree got a conflict in:

  mm/mm_init.c

between commit:

  a666a70d029d3 ("mm/mm_init: skip initializing shared vmemmap tail pages")

from the mm tree and commit:

  85d3615cea179 ("kho: rename KHO scratch to KHO bootmem")

from the liveupdate tree.

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 --combined mm/mm_init.c
index dc835f753ea9a,24a53d5f0893d..0000000000000
--- a/mm/mm_init.c
+++ b/mm/mm_init.c
@@@ -29,7 -29,6 +29,7 @@@
  #include <linux/cma.h>
  #include <linux/crash_dump.h>
  #include <linux/execmem.h>
 +#include <linux/sizes.h>
  #include <linux/vmstat.h>
  #include <linux/kexec_handover.h>
  #include <linux/hugetlb.h>
@@@ -678,33 -677,21 +678,33 @@@ static inline void fixup_hashdist(void
  static inline void fixup_hashdist(void) {}
  #endif /* CONFIG_NUMA */
  
 -#if defined(CONFIG_ZONE_DEVICE) || defined(CONFIG_DEFERRED_STRUCT_PAGE_INIT)
  static __meminit void pageblock_migratetype_init_range(unsigned long pfn,
 -		unsigned long nr_pages, int migratetype, bool atomic)
 +		unsigned long nr_pages, int migratetype, bool isolate, bool atomic)
  {
  	const unsigned long end = pfn + nr_pages;
  
  	for (pfn = pageblock_align(pfn); pfn < end; pfn += pageblock_nr_pages) {
- 		enum migratetype mt = kho_scratch_migratetype(pfn, migratetype);
+ 		enum migratetype mt = kho_bootmem_migratetype(pfn, migratetype);
  
 -		init_pageblock_migratetype(pfn_to_page(pfn), mt, false);
 -		if (!atomic && IS_ALIGNED(pfn, PAGES_PER_SECTION))
 +		init_pageblock_migratetype(pfn_to_page(pfn), mt, isolate);
 +		if (!atomic && IS_ALIGNED(pfn, PFN_DOWN(SZ_1G)))
  			cond_resched();
  	}
  }
 -#endif
 +
 +struct zone __meminit *pfn_to_zone(unsigned long pfn, int nid)
 +{
 +	pg_data_t *pgdat = NODE_DATA(nid);
 +
 +	for (enum zone_type zone_type = 0; zone_type < MAX_NR_ZONES; zone_type++) {
 +		struct zone *zone = &pgdat->node_zones[zone_type];
 +
 +		if (zone_spans_pfn(zone, pfn))
 +			return zone;
 +	}
 +
 +	return NULL;
 +}
  
  #ifdef CONFIG_DEFERRED_STRUCT_PAGE_INIT
  static inline void pgdat_set_deferred_range(pg_data_t *pgdat)
@@@ -764,17 -751,23 +764,17 @@@ defer_init(int nid, unsigned long pfn, 
  
  static void __meminit __init_deferred_page(unsigned long pfn, int nid)
  {
 -	pg_data_t *pgdat = NODE_DATA(nid);
 -	int zid;
 +	struct zone *zone;
  
  	if (early_page_initialised(pfn, nid))
  		return;
  
 -	for (zid = 0; zid < MAX_NR_ZONES; zid++) {
 -		struct zone *zone = &pgdat->node_zones[zid];
 -
 -		if (zone_spans_pfn(zone, pfn))
 -			break;
 -	}
 -	__init_single_page(pfn_to_page(pfn), pfn, zid, nid);
 -
 +	zone = pfn_to_zone(pfn, nid);
 +	__init_single_page(pfn_to_page(pfn), pfn,
 +			   zone ? zone_idx(zone) : MAX_NR_ZONES, nid);
  	if (pageblock_aligned(pfn)) {
  		enum migratetype mt =
- 			kho_scratch_migratetype(pfn, MIGRATE_MOVABLE);
+ 			kho_bootmem_migratetype(pfn, MIGRATE_MOVABLE);
  		init_pageblock_migratetype(pfn_to_page(pfn), mt, false);
  	}
  }
@@@ -823,41 -816,23 +823,41 @@@ void __meminit init_deferred_page(unsig
   *   the zone boundary; the pages in such holes will be prepended to the
   *   zone/node above the hole except for the trailing pages in the last
   *   section that will be appended to the zone/node below.
 + *
 + * The function counts pages that should be added to
 + * zone->pages_with_online_memmap. With CONFIG_SPARSEMEM_VMEMMAP there could
 + * be offline subsections even though the entire memory map is valid and all
 + * the early sections are online. Count only pages in online subsections
 + * (see pfn_to_online_page()).
   */
 -static void __init init_unavailable_range(unsigned long spfn,
 -					  unsigned long epfn,
 -					  int zone, int node)
 +static unsigned long __init init_unavailable_range(unsigned long spfn,
 +						   unsigned long epfn,
 +						   int zone, int node)
  {
 +	unsigned long next_chunk_pfn __maybe_unused = spfn;
  	unsigned long pfn;
 -	u64 pgcnt = 0;
 +	u64 online_pgcnt = 0, pgcnt = 0;
 +	bool is_online = true;
  
  	for_each_valid_pfn(pfn, spfn, epfn) {
  		__init_single_page(pfn_to_page(pfn), pfn, zone, node);
  		__SetPageReserved(pfn_to_page(pfn));
  		pgcnt++;
 +
 +#ifdef CONFIG_SPARSEMEM_VMEMMAP
 +		if (pfn >= next_chunk_pfn) {
 +			is_online = pfn_section_valid(__pfn_to_section(pfn), pfn);
 +			next_chunk_pfn = min(SUBSECTION_ALIGN_UP(pfn + 1), epfn);
 +		}
 +#endif
 +		if (is_online)
 +			online_pgcnt++;
  	}
  
  	if (pgcnt)
  		pr_info("On node %d, zone %s: %lld pages in unavailable ranges\n",
  			node, zone_names[zone], pgcnt);
 +	return online_pgcnt;
  }
  
  /*
@@@ -911,17 -886,6 +911,17 @@@ void __meminit memmap_init_range(unsign
  			}
  		}
  
 +		/*
 +		 * Vmemmap-optimizable PFNs are backed by shared tail struct pages,
 +		 * which have already been initialized during vmemmap population.
 +		 */
 +		if (vmemmap_optimizable_pfn(pfn)) {
 +			const unsigned int order = pfn_to_section_compound_order(pfn);
 +
 +			pfn = min(ALIGN(pfn, 1UL << order), end_pfn);
 +			continue;
 +		}
 +
  		page = pfn_to_page(pfn);
  		__init_single_page(page, pfn, zone, nid);
  		if (context == MEMINIT_HOTPLUG) {
@@@ -933,13 -897,19 +933,13 @@@
  				__SetPageOffline(page);
  		}
  
 -		/*
 -		 * Usually, we want to mark the pageblock MIGRATE_MOVABLE,
 -		 * such that unmovable allocations won't be scattered all
 -		 * over the place during system boot.
 -		 */
 -		if (pageblock_aligned(pfn)) {
 -			enum migratetype mt = kho_bootmem_migratetype(pfn, migratetype);
 -
 -			init_pageblock_migratetype(page, mt, isolate_pageblock);
 +		if (pageblock_aligned(pfn))
  			cond_resched();
 -		}
  		pfn++;
  	}
 +
 +	pageblock_migratetype_init_range(start_pfn, pfn - start_pfn, migratetype,
 +					 isolate_pageblock, /* atomic */ false);
  }
  
  static void __init memmap_init_zone_range(struct zone *zone,
@@@ -960,21 -930,9 +960,21 @@@
  	memmap_init_range(end_pfn - start_pfn, nid, zone_id, start_pfn,
  			  zone_end_pfn, MEMINIT_EARLY, NULL, MIGRATE_MOVABLE,
  			  false);
 +	zone->pages_with_online_memmap += end_pfn - start_pfn;
  
 -	if (*hole_pfn < start_pfn)
 -		init_unavailable_range(*hole_pfn, start_pfn, zone_id, nid);
 +	if (*hole_pfn < start_pfn) {
 +		unsigned long hole_start_pfn = *hole_pfn;
 +		unsigned long pgcnt;
 +
 +		if (hole_start_pfn < zone_start_pfn) {
 +			init_unavailable_range(hole_start_pfn, zone_start_pfn,
 +					       zone_id, nid);
 +			hole_start_pfn = zone_start_pfn;
 +		}
 +		pgcnt = init_unavailable_range(hole_start_pfn, start_pfn,
 +					       zone_id, nid);
 +		zone->pages_with_online_memmap += pgcnt;
 +	}
  
  	*hole_pfn = end_pfn;
  }
@@@ -1042,9 -1000,13 +1042,9 @@@ static void __ref __init_zone_device_pa
  	page->zone_device_data = NULL;
  
  	/*
 -	 * ZONE_DEVICE pages other than MEMORY_TYPE_GENERIC are released
 -	 * directly to the driver page allocator which will set the page count
 -	 * to 1 when allocating the page.
 -	 *
 -	 * MEMORY_TYPE_GENERIC and MEMORY_TYPE_FS_DAX pages automatically have
 -	 * their refcount reset to one whenever they are freed (ie. after
 -	 * their refcount drops to 0).
 +	 * MEMORY_DEVICE_GENERIC pages regain a refcount of 1 in the free
 +	 * path. The remaining ZONE_DEVICE types start from 0 here and raise
 +	 * the count again when the allocator or driver hands the page out.
  	 */
  	switch (pgmap->type) {
  	case MEMORY_DEVICE_FS_DAX:
@@@ -1059,17 -1021,6 +1059,17 @@@
  	}
  }
  
 +static void zone_device_page_init_from_template(struct page *page,
 +		unsigned long pfn, struct page *template)
 +{
 +	set_page_section_from_pfn(template, pfn);
 +#ifdef WANT_PAGE_VIRTUAL
 +	if (!is_highmem_idx(ZONE_DEVICE))
 +		set_page_address(template, __va(pfn << PAGE_SHIFT));
 +#endif
 +	memcpy_nontemporal(page, template, sizeof(*page));
 +}
 +
  /*
   * With compound page geometry and when struct pages are stored in ram most
   * tail pages are reused. Consequently, the amount of unique struct pages to
@@@ -1079,14 -1030,19 +1079,14 @@@
   * of an altmap. See vmemmap_populate_compound_pages().
   */
  static inline unsigned long compound_nr_pages(unsigned long pfn,
 -					      struct vmem_altmap *altmap,
  					      struct dev_pagemap *pgmap)
  {
 -	/*
 -	 * If DAX memory is hot-plugged into an unoccupied subsection
 -	 * of an early section, the unoptimized boot memmap is reused.
 -	 * See section_activate().
 -	 */
 -	if (early_section(__pfn_to_section(pfn)) ||
 -	    !vmemmap_can_optimize(altmap, pgmap))
 +	const struct mem_section *ms = __pfn_to_section(pfn);
 +
 +	if (!section_vmemmap_optimizable(ms))
  		return pgmap_vmemmap_nr(pgmap);
  
 -	return VMEMMAP_RESERVE_NR * (PAGE_SIZE / sizeof(struct page));
 +	return VMEMMAP_OPTIMIZATION_PAGES * (PAGE_SIZE / sizeof(struct page));
  }
  
  static void __ref memmap_init_compound(struct page *head,
@@@ -1097,8 -1053,6 +1097,8 @@@
  {
  	unsigned long pfn, end_pfn = head_pfn + nr_pages;
  	unsigned int order = pgmap->vmemmap_shift;
 +	struct page template;
 +	struct page *page;
  
  	/*
  	 * We have to initialize the pages, including setting up page links.
@@@ -1107,23 -1061,13 +1107,23 @@@
  	 * the pages in the same go.
  	 */
  	__SetPageHead(head);
 -	for (pfn = head_pfn + 1; pfn < end_pfn; pfn++) {
 -		struct page *page = pfn_to_page(pfn);
  
 -		__init_zone_device_page(page, pfn, zone_idx, nid, pgmap);
 -		prep_compound_tail(page, head, order);
 -		set_page_count(page, 0);
 -	}
 +	/*
 +	 * All tails of the same compound page share the state established by
 +	 * prep_compound_tail(). Reuse one tail template for the whole range and
 +	 * refresh only the PFN-dependent fields in that template before each copy.
 +	 */
 +	pfn = head_pfn + 1;
 +	page = pfn_to_page(pfn);
 +	__init_zone_device_page(page, pfn, zone_idx, nid, pgmap);
 +	prep_compound_tail(page, head, order);
 +	set_page_count(page, 0);
 +	memcpy(&template, page, sizeof(*page));
 +
 +	/* Initialize the remaining tail pages from template. */
 +	for (pfn = head_pfn + 2; pfn < end_pfn; pfn++)
 +		zone_device_page_init_from_template(pfn_to_page(pfn), pfn,
 +						    &template);
  	prep_compound_head(head, order);
  }
  
@@@ -1139,8 -1083,6 +1139,8 @@@ void __ref memmap_init_zone_device(stru
  	unsigned long zone_idx = zone_idx(zone);
  	unsigned long start = jiffies;
  	int nid = pgdat->node_id;
 +	struct page template;
 +	struct page *page;
  
  	if (WARN_ON_ONCE(!pgmap || zone_idx != ZONE_DEVICE))
  		return;
@@@ -1155,28 -1097,10 +1155,28 @@@
  		nr_pages = end_pfn - start_pfn;
  	}
  
 -	for (pfn = start_pfn; pfn < end_pfn; pfn += pfns_per_compound) {
 -		struct page *page = pfn_to_page(pfn);
 +	if (!nr_pages)
 +		return;
  
 -		__init_zone_device_page(page, pfn, zone_idx, nid, pgmap);
 +	/*
 +	 * Seed the reusable head-page template from the first real struct
 +	 * page. The normal page-init and refcount helpers must operate on
 +	 * a real memmap entry rather than a stack object.
 +	 */
 +	pfn = start_pfn;
 +	page = pfn_to_page(pfn);
 +	__init_zone_device_page(page, pfn, zone_idx, nid, pgmap);
 +	memcpy(&template, page, sizeof(*page));
 +	if (pfns_per_compound != 1)
 +		memmap_init_compound(page, pfn, zone_idx, nid, pgmap,
 +				     compound_nr_pages(pfn, pgmap));
 +	pfn += pfns_per_compound;
 +
 +	/* Initialize the remaining head pages from template. */
 +	for (; pfn < end_pfn; pfn += pfns_per_compound) {
 +		page = pfn_to_page(pfn);
 +
 +		zone_device_page_init_from_template(page, pfn, &template);
  
  		if (IS_ALIGNED(pfn, PAGES_PER_SECTION))
  			cond_resched();
@@@ -1185,11 -1109,10 +1185,11 @@@
  			continue;
  
  		memmap_init_compound(page, pfn, zone_idx, nid, pgmap,
 -				     compound_nr_pages(pfn, altmap, pgmap));
 +				     compound_nr_pages(pfn, pgmap));
  	}
  
 -	pageblock_migratetype_init_range(start_pfn, nr_pages, MIGRATE_MOVABLE, false);
 +	pageblock_migratetype_init_range(start_pfn, nr_pages, MIGRATE_MOVABLE,
 +					 /* isolate */ false, /* atomic */ false);
  
  	pr_debug("%s initialised %lu pages in %ums\n", __func__,
  		nr_pages, jiffies_to_msecs(jiffies - start));
@@@ -1243,10 -1166,6 +1243,10 @@@ static unsigned long __init __absent_pa
  	unsigned long start_pfn, end_pfn;
  	int i;
  
 +	/* range is empty, nothing to do */
 +	if (!nr_absent)
 +		return 0;
 +
  	for_each_mem_pfn_range(i, nid, &start_pfn, &end_pfn, NULL) {
  		start_pfn = clamp(start_pfn, range_start_pfn, range_end_pfn);
  		end_pfn = clamp(end_pfn, range_start_pfn, range_end_pfn);
@@@ -1268,9 -1187,22 +1268,9 @@@ unsigned long __init absent_pages_in_ra
  	return __absent_pages_in_range(MAX_NUMNODES, start_pfn, end_pfn);
  }
  
 -/* Return the number of page frames in holes in a zone on a node */
 -static unsigned long __init zone_absent_pages_in_node(int nid,
 -					unsigned long zone_type,
 -					unsigned long zone_start_pfn,
 -					unsigned long zone_end_pfn)
 -{
 -	/* zone is empty, we don't have any absent pages */
 -	if (zone_start_pfn == zone_end_pfn)
 -		return 0;
 -
 -	return __absent_pages_in_range(nid, zone_start_pfn, zone_end_pfn);
 -}
 -
  /*
   * Return the number of pages a zone spans in a node, including holes
 - * present_pages = zone_spanned_pages_in_node() - zone_absent_pages_in_node()
 + * present_pages = zone_spanned_pages_in_node() - __absent_pages_in_range()
   */
  static unsigned long __init zone_spanned_pages_in_node(int nid,
  					unsigned long zone_type,
@@@ -1360,8 -1292,9 +1360,8 @@@ static void __init calculate_node_total
  						     node_end_pfn,
  						     &zone_start_pfn,
  						     &zone_end_pfn);
 -		absent = zone_absent_pages_in_node(pgdat->node_id, i,
 -						   zone_start_pfn,
 -						   zone_end_pfn);
 +		absent = __absent_pages_in_range(pgdat->node_id, zone_start_pfn,
 +						 zone_end_pfn);
  
  		real_size = spanned - absent;
  
@@@ -1988,8 -1921,7 +1988,8 @@@ static void __init deferred_free_pages(
  	if (!nr_pages)
  		return;
  
 -	pageblock_migratetype_init_range(pfn, nr_pages, MIGRATE_MOVABLE, true);
 +	pageblock_migratetype_init_range(pfn, nr_pages, MIGRATE_MOVABLE,
 +					 /* isolate */ false, /* atomic */ true);
  
  	page = pfn_to_page(pfn);
  
@@@ -2256,6 -2188,28 +2256,6 @@@ void __init init_cma_pageblock(struct p
  }
  #endif
  
 -void set_zone_contiguous(struct zone *zone)
 -{
 -	unsigned long block_start_pfn = zone->zone_start_pfn;
 -	unsigned long block_end_pfn;
 -
 -	block_end_pfn = pageblock_end_pfn(block_start_pfn);
 -	for (; block_start_pfn < zone_end_pfn(zone);
 -			block_start_pfn = block_end_pfn,
 -			 block_end_pfn += pageblock_nr_pages) {
 -
 -		block_end_pfn = min(block_end_pfn, zone_end_pfn(zone));
 -
 -		if (!__pageblock_pfn_to_page(block_start_pfn,
 -					     block_end_pfn, zone))
 -			return;
 -		cond_resched();
 -	}
 -
 -	/* We confirm that there is no hole */
 -	zone->contiguous = true;
 -}
 -
  /*
   * Check if a PFN range intersects multiple zones on one or more
   * NUMA nodes. Specify the @nid argument if it is known that this
@@@ -2674,7 -2628,6 +2674,7 @@@ void __init mm_core_init_early(void
  {
  	kho_memory_init_early();
  
 +	sparse_sections_init();
  	free_area_init();
  
  	hugetlb_cma_reserve();

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

^ permalink raw reply	[flat|nested] 3+ messages in thread
* linux-next: manual merge of the liveupdate tree with the mm tree
@ 2026-09-24 18:53 Mark Brown
  0 siblings, 0 replies; 3+ messages in thread
From: Mark Brown @ 2026-09-24 18:53 UTC (permalink / raw)
  To: Mike Rapoport, Andrew Morton, Pasha Tatashin, Pratyush Yadav
  Cc: Linux Kernel Mailing List, Linux Next Mailing List, Meijing Zhao,
	Wandun Chen

[-- Attachment #1: Type: text/plain, Size: 1257 bytes --]

Hi all,

Today's linux-next merge of the liveupdate tree got a conflict in:

  mm/memblock.c

between commit:

  ba13f1f32d96d ("mm: memblock: add missing HugeTLB flag name")

from the mm tree and commit:

  05a84ceadf702 ("memblock: rename KHO_SCRATCH to KHO_NOPRSRV")

from the liveupdate tree.

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 mm/memblock.c
index ea0de4b5f3568,f5aaa38cfa313..0000000000000
--- a/mm/memblock.c
+++ b/mm/memblock.c
@@@ -2878,8 -2885,7 +2878,8 @@@ static const char * const flagname[] = 
  	[ilog2(MEMBLOCK_DRIVER_MANAGED)] = "DRV_MNG",
  	[ilog2(MEMBLOCK_RSRV_NOINIT)] = "RSV_NIT",
  	[ilog2(MEMBLOCK_RSRV_KERN)] = "RSV_KERN",
- 	[ilog2(MEMBLOCK_KHO_SCRATCH)] = "KHO_SCRATCH",
+ 	[ilog2(MEMBLOCK_KHO_NOPRSRV)] = "KHO_NOPRSRV",
 +	[ilog2(MEMBLOCK_RSRV_HUGETLB)] = "RSV_HUGETLB",
  };
  
  static int memblock_debug_show(struct seq_file *m, void *private)

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

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

end of thread, other threads:[~2026-09-24 18:53 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-09-24 17:08 linux-next: manual merge of the liveupdate tree with the mm tree Mark Brown
2026-09-24 17:36 ` Mike Rapoport
2026-09-24 18:53 Mark Brown

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®