The Linux Kernel Mailing List
 help / color / mirror / Atom feed
* [PATCH 0/4] mm/mm_init: simplify zone_spanned_pages_in_node()
@ 2026-08-04 14:47 Sang-Heon Jeon
  2026-08-04 14:47 ` [PATCH 1/4] mm/mm_init: fold adjust_zone_range_for_zone_movable() into its sole caller Sang-Heon Jeon
                   ` (4 more replies)
  0 siblings, 5 replies; 6+ messages in thread
From: Sang-Heon Jeon @ 2026-08-04 14:47 UTC (permalink / raw)
  To: Andrew Morton, Mike Rapoport; +Cc: linux-kernel, linux-mm

Hello,

This series simplifies zone_spanned_pages_in_node(), which adjusts
*zone_start_pfn and *zone_end_pfn before and after calling
adjust_zone_range_for_zone_movable(). The helper adjusts the same two
values, which makes the code harder to follow.

Split into four patches for easier review. Squashing them into one
patch when applying is also fine.

Patch 1 folds adjust_zone_range_for_zone_movable() into the caller.

Patch 2 removes the clamping to node_end_pfn, which has no effect.

Patch 3 moves the check and the clamping to node_start_pfn into the
ZONE_MOVABLE branch, which is the only place they have an effect.

Patch 4 extracts a local variable and reduces the indentation level.

No functional change.

Sang-Heon Jeon (4):
  mm/mm_init: fold adjust_zone_range_for_zone_movable() into its sole
    caller
  mm/mm_init: remove redundant clamping in zone_spanned_pages_in_node()
  mm/mm_init: move the range check and clamping inside ZONE_MOVABLE
    branch
  mm/mm_init: clean up zone_spanned_pages_in_node()

 mm/mm_init.c | 81 ++++++++++++++++++++++++----------------------------
 1 file changed, 37 insertions(+), 44 deletions(-)

-- 
2.43.0


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

* [PATCH 1/4] mm/mm_init: fold adjust_zone_range_for_zone_movable() into its sole caller
  2026-08-04 14:47 [PATCH 0/4] mm/mm_init: simplify zone_spanned_pages_in_node() Sang-Heon Jeon
@ 2026-08-04 14:47 ` Sang-Heon Jeon
  2026-08-04 14:47 ` [PATCH 2/4] mm/mm_init: remove redundant clamping in zone_spanned_pages_in_node() Sang-Heon Jeon
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: Sang-Heon Jeon @ 2026-08-04 14:47 UTC (permalink / raw)
  To: Mike Rapoport, Andrew Morton; +Cc: linux-kernel, linux-mm

adjust_zone_range_for_zone_movable() adjusts zone_start_pfn and
zone_end_pfn. It is only called from zone_spanned_pages_in_node(), which
adjusts the same two values before and after the call. This makes the
code harder to follow.

Fold the helper into the caller to make the code clearer.

No functional change.

Signed-off-by: Sang-Heon Jeon <ekffu200098@gmail.com>
---
 mm/mm_init.c | 66 ++++++++++++++++++++++------------------------------
 1 file changed, 28 insertions(+), 38 deletions(-)

diff --git a/mm/mm_init.c b/mm/mm_init.c
index 711f821f7b3c..ddff06467239 100644
--- a/mm/mm_init.c
+++ b/mm/mm_init.c
@@ -1143,42 +1143,6 @@ void __ref memmap_init_zone_device(struct zone *zone,
 }
 #endif
 
