On Fri, Jan 13, 2023 at 04:26:59PM +0800, Peng Zhang wrote: > memblock_merge_regions() is called after regions have been modified to > merge the neighboring compatible regions. That will check all regions > but most checks is useless. > > Most of the time we only insert one or a few new regions, or modify one > or a few regions. At this time, we don't need to check all regions. We > only need to check the changed regions, because other not related > regions cannot be merged. So this patch add two parameters to > memblock_merge_regions() to indicate the lower and upper boundary to scan. > > Signed-off-by: Peng Zhang <zhangpeng.00@xxxxxxxxxxxxx> > --- > mm/memblock.c | 36 ++++++++++++++++++++++++------------ > 1 file changed, 24 insertions(+), 12 deletions(-) > > diff --git a/mm/memblock.c b/mm/memblock.c > index cb92770ac22e..e19eb08efc73 100644 > --- a/mm/memblock.c > +++ b/mm/memblock.c > @@ -523,15 +523,18 @@ static int __init_memblock memblock_double_array(struct memblock_type *type, > /** > * memblock_merge_regions - merge neighboring compatible regions > * @type: memblock type to scan > - * > - * Scan @type and merge neighboring compatible regions. > + * @start_rgn: start scanning from (@start_rgn - 1) > + * @end_rgn: end scanning at (@end_rgn - 1) > + * Scan @type and merge neighboring compatible regions in [@start_rgn - 1, @end_rgn) > */ > -static void __init_memblock memblock_merge_regions(struct memblock_type *type) > +static void __init_memblock memblock_merge_regions(struct memblock_type *type, > + int start_rgn, > + int end_rgn) Make start_rgn and end_rgn unsigned longs and ... > { > - int i = 0; > + int i = max(start_rgn - 1, 0); ... open code max() as if (start_rgn) i = start_rgn; > - /* cnt never goes below 1 */ > - while (i < type->cnt - 1) { > + end_rgn = min(end_rgn, (int)type->cnt - 1); ... and drop the casting here. > + while (i < end_rgn) { > struct memblock_region *this = &type->regions[i]; > struct memblock_region *next = &type->regions[i + 1]; > > @@ -548,6 +551,7 @@ static void __init_memblock memblock_merge_regions(struct memblock_type *type) > /* move forward from next + 1, index of which is i + 2 */ > memmove(next, next + 1, (type->cnt - (i + 2)) * sizeof(*next)); > type->cnt--; > + end_rgn--; > } > } > > @@ -604,7 +608,7 @@ static int __init_memblock memblock_add_range(struct memblock_type *type, > bool insert = false; > phys_addr_t obase = base; > phys_addr_t end = base + memblock_cap_size(base, &size); > - int idx, start_idx, nr_new; > + int idx, start_idx, nr_new, start_rgn = -1, end_rgn; > struct memblock_region *rgn; > > if (!size) > @@ -659,10 +663,14 @@ static int __init_memblock memblock_add_range(struct memblock_type *type, > #endif > WARN_ON(flags != rgn->flags); > nr_new++; > - if (insert) > + if (insert) { > + if (start_rgn == -1) you can initialize start_rgn with 0 and use if(!start_rgn) here. > + 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); > @@ -671,9 +679,13 @@ static int __init_memblock memblock_add_range(struct memblock_type *type, > /* insert the remaining portion */ > if (base < end) { > nr_new++; > - if (insert) > + if (insert) { > + if (start_rgn == -1) Ditto. > + start_rgn = idx; > + end_rgn = idx + 1; > memblock_insert_region(type, idx, base, end - base, > nid, flags); > + } > } > > if (!nr_new) > @@ -690,7 +702,7 @@ static int __init_memblock memblock_add_range(struct memblock_type *type, > insert = true; > goto repeat; > } else { > - memblock_merge_regions(type); > + memblock_merge_regions(type, start_rgn, end_rgn); > return 0; > } > } > @@ -927,7 +939,7 @@ static int __init_memblock memblock_setclr_flag(phys_addr_t base, > r->flags &= ~flag; > } > > - memblock_merge_regions(type); > + memblock_merge_regions(type, start_rgn, end_rgn); > return 0; > } > > @@ -1300,7 +1312,7 @@ int __init_memblock memblock_set_node(phys_addr_t base, phys_addr_t size, > for (i = start_rgn; i < end_rgn; i++) > memblock_set_region_node(&type->regions[i], nid); > > - memblock_merge_regions(type); > + memblock_merge_regions(type, start_rgn, end_rgn); > #endif > return 0; > } > -- > 2.20.1 > -- Sincerely yours, Mike.