@@ -500,15 +500,19 @@ static int __init_memblock memblock_double_array(struct memblock_type *type,
500
500
/**
501
501
* memblock_merge_regions - merge neighboring compatible regions
502
502
* @type: memblock type to scan
503
- *
504
- * Scan @type and merge neighboring compatible regions.
503
+ * @start_rgn: start scanning from (@start_rgn - 1)
504
+ * @end_rgn: end scanning at (@end_rgn - 1)
505
+ * Scan @type and merge neighboring compatible regions in [@start_rgn - 1, @end_rgn)
505
506
*/
506
- static void __init_memblock memblock_merge_regions (struct memblock_type * type )
507
+ static void __init_memblock memblock_merge_regions (struct memblock_type * type ,
508
+ unsigned long start_rgn ,
509
+ unsigned long end_rgn )
507
510
{
508
511
int i = 0 ;
509
-
510
- /* cnt never goes below 1 */
511
- while (i < type -> cnt - 1 ) {
512
+ if (start_rgn )
513
+ i = start_rgn - 1 ;
514
+ end_rgn = min (end_rgn , type -> cnt - 1 );
515
+ while (i < end_rgn ) {
512
516
struct memblock_region * this = & type -> regions [i ];
513
517
struct memblock_region * next = & type -> regions [i + 1 ];
514
518
@@ -525,6 +529,7 @@ static void __init_memblock memblock_merge_regions(struct memblock_type *type)
525
529
/* move forward from next + 1, index of which is i + 2 */
526
530
memmove (next , next + 1 , (type -> cnt - (i + 2 )) * sizeof (* next ));
527
531
type -> cnt -- ;
532
+ end_rgn -- ;
528
533
}
529
534
}
530
535
@@ -581,7 +586,7 @@ static int __init_memblock memblock_add_range(struct memblock_type *type,
581
586
bool insert = false;
582
587
phys_addr_t obase = base ;
583
588
phys_addr_t end = base + memblock_cap_size (base , & size );
584
- int idx , nr_new ;
589
+ int idx , nr_new , start_rgn = -1 , end_rgn ;
585
590
struct memblock_region * rgn ;
586
591
587
592
if (!size )
@@ -601,11 +606,11 @@ static int __init_memblock memblock_add_range(struct memblock_type *type,
601
606
/*
602
607
* The worst case is when new range overlaps all existing regions,
603
608
* then we'll need type->cnt + 1 empty regions in @type. So if
604
- * type->cnt * 2 + 1 is less than type->max, we know
609
+ * type->cnt * 2 + 1 is less than or equal to type->max, we know
605
610
* that there is enough empty regions in @type, and we can insert
606
611
* regions directly.
607
612
*/
608
- if (type -> cnt * 2 + 1 < type -> max )
613
+ if (type -> cnt * 2 + 1 <= type -> max )
609
614
insert = true;
610
615
611
616
repeat :
@@ -635,10 +640,14 @@ static int __init_memblock memblock_add_range(struct memblock_type *type,
635
640
#endif
636
641
WARN_ON (flags != rgn -> flags );
637
642
nr_new ++ ;
638
- if (insert )
643
+ if (insert ) {
644
+ if (start_rgn == -1 )
645
+ start_rgn = idx ;
646
+ end_rgn = idx + 1 ;
639
647
memblock_insert_region (type , idx ++ , base ,
640
648
rbase - base , nid ,
641
649
flags );
650
+ }
642
651
}
643
652
/* area below @rend is dealt with, forget about it */
644
653
base = min (rend , end );
@@ -647,9 +656,13 @@ static int __init_memblock memblock_add_range(struct memblock_type *type,
647
656
/* insert the remaining portion */
648
657
if (base < end ) {
649
658
nr_new ++ ;
650
- if (insert )
659
+ if (insert ) {
660
+ if (start_rgn == -1 )
661
+ start_rgn = idx ;
662
+ end_rgn = idx + 1 ;
651
663
memblock_insert_region (type , idx , base , end - base ,
652
664
nid , flags );
665
+ }
653
666
}
654
667
655
668
if (!nr_new )
@@ -666,7 +679,7 @@ static int __init_memblock memblock_add_range(struct memblock_type *type,
666
679
insert = true;
667
680
goto repeat ;
668
681
} else {
669
- memblock_merge_regions (type );
682
+ memblock_merge_regions (type , start_rgn , end_rgn );
670
683
return 0 ;
671
684
}
672
685
}
@@ -902,7 +915,7 @@ static int __init_memblock memblock_setclr_flag(phys_addr_t base,
902
915
r -> flags &= ~flag ;
903
916
}
904
917
905
- memblock_merge_regions (type );
918
+ memblock_merge_regions (type , start_rgn , end_rgn );
906
919
return 0 ;
907
920
}
908
921
@@ -1275,7 +1288,7 @@ int __init_memblock memblock_set_node(phys_addr_t base, phys_addr_t size,
1275
1288
for (i = start_rgn ; i < end_rgn ; i ++ )
1276
1289
memblock_set_region_node (& type -> regions [i ], nid );
1277
1290
1278
- memblock_merge_regions (type );
1291
+ memblock_merge_regions (type , start_rgn , end_rgn );
1279
1292
#endif
1280
1293
return 0 ;
1281
1294
}
0 commit comments