-/*
- * The zone ranges provided by the architecture do not include ZONE_MOVABLE
- * because it is sized independent of architecture. Unlike the other zones,
- * the starting point for ZONE_MOVABLE is not fixed. It may be different
- * in each node depending on the size of each node and how evenly kernelcore
- * is distributed. This helper function adjusts the zone ranges
- * provided by the architecture for a given node by using the end of the
- * highest usable zone for ZONE_MOVABLE. This preserves the assumption that
- * zones within a node are in order of monotonic increases memory addresses
- */
-static void __init adjust_zone_range_for_zone_movable(int nid,
-					unsigned long zone_type,
-					unsigned long node_end_pfn,
-					unsigned long *zone_start_pfn,
-					unsigned long *zone_end_pfn)
-{
-	/* Only adjust if ZONE_MOVABLE is on this node */
-	if (zone_movable_pfn[nid]) {
-		/* Size ZONE_MOVABLE */
-		if (zone_type == ZONE_MOVABLE) {
-			*zone_start_pfn = zone_movable_pfn[nid];
-			*zone_end_pfn = min(node_end_pfn,
-				arch_zone_highest_possible_pfn[movable_zone]);
-
-		/* Adjust for ZONE_MOVABLE starting within this range */
-		} else if (!mirrored_kernelcore &&
-			*zone_start_pfn < zone_movable_pfn[nid] &&
-			*zone_end_pfn > zone_movable_pfn[nid]) {
-			*zone_end_pfn = zone_movable_pfn[nid];
-
-		/* Check if this whole range is within ZONE_MOVABLE */
-		} else if (*zone_start_pfn >= zone_movable_pfn[nid])
-			*zone_start_pfn = *zone_end_pfn;
-	}
-}
-
 /*
  * Return the number of holes in a range on a node. If nid is MAX_NUMNODES,
  * then all holes in the requested range will be accounted for.
@@ -1257,6 +1221,15 @@ static unsigned long __init zone_absent_pages_in_node(int nid,
 /*
  * 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()
+ *
+ * The zone ranges provided by the architecture do not include ZONE_MOVABLE
+ * because it is sized independent of architecture. Unlike the other zones,
+ * the starting point for ZONE_MOVABLE is not fixed. It may be different
+ * in each node depending on the size of each node and how evenly kernelcore
+ * is distributed. The zone ranges provided by the architecture are adjusted
+ * for a given node by using the end of the highest usable zone for
+ * ZONE_MOVABLE. This preserves the assumption that zones within a node are
+ * in order of monotonic increases memory addresses
  */
 static unsigned long __init zone_spanned_pages_in_node(int nid,
 					unsigned long zone_type,
@@ -1271,8 +1244,25 @@ static unsigned long __init zone_spanned_pages_in_node(int nid,
 	/* Get the start and end of the zone */
 	*zone_start_pfn = clamp(node_start_pfn, zone_low, zone_high);
 	*zone_end_pfn = clamp(node_end_pfn, zone_low, zone_high);
-	adjust_zone_range_for_zone_movable(nid, zone_type, node_end_pfn,
-					   zone_start_pfn, zone_end_pfn);
+
+	/* Only adjust if ZONE_MOVABLE is on this node */
+	if (zone_movable_pfn[nid]) {
+		/* Size ZONE_MOVABLE */
+		if (zone_type == ZONE_MOVABLE) {
+			*zone_start_pfn = zone_movable_pfn[nid];
+			*zone_end_pfn = min(node_end_pfn,
+				arch_zone_highest_possible_pfn[movable_zone]);
+
+		/* Adjust for ZONE_MOVABLE starting within this range */
+		} else if (!mirrored_kernelcore &&
+			*zone_start_pfn < zone_movable_pfn[nid] &&
+			*zone_end_pfn > zone_movable_pfn[nid]) {
+			*zone_end_pfn = zone_movable_pfn[nid];
+
+		/* Check if this whole range is within ZONE_MOVABLE */
+		} else if (*zone_start_pfn >= zone_movable_pfn[nid])
+			*zone_start_pfn = *zone_end_pfn;
+	}
 
 	/* Check that this node has pages within the zone's required range */
 	if (*zone_end_pfn < node_start_pfn || *zone_start_pfn > node_end_pfn)
-- 
2.43.0


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

* [PATCH 2/4] mm/mm_init: remove redundant clamping in zone_spanned_pages_in_node()
  2026-08-04 14:47 [PATCH 0/4] mm/mm_init: simplify zone_spanned_pages_in_node() Sang-Heon Jeon
  2026-08-04 14:47 ` [PATCH 1/4] mm/mm_init: fold adjust_zone_range_for_zone_movable() into its sole caller Sang-Heon Jeon
@ 2026-08-04 14:47 ` Sang-Heon Jeon
  2026-08-04 14:48 ` [PATCH 3/4] mm/mm_init: move the range check and clamping inside ZONE_MOVABLE branch Sang-Heon Jeon
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: Sang-Heon Jeon @ 2026-08-04 14:47 UTC (permalink / raw)
  To: Mike Rapoport, Andrew Morton; +Cc: linux-kernel, linux-mm

Clamping *zone_end_pfn to node_end_pfn has no effect, because
*zone_end_pfn <= node_end_pfn is guaranteed at that point.

1. If zone_movable_pfn[nid] != 0 && zone_type == ZONE_MOVABLE,
   *zone_end_pfn = min(node_end_pfn, ...) <= node_end_pfn.

2. Else If zone_movable_pfn[nid] != 0 && !mirrored_kernelcore &&
   *zone_start_pfn < zone_movable_pfn[nid] < *zone_end_pfn,
   *zone_end_pfn = zone_movable_pfn[nid].

   The condition requires the clamped *zone_start_pfn and
   *zone_end_pfn to differ, which cannot happen when node_end_pfn <
   zone_low.

   So zone_movable_pfn[nid] < clamped *zone_end_pfn =
   min(node_end_pfn, zone_high) <= node_end_pfn.

3. Else *zone_end_pfn = clamp(node_end_pfn, zone_low, zone_high)

   a. If node_end_pfn >= zone_low, *zone_end_pfn =
      min(node_end_pfn, zone_high) <= node_end_pfn.

   b. If node_end_pfn < zone_low, *zone_start_pfn = zone_low >
      node_end_pfn, so the function returns 0 before the clamping is
      executed.

So remove it.

No functional change.

Signed-off-by: Sang-Heon Jeon <ekffu200098@gmail.com>
---
 mm/mm_init.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/mm/mm_init.c b/mm/mm_init.c
index ddff06467239..75fe1918d4d4 100644
--- a/mm/mm_init.c
+++ b/mm/mm_init.c
@@ -1269,7 +1269,6 @@ static unsigned long __init zone_spanned_pages_in_node(int nid,
 		return 0;
 
 	/* Move the zone boundaries inside the node if necessary */
-	*zone_end_pfn = min(*zone_end_pfn, node_end_pfn);
 	*zone_start_pfn = max(*zone_start_pfn, node_start_pfn);
 
 	/* Return the spanned pages */
-- 
2.43.0


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

* [PATCH 3/4] mm/mm_init: move the range check and clamping inside ZONE_MOVABLE branch
  2026-08-04 14:47 [PATCH 0/4] mm/mm_init: simplify zone_spanned_pages_in_node() Sang-Heon Jeon
  2026-08-04 14:47 ` [PATCH 1/4] mm/mm_init: fold adjust_zone_range_for_zone_movable() into its sole caller Sang-Heon Jeon
  2026-08-04 14:47 ` [PATCH 2/4] mm/mm_init: remove redundant clamping in zone_spanned_pages_in_node() Sang-Heon Jeon
@ 2026-08-04 14:48 ` Sang-Heon Jeon
  2026-08-04 14:48 ` [PATCH 4/4] mm/mm_init: clean up zone_spanned_pages_in_node() Sang-Heon Jeon
  2026-08-06 14:41 ` [PATCH 0/4] mm/mm_init: simplify zone_spanned_pages_in_node() Sang-Heon Jeon
  4 siblings, 0 replies; 6+ messages in thread
From: Sang-Heon Jeon @ 2026-08-04 14:48 UTC (permalink / raw)
  To: Mike Rapoport, Andrew Morton; +Cc: linux-kernel, linux-mm

Outside the ZONE_MOVABLE branch the check and the clamping have no
effect, because every branch ends with one of the following.

 - *zone_start_pfn == *zone_end_pfn, so the function returns 0 anyway.

 - node_start_pfn <= *zone_start_pfn <= *zone_end_pfn <= node_end_pfn,
   so the check does not return 0 and max(*zone_start_pfn,
   node_start_pfn) is always *zone_start_pfn.

The branches set *zone_start_pfn and *zone_end_pfn as follows.

1. If zone_movable_pfn[nid] != 0 && zone_type == ZONE_MOVABLE,
   *zone_start_pfn = zone_movable_pfn[nid] and *zone_end_pfn =
   min(node_end_pfn, ...).

2. Else If zone_movable_pfn[nid] != 0 && !mirrored_kernelcore &&
   *zone_start_pfn < zone_movable_pfn[nid] < *zone_end_pfn,
   *zone_end_pfn = zone_movable_pfn[nid].

   The condition requires the clamped *zone_start_pfn and
   *zone_end_pfn to differ, which cannot happen when node_end_pfn <
   zone_low or node_start_pfn > zone_high.

   So *zone_start_pfn = max(node_start_pfn, zone_low) >=
   node_start_pfn, and zone_movable_pfn[nid] < clamped *zone_end_pfn =
   min(node_end_pfn, zone_high) <= node_end_pfn.

   So node_start_pfn <= *zone_start_pfn < *zone_end_pfn <=
   node_end_pfn.

3. Else If zone_movable_pfn[nid] != 0 && *zone_start_pfn >=
   zone_movable_pfn[nid], *zone_start_pfn = *zone_end_pfn.

4. Else *zone_start_pfn = clamp(node_start_pfn, zone_low, zone_high)
   and *zone_end_pfn = clamp(node_end_pfn, zone_low, zone_high)

   a. If node_end_pfn < zone_low, *zone_start_pfn = *zone_end_pfn =
      zone_low.

   b. If node_start_pfn > zone_high, *zone_start_pfn = *zone_end_pfn =
      zone_high.

   c. If node_end_pfn >= zone_low && node_start_pfn <= zone_high,
      node_start_pfn <= *zone_start_pfn <= *zone_end_pfn <=
      node_end_pfn.

So move both inside the ZONE_MOVABLE branch.

No functional change.

Signed-off-by: Sang-Heon Jeon <ekffu200098@gmail.com>
---
 mm/mm_init.c | 18 +++++++++++-------
 1 file changed, 11 insertions(+), 7 deletions(-)

diff --git a/mm/mm_init.c b/mm/mm_init.c
index 75fe1918d4d4..1190a27ed0fb 100644
--- a/mm/mm_init.c
+++ b/mm/mm_init.c
@@ -1253,6 +1253,17 @@ static unsigned long __init zone_spanned_pages_in_node(int nid,
 			*zone_end_pfn = min(node_end_pfn,
 				arch_zone_highest_possible_pfn[movable_zone]);
 
+			/*
+			 * Check that this node has pages within the
+			 * zone's required range
+			 */
+			if (*zone_end_pfn < node_start_pfn ||
+			    *zone_start_pfn > node_end_pfn)
+				return 0;
+
+			/* Move the zone start inside the node if necessary */
+			*zone_start_pfn = max(*zone_start_pfn, node_start_pfn);
+
 		/* Adjust for ZONE_MOVABLE starting within this range */
 		} else if (!mirrored_kernelcore &&
 			*zone_start_pfn < zone_movable_pfn[nid] &&
@@ -1264,13 +1275,6 @@ static unsigned long __init zone_spanned_pages_in_node(int nid,
 			*zone_start_pfn = *zone_end_pfn;
 	}
 
-	/* Check that this node has pages within the zone's required range */
-	if (*zone_end_pfn < node_start_pfn || *zone_start_pfn > node_end_pfn)
-		return 0;
-
-	/* Move the zone boundaries inside the node if necessary */
-	*zone_start_pfn = max(*zone_start_pfn, node_start_pfn);
-
 	/* Return the spanned pages */
 	return *zone_end_pfn - *zone_start_pfn;
 }
-- 
2.43.0


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

* [PATCH 4/4] mm/mm_init: clean up zone_spanned_pages_in_node()
  2026-08-04 14:47 [PATCH 0/4] mm/mm_init: simplify zone_spanned_pages_in_node() Sang-Heon Jeon
                   ` (2 preceding siblings ...)
  2026-08-04 14:48 ` [PATCH 3/4] mm/mm_init: move the range check and clamping inside ZONE_MOVABLE branch Sang-Heon Jeon
@ 2026-08-04 14:48 ` Sang-Heon Jeon
  2026-08-06 14:41 ` [PATCH 0/4] mm/mm_init: simplify zone_spanned_pages_in_node() Sang-Heon Jeon
  4 siblings, 0 replies; 6+ messages in thread
From: Sang-Heon Jeon @ 2026-08-04 14:48 UTC (permalink / raw)
  To: Mike Rapoport, Andrew Morton; +Cc: linux-kernel, linux-mm

Extract zone_movable_pfn[nid], which is used six times, into a local
variable, and return early to reduce the indentation level.

No functional change.

Signed-off-by: Sang-Heon Jeon <ekffu200098@gmail.com>
---
 mm/mm_init.c | 48 ++++++++++++++++++++++++------------------------
 1 file changed, 24 insertions(+), 24 deletions(-)

diff --git a/mm/mm_init.c b/mm/mm_init.c
index 1190a27ed0fb..d544eed2f173 100644
--- a/mm/mm_init.c
+++ b/mm/mm_init.c
@@ -1240,41 +1240,41 @@ static unsigned long __init zone_spanned_pages_in_node(int nid,
 {
 	unsigned long zone_low = arch_zone_lowest_possible_pfn[zone_type];
 	unsigned long zone_high = arch_zone_highest_possible_pfn[zone_type];
+	unsigned long movable_pfn = zone_movable_pfn[nid];
 
 	/* Get the start and end of the zone */
 	*zone_start_pfn = clamp(node_start_pfn, zone_low, zone_high);
 	*zone_end_pfn = clamp(node_end_pfn, zone_low, zone_high);
 
-	/* Only adjust if ZONE_MOVABLE is on this node */
-	if (zone_movable_pfn[nid]) {
-		/* Size ZONE_MOVABLE */
-		if (zone_type == ZONE_MOVABLE) {
-			*zone_start_pfn = zone_movable_pfn[nid];
-			*zone_end_pfn = min(node_end_pfn,
-				arch_zone_highest_possible_pfn[movable_zone]);
+	/* Nothing to adjust if ZONE_MOVABLE is not on this node */
+	if (!movable_pfn)
+		goto out;
 
-			/*
-			 * Check that this node has pages within the
-			 * zone's required range
-			 */
-			if (*zone_end_pfn < node_start_pfn ||
-			    *zone_start_pfn > node_end_pfn)
-				return 0;
+	/* Size ZONE_MOVABLE */
+	if (zone_type == ZONE_MOVABLE) {
+		*zone_start_pfn = movable_pfn;
+		*zone_end_pfn = min(node_end_pfn,
+			arch_zone_highest_possible_pfn[movable_zone]);
 
-			/* Move the zone start inside the node if necessary */
-			*zone_start_pfn = max(*zone_start_pfn, node_start_pfn);
+		/* Check that this node has pages within the zone's required range */
+		if (*zone_end_pfn < node_start_pfn ||
+		    *zone_start_pfn > node_end_pfn)
+			return 0;
 
-		/* Adjust for ZONE_MOVABLE starting within this range */
-		} else if (!mirrored_kernelcore &&
-			*zone_start_pfn < zone_movable_pfn[nid] &&
-			*zone_end_pfn > zone_movable_pfn[nid]) {
-			*zone_end_pfn = zone_movable_pfn[nid];
+		/* Move the zone start inside the node if necessary */
+		*zone_start_pfn = max(*zone_start_pfn, node_start_pfn);
 
-		/* Check if this whole range is within ZONE_MOVABLE */
-		} else if (*zone_start_pfn >= zone_movable_pfn[nid])
-			*zone_start_pfn = *zone_end_pfn;
+	/* Adjust for ZONE_MOVABLE starting within this range */
+	} else if (!mirrored_kernelcore && *zone_start_pfn < movable_pfn &&
+		   *zone_end_pfn > movable_pfn) {
+		*zone_end_pfn = movable_pfn;
+
+	/* Check if this whole range is within ZONE_MOVABLE */
+	} else if (*zone_start_pfn >= movable_pfn) {
+		*zone_start_pfn = *zone_end_pfn;
 	}
 
+out:
 	/* Return the spanned pages */
 	return *zone_end_pfn - *zone_start_pfn;
 }
-- 
2.43.0


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

* Re: [PATCH 0/4] mm/mm_init: simplify zone_spanned_pages_in_node()
  2026-08-04 14:47 [PATCH 0/4] mm/mm_init: simplify zone_spanned_pages_in_node() Sang-Heon Jeon
                   ` (3 preceding siblings ...)
  2026-08-04 14:48 ` [PATCH 4/4] mm/mm_init: clean up zone_spanned_pages_in_node() Sang-Heon Jeon
@ 2026-08-06 14:41 ` Sang-Heon Jeon
  4 siblings, 0 replies; 6+ messages in thread
From: Sang-Heon Jeon @ 2026-08-06 14:41 UTC (permalink / raw)
  To: Andrew Morton, Mike Rapoport; +Cc: linux-kernel, linux-mm

On Tue, Aug 4, 2026 at 11:48 PM Sang-Heon Jeon <ekffu200098@gmail.com> wrote:
>
> Hello,
>
> This series simplifies zone_spanned_pages_in_node(), which adjusts
> *zone_start_pfn and *zone_end_pfn before and after calling
> adjust_zone_range_for_zone_movable(). The helper adjusts the same two
> values, which makes the code harder to follow.
>
> Split into four patches for easier review. Squashing them into one
> patch when applying is also fine.
>
> Patch 1 folds adjust_zone_range_for_zone_movable() into the caller.
>
> Patch 2 removes the clamping to node_end_pfn, which has no effect.
>
> Patch 3 moves the check and the clamping to node_start_pfn into the
> ZONE_MOVABLE branch, which is the only place they have an effect.
>
> Patch 4 extracts a local variable and reduces the indentation level.
>
> No functional change.
>
> Sang-Heon Jeon (4):
>   mm/mm_init: fold adjust_zone_range_for_zone_movable() into its sole
>     caller
>   mm/mm_init: remove redundant clamping in zone_spanned_pages_in_node()
>   mm/mm_init: move the range check and clamping inside ZONE_MOVABLE
>     branch
>   mm/mm_init: clean up zone_spanned_pages_in_node()

A series changing the kernelcore=mirror behavior [1] has already been
merged into memblock/for-next. I'll rebase and send v2.

[1] https://lore.kernel.org/all/20260630072212.624305-1-rppt@kernel.org/

>  mm/mm_init.c | 81 ++++++++++++++++++++++++----------------------------
>  1 file changed, 37 insertions(+), 44 deletions(-)
>
> --
> 2.43.0
>

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

end of thread, other threads:[~2026-08-06 14:42 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-08-04 14:47 [PATCH 0/4] mm/mm_init: simplify zone_spanned_pages_in_node() Sang-Heon Jeon
2026-08-04 14:47 ` [PATCH 1/4] mm/mm_init: fold adjust_zone_range_for_zone_movable() into its sole caller Sang-Heon Jeon
2026-08-04 14:47 ` [PATCH 2/4] mm/mm_init: remove redundant clamping in zone_spanned_pages_in_node() Sang-Heon Jeon
2026-08-04 14:48 ` [PATCH 3/4] mm/mm_init: move the range check and clamping inside ZONE_MOVABLE branch Sang-Heon Jeon
2026-08-04 14:48 ` [PATCH 4/4] mm/mm_init: clean up zone_spanned_pages_in_node() Sang-Heon Jeon
2026-08-06 14:41 ` [PATCH 0/4] mm/mm_init: simplify zone_spanned_pages_in_node() Sang-Heon Jeon

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox