linux-mm.kvack.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 1/6] mm/memblock: reduce the two round insertion of memblock_add_range()
@ 2024-04-14  0:45 Wei Yang
  2024-04-14  0:45 ` [PATCH 2/6] memblock tests: add the 129th memory block at all possible position Wei Yang
                   ` (5 more replies)
  0 siblings, 6 replies; 16+ messages in thread
From: Wei Yang @ 2024-04-14  0:45 UTC (permalink / raw)
  To: rppt, akpm; +Cc: linux-mm, Wei Yang, Jinyu Tang, Peng Zhang

Current memblock_add_range() does the insertion with two round
iteration.

First round does the calculation of new region required, and second
round does the actual insertion. Between them, if current max can't meet
new region requirement, it is expanded.

The worst case is:

1. cnt == max
2. new range overlaps all existing region

This means the final cnt should be (2 * max + 1). Since we always double
the array size, this means we only need to double the array twice at the
worst case, which is fairly rare. For other cases, only once array
double is enough.

Let's double the array immediately when there is no room for new region.
This simplify the code a little.

Signed-off-by: Wei Yang <richard.weiyang@gmail.com>
CC: Jinyu Tang <tjytimi@163.com>
CC: Peng Zhang <zhangpeng.00@bytedance.com>
---
 mm/memblock.c | 74 +++++++++++++++------------------------------------
 1 file changed, 22 insertions(+), 52 deletions(-)

diff --git a/mm/memblock.c b/mm/memblock.c
index 98d25689cf10..b46109300927 100644
--- a/mm/memblock.c
+++ b/mm/memblock.c
@@ -585,10 +585,9 @@ static int __init_memblock memblock_add_range(struct memblock_type *type,
 				phys_addr_t base, phys_addr_t size,
 				int nid, enum memblock_flags flags)
 {
-	bool insert = false;
 	phys_addr_t obase = base;
 	phys_addr_t end = base + memblock_cap_size(base, &size);
-	int idx, nr_new, start_rgn = -1, end_rgn;
+	int idx, start_rgn = -1, end_rgn;
 	struct memblock_region *rgn;
 
 	if (!size)
@@ -606,25 +605,6 @@ static int __init_memblock memblock_add_range(struct memblock_type *type,
 		return 0;
 	}
 
-	/*
-	 * The worst case is when new range overlaps all existing regions,
-	 * then we'll need type->cnt + 1 empty regions in @type. So if
-	 * type->cnt * 2 + 1 is less than or equal to type->max, we know
-	 * that there is enough empty regions in @type, and we can insert
-	 * regions directly.
-	 */
-	if (type->cnt * 2 + 1 <= type->max)
-		insert = true;
-
-repeat:
-	/*
-	 * The following is executed twice.  Once with %false @insert and
-	 * then with %true.  The first counts the number of regions needed
-	 * to accommodate the new area.  The second actually inserts them.
-	 */
-	base = obase;
-	nr_new = 0;
-
 	for_each_memblock_type(idx, type, rgn) {
 		phys_addr_t rbase = rgn->base;
 		phys_addr_t rend = rbase + rgn->size;
@@ -642,15 +622,17 @@ static int __init_memblock memblock_add_range(struct memblock_type *type,
 			WARN_ON(nid != memblock_get_region_node(rgn));
 #endif
 			WARN_ON(flags != rgn->flags);
-			nr_new++;
-			if (insert) {
-				if (start_rgn == -1)
-					start_rgn = idx;
-				end_rgn = idx + 1;
-				memblock_insert_region(type, idx++, base,
-						       rbase - base, nid,
-						       flags);
+			if (type->cnt >= type->max) {
+				if (memblock_double_array(type, obase, size) < 0)
+					return -ENOMEM;
 			}
+
+			if (start_rgn == -1)
+				start_rgn = idx;
+			end_rgn = idx + 1;
+			memblock_insert_region(type, idx++, base,
+					       rbase - base, nid,
+					       flags);
 		}
 		/* area below @rend is dealt with, forget about it */
 		base = min(rend, end);
@@ -658,33 +640,21 @@ static int __init_memblock memblock_add_range(struct memblock_type *type,
 
 	/* insert the remaining portion */
 	if (base < end) {
-		nr_new++;
-		if (insert) {
-			if (start_rgn == -1)
-				start_rgn = idx;
-			end_rgn = idx + 1;
-			memblock_insert_region(type, idx, base, end - base,
-					       nid, flags);
+		if (type->cnt >= type->max) {
+			if (memblock_double_array(type, obase, size) < 0)
+				return -ENOMEM;
 		}
-	}
 
-	if (!nr_new)
-		return 0;
+		if (start_rgn == -1)
+			start_rgn = idx;
+		end_rgn = idx + 1;
+		memblock_insert_region(type, idx, base, end - base,
+				       nid, flags);
+	}
 
-	/*
-	 * If this was the first round, resize array and repeat for actual
-	 * insertions; otherwise, merge and return.
-	 */
-	if (!insert) {
-		while (type->cnt + nr_new > type->max)
-			if (memblock_double_array(type, obase, size) < 0)
-				return -ENOMEM;
-		insert = true;
-		goto repeat;
-	} else {
+	if (start_rgn != -1)
 		memblock_merge_regions(type, start_rgn, end_rgn);
-		return 0;
-	}
+	return 0;
 }
 
 /**
-- 
2.34.1



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

end of thread, other threads:[~2024-04-25  1:38 UTC | newest]

Thread overview: 16+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-04-14  0:45 [PATCH 1/6] mm/memblock: reduce the two round insertion of memblock_add_range() Wei Yang
2024-04-14  0:45 ` [PATCH 2/6] memblock tests: add the 129th memory block at all possible position Wei Yang
2024-04-15 15:19   ` Mike Rapoport
2024-04-16 12:55     ` Wei Yang
2024-04-17  5:51       ` Mike Rapoport
2024-04-18  9:02         ` Wei Yang
2024-04-19  3:15         ` Wei Yang
2024-04-24 13:13           ` Mike Rapoport
2024-04-14  0:45 ` [PATCH 3/6] mm/memblock: fix comment for memblock_isolate_range() Wei Yang
2024-04-14  0:45 ` [PATCH 4/6] mm/memblock: remove consecutive regions at once Wei Yang
2024-04-14  0:45 ` [PATCH 5/6] memblock tests: add memblock_overlaps_region_checks Wei Yang
2024-04-14  0:45 ` [PATCH 6/6] mm/memblock: return true directly on finding overlap region Wei Yang
2024-04-15 15:17 ` [PATCH 1/6] mm/memblock: reduce the two round insertion of memblock_add_range() Mike Rapoport
2024-04-22  2:55   ` Wei Yang
2024-04-24 13:15     ` Mike Rapoport
2024-04-25  1:38       ` Wei Yang

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).