mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH v2 0/3] memblock: Remove unused exact nid allocation API
@ 2026-09-19 13:53 Kaitao Cheng
  2026-09-19 13:53 ` [PATCH v2 1/3] mm: Remove unused exact_nid parameter from memmap_alloc() Kaitao Cheng
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: Kaitao Cheng @ 2026-09-19 13:53 UTC (permalink / raw)
  To: Mike Rapoport, Andrew Morton, David Hildenbrand, Lorenzo Stoakes,
	Liam R . Howlett, Vlastimil Babka, Suren Baghdasaryan,
	Michal Hocko, Muchun Song
  Cc: Priyanshu Kumar, linux-mm, linux-kernel, Kaitao Cheng

Commit ffe55393137c ("mm/sparse: remove sparse buffer pre-allocation
mechanism") removed the only memmap_alloc() caller that requested an
allocation from an exact NUMA node. All remaining callers allow fallback
to other nodes, leaving the exact_nid argument unused.

Remove the argument from memmap_alloc(). This leaves
memblock_alloc_exact_nid_raw() without any in-kernel callers, so move the
applicable exact-node allocation tests to memblock_alloc_range_nid() and
remove the unused API. Also remove the exact_nid argument from the internal
allocation helper, since all of its remaining callers allow fallback.

Exact-node allocation remains a required behavior of
memblock_alloc_range_nid(). CMA uses it when reserving per-node CMA areas;
allowing fallback could leave the area's recorded nid inconsistent with
the physical location of its memory. KHO also uses it for per-node scratch
areas that must remain on the requested node. Therefore, retain coverage
of this behavior by making the applicable NUMA tests call
memblock_alloc_range_nid() directly with exact_nid set.

The tests that exercise memblock_alloc_internal() retrying below min_addr
cannot be retained unchanged. Unlike memblock_alloc_internal(),
memblock_alloc_range_nid() treats its start address as a hard boundary and
does not retry from address zero. Remove those tests along with the now
unused TEST_F_EXACT dispatch from the shared allocation tests.

Kaitao Cheng (3):
  mm: Remove unused exact_nid parameter from memmap_alloc()
  memblock tests: Move exact nid tests to memblock_alloc_range_nid()
  memblock: Remove unused memblock_alloc_exact_nid_raw()

 include/linux/memblock.h                      |   3 -
 mm/memblock.c                                 |  44 +-
 mm/mm_init.c                                  |  14 +-
 mm/mm_init.h                                  |   4 +-
 mm/sparse-vmemmap.c                           |   2 +-
 mm/sparse.c                                   |   2 +-
 .../memblock/tests/alloc_exact_nid_api.c      | 454 ++----------------
 tools/testing/memblock/tests/alloc_nid_api.c  |  20 -
 tools/testing/memblock/tests/alloc_nid_api.h  |   1 -
 tools/testing/memblock/tests/common.h         |   2 -
 10 files changed, 50 insertions(+), 496 deletions(-)

-- 
2.54.0 (Apple Git-157)


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

* [PATCH v2 1/3] mm: Remove unused exact_nid parameter from memmap_alloc()
  2026-09-19 13:53 [PATCH v2 0/3] memblock: Remove unused exact nid allocation API Kaitao Cheng
@ 2026-09-19 13:53 ` Kaitao Cheng
  2026-09-19 13:53 ` [PATCH v2 2/3] memblock tests: Move exact nid tests to memblock_alloc_range_nid() Kaitao Cheng
  2026-09-19 13:53 ` [PATCH v2 3/3] memblock: Remove unused memblock_alloc_exact_nid_raw() Kaitao Cheng
  2 siblings, 0 replies; 4+ messages in thread
From: Kaitao Cheng @ 2026-09-19 13:53 UTC (permalink / raw)
  To: Mike Rapoport, Andrew Morton, David Hildenbrand, Lorenzo Stoakes,
	Liam R . Howlett, Vlastimil Babka, Suren Baghdasaryan,
	Michal Hocko, Muchun Song
  Cc: Priyanshu Kumar, linux-mm, linux-kernel, Kaitao Cheng

From: Kaitao Cheng <chengkaitao@kylinos.cn>

