diff --git a/mm/memblock.c b/mm/memblock.c
index 95af35fd1389..75c76b39a364 100644
--- a/mm/memblock.c
+++ b/mm/memblock.c
@@ -585,16 +585,16 @@ 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;
+     phys_addr_t rbase, rend;
+     int idx, nr_new, start_rgn, end_rgn;
      struct memblock_region *rgn;
 
      if (!size)
            return 0;
 
-     /* special case for empty array */
+     /* Special case for empty array */
      if (type->regions[0].size == 0) {
            WARN_ON(type->cnt != 0 || type->total_size);
            type->regions[0].base = base;
@@ -606,80 +606,114 @@ static int __init_memblock memblock_add_range(struct memblock_type *type,
            return 0;
      }
 
+    /* Delayed assignment, which is not necessary when the array is empty. */
+     start_rgn = -1;
      /*
-      * 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.
+      * Originally, `end_rgn` didn't need to be assigned a value,
+      * but due to the use of nested conditional expressions,
+      * the compiler reports a warning that `end_rgn` is uninitialized.
+      * Therefore, it has been given an initial value here
+      * to eliminate the warning.
       */
-     if (type->cnt * 2 + 1 <= type->max)
-           insert = true;
+     end_rgn   = -1;
 
 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.
+      * It is assumed that insertion is always possible under normal circumstances.
+      * If memory is insufficient during insertion, the operation will record the need,
+      * allocate memory, and then re-execute the insertion for the remaining portion.
       */
      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;
+           rbase = rgn->base;
+           rend = rbase + rgn->size;
 
            if (rbase >= end)
                  break;
            if (rend <= base)
                  continue;
+
            /*
-            * @rgn overlaps.  If it separates the lower part of new
-            * area, insert that portion.
+            * @rgn overlaps. If it separates the lower part of new area, insert that portion.
             */
            if (rbase > base) {
 #ifdef CONFIG_NUMA
                  WARN_ON(nid != memblock_get_region_node(rgn));
 #endif
                  WARN_ON(flags != rgn->flags);
-                 nr_new++;
-                 if (insert) {
+                 /*
+                  * If memory is insufficient, the space required will be recorded.
+                  * If memory is sufficient, the insertion will proceed.
+                  */
+                 if (type->cnt >= type->max) {
+                       /*
+                        * Record obase as the address where the
+                        * overlapping part has not been resolved,
+                        * so that when repeat restarts,
+                        * redundant operations of resolving the
+                        * overlapping addresses are avoided.
+                        */
+                       if (nr_new == 0)
+                             obase = base;
+                       nr_new++;
+                 } else {
                        if (start_rgn == -1)
                              start_rgn = idx;
                        end_rgn = idx + 1;
-                       memblock_insert_region(type, idx++, base,
-                                          rbase - base, nid,
-                                          flags);
+                       memblock_insert_region(type, idx++, base, rbase - base, nid, flags);
                  }
            }
-           /* area below @rend is dealt with, forget about it */
+           /* Area below @rend is dealt with, forget about it */
            base = min(rend, end);
      }
 
-     /* insert the remaining portion */
+     /* Insert the remaining portion */
      if (base < end) {
-           nr_new++;
-           if (insert) {
+           /*
+            * Similarly, after handling the overlapping part,
+            * it is still possible that memory is
+            * insufficient. In that case, the space will be recorded once again.
+            */
+           if (type->cnt >= type->max) {
+                 /*
+                  * The address of obase needs to be recorded here as well. The purpose is to
+                  * handle the situation where,
+                  * after resolving the overlap, there is still a remaining space to
+                  * insert but memory is insufficient (i.e.,
+                  * no memory shortage occurred while resolving the overlap).
+                  * This means that space for
+                  * N (overlapping parts) + 1 (non-overlapping part) is required.
+                  * If obase is not recorded, after memory expansion,
+                  * base might revert to the original address to be
+                  * inserted (which could be overlapping).
+                  * This could lead to for_each_memblock_type attempting
+                  * to resolve the overlap again, causing multiple unnecessary iterations,
+                  * even if it's just a simple check.
+                  */
+                 if (nr_new == 0)
+                       obase = base;
+                 nr_new++;
+           } else {
                  if (start_rgn == -1)
                        start_rgn = idx;
                  end_rgn = idx + 1;
-                 memblock_insert_region(type, idx, base, end - base,
-                                    nid, flags);
+                 memblock_insert_region(type, idx, base, end - base, nid, flags);
            }
      }
 
-     if (!nr_new)
-           return 0;
-
      /*
-      * If this was the first round, resize array and repeat for actual
-      * insertions; otherwise, merge and return.
+      * Finally, check if memory insufficiency occurred during insertion.
+      * If so, the memory will be expanded to an appropriate size,
+      * and the remaining portion will be inserted again.
+      * If not, it means memory is sufficient, and the regions will be merged directly.
       */
-     if (!insert) {
-           while (type->cnt + nr_new > type->max)
+     if (nr_new > 0) {
+           while (type->cnt + nr_new > type->max) {
                  if (memblock_double_array(type, obase, size) < 0)
                        return -ENOMEM;
-           insert = true;
+           }
            goto repeat;
      } else {
            memblock_merge_regions(type, start_rgn, end_rgn);