Commit ffe55393137c ("mm/sparse: remove sparse buffer pre-allocation
mechanism") removed sparse_buffer_init(), which was the only caller of
memmap_alloc() that passed true for exact_nid.

All remaining callers pass false, leaving the exact-node allocation
branch unreachable. Remove the exact_nid parameter and unconditionally
use memblock_alloc_try_nid_raw().

This has no functional impact.

Signed-off-by: Kaitao Cheng <chengkaitao@kylinos.cn>
---
 mm/mm_init.c        | 14 ++++----------
 mm/mm_init.h        |  4 ++--
 mm/sparse-vmemmap.c |  2 +-
 mm/sparse.c         |  2 +-
 4 files changed, 8 insertions(+), 14 deletions(-)

diff --git a/mm/mm_init.c b/mm/mm_init.c
index 9ce6060de06d..af3c8a2cc91b 100644
--- a/mm/mm_init.c
+++ b/mm/mm_init.c
@@ -1596,7 +1596,7 @@ static void __init free_area_init_core(struct pglist_data *pgdat)
 }
 
 void __init *memmap_alloc(phys_addr_t size, phys_addr_t align,
-			  phys_addr_t min_addr, int nid, bool exact_nid)
+			  phys_addr_t min_addr, int nid)
 {
 	void *ptr;
 
@@ -1604,14 +1604,8 @@ void __init *memmap_alloc(phys_addr_t size, phys_addr_t align,
 	 * Kmemleak will explicitly scan mem_map by traversing all valid
 	 * `struct *page`,so memblock does not need to be added to the scan list.
 	 */
-	if (exact_nid)
-		ptr = memblock_alloc_exact_nid_raw(size, align, min_addr,
-						   MEMBLOCK_ALLOC_NOLEAKTRACE,
-						   nid);
-	else
-		ptr = memblock_alloc_try_nid_raw(size, align, min_addr,
-						 MEMBLOCK_ALLOC_NOLEAKTRACE,
-						 nid);
+	ptr = memblock_alloc_try_nid_raw(size, align, min_addr,
+					 MEMBLOCK_ALLOC_NOLEAKTRACE, nid);
 
 	if (ptr && size > 0)
 		page_init_poison(ptr, size);
@@ -1639,7 +1633,7 @@ static void __init alloc_node_mem_map(struct pglist_data *pgdat)
 	end = ALIGN(pgdat_end_pfn(pgdat), MAX_ORDER_NR_PAGES);
 	size =  (end - start) * sizeof(struct page);
 	map = memmap_alloc(size, SMP_CACHE_BYTES, MEMBLOCK_LOW_LIMIT,
-			   pgdat->node_id, false);
+			   pgdat->node_id);
 	if (!map)
 		panic("Failed to allocate %ld bytes for node %d memory map\n",
 		      size, pgdat->node_id);
diff --git a/mm/mm_init.h b/mm/mm_init.h
index c9fc35e7e9f1..a8ed5c20851b 100644
--- a/mm/mm_init.h
+++ b/mm/mm_init.h
@@ -31,8 +31,8 @@ static inline void clear_zone_contiguous(struct zone *zone)
 
 void memblock_free_pages(unsigned long pfn, unsigned int order);
 
-void *memmap_alloc(phys_addr_t size, phys_addr_t align, phys_addr_t min_addr,
-		int nid, bool exact_nid);
+void *memmap_alloc(phys_addr_t size, phys_addr_t align,
+		   phys_addr_t min_addr, int nid);
 
 void memmap_init_range(unsigned long size, int nid, unsigned long zone,
 		unsigned long start_pfn, unsigned long zone_end_pfn,
diff --git a/mm/sparse-vmemmap.c b/mm/sparse-vmemmap.c
index 96506f594924..dbd1ebe93fe9 100644
--- a/mm/sparse-vmemmap.c
+++ b/mm/sparse-vmemmap.c
@@ -62,7 +62,7 @@ void __ref *vmemmap_alloc_block(unsigned long size, int node)
 		}
 		return NULL;
 	} else
-		return memmap_alloc(size, size, __pa(MAX_DMA_ADDRESS), node, false);
+		return memmap_alloc(size, size, __pa(MAX_DMA_ADDRESS), node);
 }
 
 static void * __meminit altmap_alloc_block_buf(unsigned long size,
diff --git a/mm/sparse.c b/mm/sparse.c
index b75921c622ed..36692b1dd733 100644
--- a/mm/sparse.c
+++ b/mm/sparse.c
@@ -215,7 +215,7 @@ struct page __init *__populate_section_memmap(unsigned long pfn,
 {
 	const unsigned long size = PAGE_ALIGN(sizeof(struct page) * PAGES_PER_SECTION);
 
-	return memmap_alloc(size, size, __pa(MAX_DMA_ADDRESS), nid, false);
+	return memmap_alloc(size, size, __pa(MAX_DMA_ADDRESS), nid);
 }
 #endif /* !CONFIG_SPARSEMEM_VMEMMAP */
 
-- 
2.54.0 (Apple Git-157)


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

* [PATCH v2 2/3] memblock tests: Move exact nid tests to memblock_alloc_range_nid()
  2026-09-19 13:53 [PATCH v2 0/3] memblock: Remove unused exact nid allocation API Kaitao Cheng
  2026-09-19 13:53 ` [PATCH v2 1/3] mm: Remove unused exact_nid parameter from memmap_alloc() Kaitao Cheng
@ 2026-09-19 13:53 ` Kaitao Cheng
  2026-09-19 13:53 ` [PATCH v2 3/3] memblock: Remove unused memblock_alloc_exact_nid_raw() Kaitao Cheng
  2 siblings, 0 replies; 4+ messages in thread
From: Kaitao Cheng @ 2026-09-19 13:53 UTC (permalink / raw)
  To: Mike Rapoport, Andrew Morton, David Hildenbrand, Lorenzo Stoakes,
	Liam R . Howlett, Vlastimil Babka, Suren Baghdasaryan,
	Michal Hocko, Muchun Song
  Cc: Priyanshu Kumar, linux-mm, linux-kernel, Kaitao Cheng

From: Kaitao Cheng <chengkaitao@kylinos.cn>

After memmap_alloc() stopped requesting allocations from an exact NUMA
node, memblock_alloc_exact_nid_raw() no longer has any in-kernel users
and is being removed.

Preserve coverage of exact-node allocation by converting the applicable
NUMA tests to call memblock_alloc_range_nid() with exact_nid set. Remove
the tests that depend on memblock_alloc_internal() retrying below
min_addr, as memblock_alloc_range_nid() treats its address range as a
hard constraint.

Remove the now-unused TEST_F_EXACT support from the shared allocation
tests.

Suggested-by: Lorenzo Stoakes <ljs@kernel.org>
Signed-off-by: Kaitao Cheng <chengkaitao@kylinos.cn>
---
 .../memblock/tests/alloc_exact_nid_api.c      | 454 ++----------------
 tools/testing/memblock/tests/alloc_nid_api.c  |  20 -
 tools/testing/memblock/tests/alloc_nid_api.h  |   1 -
 tools/testing/memblock/tests/common.h         |   2 -
 4 files changed, 37 insertions(+), 440 deletions(-)

diff --git a/tools/testing/memblock/tests/alloc_exact_nid_api.c b/tools/testing/memblock/tests/alloc_exact_nid_api.c
index 0c46c73b5e04..52c63d011870 100644
--- a/tools/testing/memblock/tests/alloc_exact_nid_api.c
+++ b/tools/testing/memblock/tests/alloc_exact_nid_api.c
@@ -1,8 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0-or-later
 #include "alloc_exact_nid_api.h"
-#include "alloc_nid_api.h"
 
-#define FUNC_NAME			"memblock_alloc_exact_nid_raw"
+#define FUNC_NAME			"memblock_alloc_range_nid(exact)"
 
 /*
  * contains the fraction of MEM_SIZE contained in each node in basis point
@@ -19,6 +18,18 @@ static const unsigned int node_fractions[] = {
 	 625, /* 1/16 */
 };
 
+static void *alloc_range_exact_nid(phys_addr_t size, phys_addr_t align,
+				   phys_addr_t min_addr,
+				   phys_addr_t max_addr, int nid)
+{
+	phys_addr_t addr;
+
+	addr = memblock_alloc_range_nid(size, align, min_addr, max_addr, nid,
+					true);
+
+	return addr ? phys_to_virt(addr) : NULL;
+}
+
 /*
  * A test that tries to allocate a memory region in a specific NUMA node that
  * has enough memory to allocate a region of the requested size.
@@ -42,9 +53,8 @@ static int alloc_exact_nid_top_down_numa_simple_check(void)
 	min_addr = memblock_start_of_DRAM();
 	max_addr = memblock_end_of_DRAM();
 
-	allocated_ptr = memblock_alloc_exact_nid_raw(size, SMP_CACHE_BYTES,
-						     min_addr, max_addr,
-						     nid_req);
+	allocated_ptr = alloc_range_exact_nid(size, SMP_CACHE_BYTES,
+					      min_addr, max_addr, nid_req);
 
 	ASSERT_NE(allocated_ptr, NULL);
 	ASSERT_MEM_NE(allocated_ptr, 0, size);
@@ -98,9 +108,8 @@ static int alloc_exact_nid_top_down_numa_part_reserved_check(void)
 	max_addr = memblock_end_of_DRAM();
 
 	memblock_reserve(r1.base, r1.size);
-	allocated_ptr = memblock_alloc_exact_nid_raw(size, SMP_CACHE_BYTES,
-						     min_addr, max_addr,
-						     nid_req);
+	allocated_ptr = alloc_range_exact_nid(size, SMP_CACHE_BYTES,
+					      min_addr, max_addr, nid_req);
 
 	ASSERT_NE(allocated_ptr, NULL);
 	ASSERT_MEM_NE(allocated_ptr, 0, size);
@@ -117,177 +126,6 @@ static int alloc_exact_nid_top_down_numa_part_reserved_check(void)
 	return 0;
 }
 
-/*
- * A test that tries to allocate a memory region that spans over the min_addr
- * and max_addr range and overlaps with two different nodes, where the first
- * node is the requested node:
- *
- *                                min_addr
- *                                |           max_addr
- *                                |           |
- *                                v           v
- *  |           +-----------------------+-----------+              |
- *  |           |       requested       |   node3   |              |
- *  +-----------+-----------------------+-----------+--------------+
- *                                +           +
- *  |                       +-----------+                          |
- *  |                       |    rgn    |                          |
- *  +-----------------------+-----------+--------------------------+
- *
- * Expect to drop the lower limit and allocate a memory region that ends at
- * the end of the requested node.
- */
-static int alloc_exact_nid_top_down_numa_split_range_low_check(void)
-{
-	int nid_req = 2;
-	struct memblock_region *new_rgn = &memblock.reserved.regions[0];
-	struct memblock_region *req_node = &memblock.memory.regions[nid_req];
-	void *allocated_ptr = NULL;
-	phys_addr_t size = SZ_512;
-	phys_addr_t min_addr;
-	phys_addr_t max_addr;
-	phys_addr_t req_node_end;
-
-	PREFIX_PUSH();
-	setup_numa_memblock(node_fractions);
-
-	req_node_end = region_end(req_node);
-	min_addr = req_node_end - SZ_256;
-	max_addr = min_addr + size;
-
-	allocated_ptr = memblock_alloc_exact_nid_raw(size, SMP_CACHE_BYTES,
-						     min_addr, max_addr,
-						     nid_req);
-
-	ASSERT_NE(allocated_ptr, NULL);
-	ASSERT_MEM_NE(allocated_ptr, 0, size);
-
-	ASSERT_EQ(new_rgn->size, size);
-	ASSERT_EQ(new_rgn->base, req_node_end - size);
-	ASSERT_LE(req_node->base, new_rgn->base);
-
-	ASSERT_EQ(memblock.reserved.cnt, 1);
-	ASSERT_EQ(memblock.reserved.total_size, size);
-
-	test_pass_pop();
-
-	return 0;
-}
-
-/*
- * A test that tries to allocate a memory region that spans over the min_addr
- * and max_addr range and overlaps with two different nodes, where the requested
- * node ends before min_addr:
- *
- *                                         min_addr
- *                                         |         max_addr
- *                                         |         |
- *                                         v         v
- *  |    +---------------+        +-------------+---------+          |
- *  |    |   requested   |        |    node1    |  node2  |          |
- *  +----+---------------+--------+-------------+---------+----------+
- *                                         +         +
- *  |          +---------+                                           |
- *  |          |   rgn   |                                           |
- *  +----------+---------+-------------------------------------------+
- *
- * Expect to drop the lower limit and allocate a memory region that ends at
- * the end of the requested node.
- */
-static int alloc_exact_nid_top_down_numa_no_overlap_split_check(void)
-{
-	int nid_req = 2;
-	struct memblock_region *new_rgn = &memblock.reserved.regions[0];
-	struct memblock_region *req_node = &memblock.memory.regions[nid_req];
-	struct memblock_region *node2 = &memblock.memory.regions[6];
-	void *allocated_ptr = NULL;
-	phys_addr_t size;
-	phys_addr_t min_addr;
-	phys_addr_t max_addr;
-
-	PREFIX_PUSH();
-	setup_numa_memblock(node_fractions);
-
-	size = SZ_512;
-	min_addr = node2->base - SZ_256;
-	max_addr = min_addr + size;
-
-	allocated_ptr = memblock_alloc_exact_nid_raw(size, SMP_CACHE_BYTES,
-						     min_addr, max_addr,
-						     nid_req);
-
-	ASSERT_NE(allocated_ptr, NULL);
-	ASSERT_MEM_NE(allocated_ptr, 0, size);
-
-	ASSERT_EQ(new_rgn->size, size);
-	ASSERT_EQ(new_rgn->base, region_end(req_node) - size);
-	ASSERT_LE(req_node->base, new_rgn->base);
-
-	ASSERT_EQ(memblock.reserved.cnt, 1);
-	ASSERT_EQ(memblock.reserved.total_size, size);
-
-	test_pass_pop();
-
-	return 0;
-}
-
-/*
- * A test that tries to allocate memory within min_addr and max_add range when
- * the requested node and the range do not overlap, and requested node ends
- * before min_addr. The range overlaps with multiple nodes along node
- * boundaries:
- *
- *                          min_addr
- *                          |                                 max_addr
- *                          |                                 |
- *                          v                                 v
- *  |-----------+           +----------+----...----+----------+      |
- *  | requested |           | min node |    ...    | max node |      |
- *  +-----------+-----------+----------+----...----+----------+------+
- *                          +                                 +
- *  |     +-----+                                                    |
- *  |     | rgn |                                                    |
- *  +-----+-----+----------------------------------------------------+
- *
- * Expect to drop the lower limit and allocate a memory region that ends at
- * the end of the requested node.
- */
-static int alloc_exact_nid_top_down_numa_no_overlap_low_check(void)
-{
-	int nid_req = 0;
-	struct memblock_region *new_rgn = &memblock.reserved.regions[0];
-	struct memblock_region *req_node = &memblock.memory.regions[nid_req];
-	struct memblock_region *min_node = &memblock.memory.regions[2];
-	struct memblock_region *max_node = &memblock.memory.regions[5];
-	void *allocated_ptr = NULL;
-	phys_addr_t size = SZ_64;
-	phys_addr_t max_addr;
-	phys_addr_t min_addr;
-
-	PREFIX_PUSH();
-	setup_numa_memblock(node_fractions);
-
-	min_addr = min_node->base;
-	max_addr = region_end(max_node);
-
-	allocated_ptr = memblock_alloc_exact_nid_raw(size, SMP_CACHE_BYTES,
-						     min_addr, max_addr,
-						     nid_req);
-
-	ASSERT_NE(allocated_ptr, NULL);
-	ASSERT_MEM_NE(allocated_ptr, 0, size);
-
-	ASSERT_EQ(new_rgn->size, size);
-	ASSERT_EQ(new_rgn->base, region_end(req_node) - size);
-
-	ASSERT_EQ(memblock.reserved.cnt, 1);
-	ASSERT_EQ(memblock.reserved.total_size, size);
-
-	test_pass_pop();
-
-	return 0;
-}
-
 /*
  * A test that tries to allocate a memory region in a specific NUMA node that
  * has enough memory to allocate a region of the requested size.
@@ -311,9 +149,8 @@ static int alloc_exact_nid_bottom_up_numa_simple_check(void)
 	min_addr = memblock_start_of_DRAM();
 	max_addr = memblock_end_of_DRAM();
 
-	allocated_ptr = memblock_alloc_exact_nid_raw(size, SMP_CACHE_BYTES,
-						     min_addr, max_addr,
-						     nid_req);
+	allocated_ptr = alloc_range_exact_nid(size, SMP_CACHE_BYTES,
+					      min_addr, max_addr, nid_req);
 
 	ASSERT_NE(allocated_ptr, NULL);
 	ASSERT_MEM_NE(allocated_ptr, 0, size);
@@ -369,9 +206,8 @@ static int alloc_exact_nid_bottom_up_numa_part_reserved_check(void)
 	total_size = size + r1.size;
 
 	__memblock_reserve(r1.base, r1.size, nid_req, MEMBLOCK_RSRV_KERN);
-	allocated_ptr = memblock_alloc_exact_nid_raw(size, SMP_CACHE_BYTES,
-						     min_addr, max_addr,
-						     nid_req);
+	allocated_ptr = alloc_range_exact_nid(size, SMP_CACHE_BYTES,
+					      min_addr, max_addr, nid_req);
 
 	ASSERT_NE(allocated_ptr, NULL);
 	ASSERT_MEM_NE(allocated_ptr, 0, size);
@@ -388,178 +224,6 @@ static int alloc_exact_nid_bottom_up_numa_part_reserved_check(void)
 	return 0;
 }
 
-/*
- * A test that tries to allocate a memory region that spans over the min_addr
- * and max_addr range and overlaps with two different nodes, where the first
- * node is the requested node:
- *
- *                                min_addr
- *                                |           max_addr
- *                                |           |
- *                                v           v
- *  |           +-----------------------+-----------+              |
- *  |           |       requested       |   node3   |              |
- *  +-----------+-----------------------+-----------+--------------+
- *                                +           +
- *  |           +-----------+                                      |
- *  |           |    rgn    |                                      |
- *  +-----------+-----------+--------------------------------------+
- *
- * Expect to drop the lower limit and allocate a memory region at the beginning
- * of the requested node.
- */
-static int alloc_exact_nid_bottom_up_numa_split_range_low_check(void)
-{
-	int nid_req = 2;
-	struct memblock_region *new_rgn = &memblock.reserved.regions[0];
-	struct memblock_region *req_node = &memblock.memory.regions[nid_req];
-	void *allocated_ptr = NULL;
-	phys_addr_t size = SZ_512;
-	phys_addr_t min_addr;
-	phys_addr_t max_addr;
-	phys_addr_t req_node_end;
-
-	PREFIX_PUSH();
-	setup_numa_memblock(node_fractions);
-
-	req_node_end = region_end(req_node);
-	min_addr = req_node_end - SZ_256;
-	max_addr = min_addr + size;
-
-	allocated_ptr = memblock_alloc_exact_nid_raw(size, SMP_CACHE_BYTES,
-						     min_addr, max_addr,
-						     nid_req);
-
-	ASSERT_NE(allocated_ptr, NULL);
-	ASSERT_MEM_NE(allocated_ptr, 0, size);
-
-	ASSERT_EQ(new_rgn->size, size);
-	ASSERT_EQ(new_rgn->base, req_node->base);
-	ASSERT_LE(region_end(new_rgn), req_node_end);
-
-	ASSERT_EQ(memblock.reserved.cnt, 1);
-	ASSERT_EQ(memblock.reserved.total_size, size);
-
-	test_pass_pop();
-
-	return 0;
-}
-
-/*
- * A test that tries to allocate a memory region that spans over the min_addr
- * and max_addr range and overlaps with two different nodes, where the requested
- * node ends before min_addr:
- *
- *                                          min_addr
- *                                         |         max_addr
- *                                         |         |
- *                                         v         v
- *  |    +---------------+        +-------------+---------+         |
- *  |    |   requested   |        |    node1    |  node2  |         |
- *  +----+---------------+--------+-------------+---------+---------+
- *                                         +         +
- *  |    +---------+                                                |
- *  |    |   rgn   |                                                |
- *  +----+---------+------------------------------------------------+
- *
- * Expect to drop the lower limit and allocate a memory region that starts at
- * the beginning of the requested node.
- */
-static int alloc_exact_nid_bottom_up_numa_no_overlap_split_check(void)
-{
-	int nid_req = 2;
-	struct memblock_region *new_rgn = &memblock.reserved.regions[0];
-	struct memblock_region *req_node = &memblock.memory.regions[nid_req];
-	struct memblock_region *node2 = &memblock.memory.regions[6];
-	void *allocated_ptr = NULL;
-	phys_addr_t size;
-	phys_addr_t min_addr;
-	phys_addr_t max_addr;
-
-	PREFIX_PUSH();
-	setup_numa_memblock(node_fractions);
-
-	size = SZ_512;
-	min_addr = node2->base - SZ_256;
-	max_addr = min_addr + size;
-
-	allocated_ptr = memblock_alloc_exact_nid_raw(size, SMP_CACHE_BYTES,
-						     min_addr, max_addr,
-						     nid_req);
-
-	ASSERT_NE(allocated_ptr, NULL);
-	ASSERT_MEM_NE(allocated_ptr, 0, size);
-
-	ASSERT_EQ(new_rgn->size, size);
-	ASSERT_EQ(new_rgn->base, req_node->base);
-	ASSERT_LE(region_end(new_rgn), region_end(req_node));
-
-	ASSERT_EQ(memblock.reserved.cnt, 1);
-	ASSERT_EQ(memblock.reserved.total_size, size);
-
-	test_pass_pop();
-
-	return 0;
-}
-
-/*
- * A test that tries to allocate memory within min_addr and max_add range when
- * the requested node and the range do not overlap, and requested node ends
- * before min_addr. The range overlaps with multiple nodes along node
- * boundaries:
- *
- *                          min_addr
- *                          |                                 max_addr
- *                          |                                 |
- *                          v                                 v
- *  |-----------+           +----------+----...----+----------+      |
- *  | requested |           | min node |    ...    | max node |      |
- *  +-----------+-----------+----------+----...----+----------+------+
- *                          +                                 +
- *  |-----+                                                          |
- *  | rgn |                                                          |
- *  +-----+----------------------------------------------------------+
- *
- * Expect to drop the lower limit and allocate a memory region that starts at
- * the beginning of the requested node.
- */
-static int alloc_exact_nid_bottom_up_numa_no_overlap_low_check(void)
-{
-	int nid_req = 0;
-	struct memblock_region *new_rgn = &memblock.reserved.regions[0];
-	struct memblock_region *req_node = &memblock.memory.regions[nid_req];
-	struct memblock_region *min_node = &memblock.memory.regions[2];
-	struct memblock_region *max_node = &memblock.memory.regions[5];
-	void *allocated_ptr = NULL;
-	phys_addr_t size = SZ_64;
-	phys_addr_t max_addr;
-	phys_addr_t min_addr;
-
-	PREFIX_PUSH();
-	setup_numa_memblock(node_fractions);
-
-	min_addr = min_node->base;
-	max_addr = region_end(max_node);
-
-	allocated_ptr = memblock_alloc_exact_nid_raw(size, SMP_CACHE_BYTES,
-						     min_addr, max_addr,
-						     nid_req);
-
-	ASSERT_NE(allocated_ptr, NULL);
-	ASSERT_MEM_NE(allocated_ptr, 0, size);
-
-	ASSERT_EQ(new_rgn->size, size);
-	ASSERT_EQ(new_rgn->base, req_node->base);
-	ASSERT_LE(region_end(new_rgn), region_end(req_node));
-
-	ASSERT_EQ(memblock.reserved.cnt, 1);
-	ASSERT_EQ(memblock.reserved.total_size, size);
-
-	test_pass_pop();
-
-	return 0;
-}
-
 /*
  * A test that tries to allocate a memory region in a specific NUMA node that
  * does not have enough memory to allocate a region of the requested size:
@@ -590,9 +254,8 @@ static int alloc_exact_nid_numa_small_node_generic_check(void)
 	min_addr = memblock_start_of_DRAM();
 	max_addr = memblock_end_of_DRAM();
 
-	allocated_ptr = memblock_alloc_exact_nid_raw(size, SMP_CACHE_BYTES,
-						     min_addr, max_addr,
-						     nid_req);
+	allocated_ptr = alloc_range_exact_nid(size, SMP_CACHE_BYTES,
+					      min_addr, max_addr, nid_req);
 
 	ASSERT_EQ(allocated_ptr, NULL);
 
@@ -632,9 +295,8 @@ static int alloc_exact_nid_numa_node_reserved_generic_check(void)
 	max_addr = memblock_end_of_DRAM();
 
 	memblock_reserve(req_node->base, req_node->size);
-	allocated_ptr = memblock_alloc_exact_nid_raw(size, SMP_CACHE_BYTES,
-						     min_addr, max_addr,
-						     nid_req);
+	allocated_ptr = alloc_range_exact_nid(size, SMP_CACHE_BYTES,
+					      min_addr, max_addr, nid_req);
 
 	ASSERT_EQ(allocated_ptr, NULL);
 
@@ -680,9 +342,8 @@ static int alloc_exact_nid_numa_part_reserved_fail_generic_check(void)
 	max_addr = memblock_end_of_DRAM();
 
 	memblock_reserve(r1.base, r1.size);
-	allocated_ptr = memblock_alloc_exact_nid_raw(size, SMP_CACHE_BYTES,
-						     min_addr, max_addr,
-						     nid_req);
+	allocated_ptr = alloc_range_exact_nid(size, SMP_CACHE_BYTES,
+					      min_addr, max_addr, nid_req);
 
 	ASSERT_EQ(allocated_ptr, NULL);
 
@@ -721,9 +382,8 @@ static int alloc_exact_nid_numa_split_range_high_generic_check(void)
 	min_addr = req_node->base - SZ_256;
 	max_addr = min_addr + size;
 
-	allocated_ptr = memblock_alloc_exact_nid_raw(size, SMP_CACHE_BYTES,
-						     min_addr, max_addr,
-						     nid_req);
+	allocated_ptr = alloc_range_exact_nid(size, SMP_CACHE_BYTES,
+					      min_addr, max_addr, nid_req);
 
 	ASSERT_EQ(allocated_ptr, NULL);
 
@@ -764,9 +424,8 @@ static int alloc_exact_nid_numa_no_overlap_high_generic_check(void)
 	min_addr = min_node->base;
 	max_addr = region_end(max_node);
 
-	allocated_ptr = memblock_alloc_exact_nid_raw(size, SMP_CACHE_BYTES,
-						     min_addr, max_addr,
-						     nid_req);
+	allocated_ptr = alloc_range_exact_nid(size, SMP_CACHE_BYTES,
+					      min_addr, max_addr, nid_req);
 
 	ASSERT_EQ(allocated_ptr, NULL);
 
@@ -803,9 +462,8 @@ static int alloc_exact_nid_numa_large_region_generic_check(void)
 	min_addr = memblock_start_of_DRAM();
 	max_addr = memblock_end_of_DRAM();
 
-	allocated_ptr = memblock_alloc_exact_nid_raw(size, SMP_CACHE_BYTES,
-						     min_addr, max_addr,
-						     nid_req);
+	allocated_ptr = alloc_range_exact_nid(size, SMP_CACHE_BYTES,
+					      min_addr, max_addr, nid_req);
 	ASSERT_EQ(allocated_ptr, NULL);
 
 	test_pass_pop();
@@ -864,9 +522,8 @@ static int alloc_exact_nid_numa_reserved_full_merge_generic_check(void)
 	__memblock_reserve(r1.base, r1.size, nid_req, MEMBLOCK_RSRV_KERN);
 	__memblock_reserve(r2.base, r2.size, nid_req, MEMBLOCK_RSRV_KERN);
 
-	allocated_ptr = memblock_alloc_exact_nid_raw(size, SMP_CACHE_BYTES,
-						     min_addr, max_addr,
-						     nid_req);
+	allocated_ptr = alloc_range_exact_nid(size, SMP_CACHE_BYTES,
+					      min_addr, max_addr, nid_req);
 
 	ASSERT_NE(allocated_ptr, NULL);
 	ASSERT_MEM_NE(allocated_ptr, 0, size);
@@ -933,9 +590,8 @@ static int alloc_exact_nid_numa_split_all_reserved_generic_check(void)
 	memblock_reserve(r1.base, r1.size);
 	memblock_reserve(r2.base, r2.size);
 
-	allocated_ptr = memblock_alloc_exact_nid_raw(size, SMP_CACHE_BYTES,
-						     min_addr, max_addr,
-						     NUMA_NO_NODE);
+	allocated_ptr = alloc_range_exact_nid(size, SMP_CACHE_BYTES,
+					      min_addr, max_addr, NUMA_NO_NODE);
 
 	ASSERT_EQ(allocated_ptr, NULL);
 
@@ -967,38 +623,6 @@ static int alloc_exact_nid_numa_part_reserved_check(void)
 	return 0;
 }
 
-static int alloc_exact_nid_numa_split_range_low_check(void)
-{
-	test_print("\tRunning %s...\n", __func__);
-	memblock_set_bottom_up(false);
-	alloc_exact_nid_top_down_numa_split_range_low_check();
-	memblock_set_bottom_up(true);
-	alloc_exact_nid_bottom_up_numa_split_range_low_check();
-
-	return 0;
-}
-
-static int alloc_exact_nid_numa_no_overlap_split_check(void)
-{
-	test_print("\tRunning %s...\n", __func__);
-	memblock_set_bottom_up(false);
-	alloc_exact_nid_top_down_numa_no_overlap_split_check();
-	memblock_set_bottom_up(true);
-	alloc_exact_nid_bottom_up_numa_no_overlap_split_check();
-
-	return 0;
-}
-
-static int alloc_exact_nid_numa_no_overlap_low_check(void)
-{
-	test_print("\tRunning %s...\n", __func__);
-	memblock_set_bottom_up(false);
-	alloc_exact_nid_top_down_numa_no_overlap_low_check();
-	memblock_set_bottom_up(true);
-	alloc_exact_nid_bottom_up_numa_no_overlap_low_check();
-
-	return 0;
-}
 
 static int alloc_exact_nid_numa_small_node_check(void)
 {
@@ -1078,9 +702,6 @@ int __memblock_alloc_exact_nid_numa_checks(void)
 
 	alloc_exact_nid_numa_simple_check();
 	alloc_exact_nid_numa_part_reserved_check();
-	alloc_exact_nid_numa_split_range_low_check();
-	alloc_exact_nid_numa_no_overlap_split_check();
-	alloc_exact_nid_numa_no_overlap_low_check();
 
 	alloc_exact_nid_numa_small_node_check();
 	alloc_exact_nid_numa_node_reserved_check();
@@ -1102,7 +723,6 @@ int memblock_alloc_exact_nid_checks(void)
 	reset_memblock_attributes();
 	dummy_physical_memory_init();
 
-	memblock_alloc_exact_nid_range_checks();
 	memblock_alloc_exact_nid_numa_checks();
 
 	dummy_physical_memory_cleanup();
diff --git a/tools/testing/memblock/tests/alloc_nid_api.c b/tools/testing/memblock/tests/alloc_nid_api.c
index c04923532159..3dd4c0bebc41 100644
--- a/tools/testing/memblock/tests/alloc_nid_api.c
+++ b/tools/testing/memblock/tests/alloc_nid_api.c
@@ -20,8 +20,6 @@ static const unsigned int node_fractions[] = {
 
 static inline const char * const get_memblock_alloc_nid_name(int flags)
 {
-	if (flags & TEST_F_EXACT)
-		return "memblock_alloc_exact_nid_raw";
 	if (flags & TEST_F_RAW)
 		return "memblock_alloc_try_nid_raw";
 	return "memblock_alloc_try_nid";
@@ -32,15 +30,6 @@ static inline void *run_memblock_alloc_nid(phys_addr_t size,
 					   phys_addr_t min_addr,
 					   phys_addr_t max_addr, int nid)
 {
-	assert(!(alloc_nid_test_flags & TEST_F_EXACT) ||
-	       (alloc_nid_test_flags & TEST_F_RAW));
-	/*
-	 * TEST_F_EXACT should be checked before TEST_F_RAW since
-	 * memblock_alloc_exact_nid_raw() performs raw allocations.
-	 */
-	if (alloc_nid_test_flags & TEST_F_EXACT)
-		return memblock_alloc_exact_nid_raw(size, align, min_addr,
-						    max_addr, nid);
 	if (alloc_nid_test_flags & TEST_F_RAW)
 		return memblock_alloc_try_nid_raw(size, align, min_addr,
 						  max_addr, nid);
@@ -2722,12 +2711,3 @@ int memblock_alloc_nid_checks(void)
 
 	return 0;
 }
-
-int memblock_alloc_exact_nid_range_checks(void)
-{
-	alloc_nid_test_flags = (TEST_F_RAW | TEST_F_EXACT);
-
-	memblock_alloc_nid_range_checks();
-
-	return 0;
-}
diff --git a/tools/testing/memblock/tests/alloc_nid_api.h b/tools/testing/memblock/tests/alloc_nid_api.h
index 2b8cabacacb8..92d07d230e18 100644
--- a/tools/testing/memblock/tests/alloc_nid_api.h
+++ b/tools/testing/memblock/tests/alloc_nid_api.h
@@ -5,7 +5,6 @@
 #include "common.h"
 
 int memblock_alloc_nid_checks(void);
-int memblock_alloc_exact_nid_range_checks(void);
 int __memblock_alloc_nid_numa_checks(void);
 
 #ifdef CONFIG_NUMA
diff --git a/tools/testing/memblock/tests/common.h b/tools/testing/memblock/tests/common.h
index e1138e06c903..c3cca972dcca 100644
--- a/tools/testing/memblock/tests/common.h
+++ b/tools/testing/memblock/tests/common.h
@@ -23,8 +23,6 @@ enum test_flags {
 	TEST_F_NONE = 0x0,
 	/* Perform raw allocations (no zeroing of memory). */
 	TEST_F_RAW = 0x1,
-	/* Perform allocations on the exact node specified. */
-	TEST_F_EXACT = 0x2
 };
 
 /**
-- 
2.54.0 (Apple Git-157)


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

* [PATCH v2 3/3] memblock: Remove unused memblock_alloc_exact_nid_raw()
  2026-09-19 13:53 [PATCH v2 0/3] memblock: Remove unused exact nid allocation API Kaitao Cheng
  2026-09-19 13:53 ` [PATCH v2 1/3] mm: Remove unused exact_nid parameter from memmap_alloc() Kaitao Cheng
  2026-09-19 13:53 ` [PATCH v2 2/3] memblock tests: Move exact nid tests to memblock_alloc_range_nid() Kaitao Cheng
@ 2026-09-19 13:53 ` Kaitao Cheng
  2 siblings, 0 replies; 4+ messages in thread
From: Kaitao Cheng @ 2026-09-19 13:53 UTC (permalink / raw)
  To: Mike Rapoport, Andrew Morton, David Hildenbrand, Lorenzo Stoakes,
	Liam R . Howlett, Vlastimil Babka, Suren Baghdasaryan,
	Michal Hocko, Muchun Song
  Cc: Priyanshu Kumar, linux-mm, linux-kernel, Kaitao Cheng

From: Kaitao Cheng <chengkaitao@kylinos.cn>

memmap_alloc() was the only in-kernel caller of
memblock_alloc_exact_nid_raw(). After removing its unused exact_nid
argument, the function no longer has any callers.

Remove memblock_alloc_exact_nid_raw() and its declaration. The remaining
callers of memblock_alloc_internal() always allow allocation to fall back
to other NUMA nodes, so remove its exact_nid argument and pass false
directly to memblock_alloc_range_nid().

Suggested-by: Lorenzo Stoakes <ljs@kernel.org>
Signed-off-by: Kaitao Cheng <chengkaitao@kylinos.cn>
---
 include/linux/memblock.h |  3 ---
 mm/memblock.c            | 44 +++++-----------------------------------
 2 files changed, 5 insertions(+), 42 deletions(-)

diff --git a/include/linux/memblock.h b/include/linux/memblock.h
index aa845f488327..01a2dea5aa11 100644
--- a/include/linux/memblock.h
+++ b/include/linux/memblock.h
@@ -412,9 +412,6 @@ static __always_inline phys_addr_t memblock_phys_alloc(phys_addr_t size,
 					 MEMBLOCK_ALLOC_ACCESSIBLE);
 }
 
-void *memblock_alloc_exact_nid_raw(phys_addr_t size, phys_addr_t align,
-				 phys_addr_t min_addr, phys_addr_t max_addr,
-				 int nid);
 void *memblock_alloc_try_nid_raw(phys_addr_t size, phys_addr_t align,
 				 phys_addr_t min_addr, phys_addr_t max_addr,
 				 int nid);
diff --git a/mm/memblock.c b/mm/memblock.c
index 22d14a637f24..51f816ce0cd9 100644
--- a/mm/memblock.c
+++ b/mm/memblock.c
@@ -1659,7 +1659,6 @@ phys_addr_t __init memblock_phys_alloc_try_nid(phys_addr_t size, phys_addr_t ali
  * @min_addr: the lower bound of the memory region to allocate (phys address)
  * @max_addr: the upper bound of the memory region to allocate (phys address)
  * @nid: nid of the free area to find, %NUMA_NO_NODE for any node
- * @exact_nid: control the allocation fall back to other nodes
  *
  * Allocates memory block using memblock_alloc_range_nid() and
  * converts the returned physical address to virtual.
@@ -1675,7 +1674,7 @@ phys_addr_t __init memblock_phys_alloc_try_nid(phys_addr_t size, phys_addr_t ali
 static void * __init memblock_alloc_internal(
 				phys_addr_t size, phys_addr_t align,
 				phys_addr_t min_addr, phys_addr_t max_addr,
-				int nid, bool exact_nid)
+				int nid)
 {
 	phys_addr_t alloc;
 
@@ -1684,12 +1683,12 @@ static void * __init memblock_alloc_internal(
 		max_addr = memblock.current_limit;
 
 	alloc = memblock_alloc_range_nid(size, align, min_addr, max_addr, nid,
-					exact_nid);
+					false);
 
 	/* retry allocation without lower limit */
 	if (!alloc && min_addr)
 		alloc = memblock_alloc_range_nid(size, align, 0, max_addr, nid,
-						exact_nid);
+						false);
 
 	if (!alloc)
 		return NULL;
@@ -1697,37 +1696,6 @@ static void * __init memblock_alloc_internal(
 	return phys_to_virt(alloc);
 }
 
-/**
- * memblock_alloc_exact_nid_raw - allocate boot memory block on the exact node
- * without zeroing memory
- * @size: size of memory block to be allocated in bytes
- * @align: alignment of the region and block's size
- * @min_addr: the lower bound of the memory region from where the allocation
- *	  is preferred (phys address)
- * @max_addr: the upper bound of the memory region from where the allocation
- *	      is preferred (phys address), or %MEMBLOCK_ALLOC_ACCESSIBLE to
- *	      allocate only from memory limited by memblock.current_limit value
- * @nid: nid of the free area to find, %NUMA_NO_NODE for any node
- *
- * Public function, provides additional debug information (including caller
- * info), if enabled. Does not zero allocated memory.
- *
- * Return:
- * Virtual address of allocated memory block on success, NULL on failure.
- */
-void * __init memblock_alloc_exact_nid_raw(
-			phys_addr_t size, phys_addr_t align,
-			phys_addr_t min_addr, phys_addr_t max_addr,
-			int nid)
-{
-	memblock_dbg("%s: %llu bytes align=0x%llx nid=%d from=%pa max_addr=%pa %pS\n",
-		     __func__, (u64)size, (u64)align, nid, &min_addr,
-		     &max_addr, (void *)_RET_IP_);
-
-	return memblock_alloc_internal(size, align, min_addr, max_addr, nid,
-				       true);
-}
-
 /**
  * memblock_alloc_try_nid_raw - allocate boot memory block without zeroing
  * memory and without panicking
@@ -1756,8 +1724,7 @@ void * __init memblock_alloc_try_nid_raw(
 		     __func__, (u64)size, (u64)align, nid, &min_addr,
 		     &max_addr, (void *)_RET_IP_);
 
-	return memblock_alloc_internal(size, align, min_addr, max_addr, nid,
-				       false);
+	return memblock_alloc_internal(size, align, min_addr, max_addr, nid);
 }
 
 /**
@@ -1858,8 +1825,7 @@ void * __init memblock_alloc_try_nid(
 	memblock_dbg("%s: %llu bytes align=0x%llx nid=%d from=%pa max_addr=%pa %pS\n",
 		     __func__, (u64)size, (u64)align, nid, &min_addr,
 		     &max_addr, (void *)_RET_IP_);
-	ptr = memblock_alloc_internal(size, align,
-					   min_addr, max_addr, nid, false);
+	ptr = memblock_alloc_internal(size, align, min_addr, max_addr, nid);
 	if (ptr)
 		memset(ptr, 0, size);
 
-- 
2.54.0 (Apple Git-157)


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

end of thread, other threads:[~2026-09-19 13:54 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-09-19 13:53 [PATCH v2 0/3] memblock: Remove unused exact nid allocation API Kaitao Cheng
2026-09-19 13:53 ` [PATCH v2 1/3] mm: Remove unused exact_nid parameter from memmap_alloc() Kaitao Cheng
2026-09-19 13:53 ` [PATCH v2 2/3] memblock tests: Move exact nid tests to memblock_alloc_range_nid() Kaitao Cheng
2026-09-19 13:53 ` [PATCH v2 3/3] memblock: Remove unused memblock_alloc_exact_nid_raw() Kaitao Cheng

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®