Commit 5a6d9249 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'memblock-v6.3-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rppt/memblock

Pull memblock updates from Mike Rapoport:
 "Small optimizations:

   - fix off-by-one in the check whether memblock_add_range() should
     reallocate memory to accommodate newly inserted range

   - check only for relevant regions in memblock_merge_regions() rather
     than swipe over the entire array"

* tag 'memblock-v6.3-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rppt/memblock:
  memblock: Avoid useless checks in memblock_merge_regions().
  memblock: Make a boundary tighter in memblock_add_range().
parents 02a737f4 2fe03412
...@@ -500,15 +500,19 @@ static int __init_memblock memblock_double_array(struct memblock_type *type, ...@@ -500,15 +500,19 @@ static int __init_memblock memblock_double_array(struct memblock_type *type,
/** /**
* memblock_merge_regions - merge neighboring compatible regions * memblock_merge_regions - merge neighboring compatible regions
* @type: memblock type to scan * @type: memblock type to scan
* * @start_rgn: start scanning from (@start_rgn - 1)
* Scan @type and merge neighboring compatible regions. * @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,
unsigned long start_rgn,
unsigned long end_rgn)
{ {
int i = 0; int i = 0;
if (start_rgn)
/* cnt never goes below 1 */ i = start_rgn - 1;
while (i < type->cnt - 1) { end_rgn = min(end_rgn, type->cnt - 1);
while (i < end_rgn) {
struct memblock_region *this = &type->regions[i]; struct memblock_region *this = &type->regions[i];
struct memblock_region *next = &type->regions[i + 1]; struct memblock_region *next = &type->regions[i + 1];
...@@ -525,6 +529,7 @@ static void __init_memblock memblock_merge_regions(struct memblock_type *type) ...@@ -525,6 +529,7 @@ static void __init_memblock memblock_merge_regions(struct memblock_type *type)
/* move forward from next + 1, index of which is i + 2 */ /* move forward from next + 1, index of which is i + 2 */
memmove(next, next + 1, (type->cnt - (i + 2)) * sizeof(*next)); memmove(next, next + 1, (type->cnt - (i + 2)) * sizeof(*next));
type->cnt--; type->cnt--;
end_rgn--;
} }
} }
...@@ -581,7 +586,7 @@ static int __init_memblock memblock_add_range(struct memblock_type *type, ...@@ -581,7 +586,7 @@ static int __init_memblock memblock_add_range(struct memblock_type *type,
bool insert = false; bool insert = false;
phys_addr_t obase = base; phys_addr_t obase = base;
phys_addr_t end = base + memblock_cap_size(base, &size); phys_addr_t end = base + memblock_cap_size(base, &size);
int idx, nr_new; int idx, nr_new, start_rgn = -1, end_rgn;
struct memblock_region *rgn; struct memblock_region *rgn;
if (!size) if (!size)
...@@ -601,11 +606,11 @@ static int __init_memblock memblock_add_range(struct memblock_type *type, ...@@ -601,11 +606,11 @@ static int __init_memblock memblock_add_range(struct memblock_type *type,
/* /*
* The worst case is when new range overlaps all existing regions, * The worst case is when new range overlaps all existing regions,
* then we'll need type->cnt + 1 empty regions in @type. So if * then we'll need type->cnt + 1 empty regions in @type. So if
* type->cnt * 2 + 1 is less than type->max, we know * 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 * that there is enough empty regions in @type, and we can insert
* regions directly. * regions directly.
*/ */
if (type->cnt * 2 + 1 < type->max) if (type->cnt * 2 + 1 <= type->max)
insert = true; insert = true;
repeat: repeat:
...@@ -635,11 +640,15 @@ static int __init_memblock memblock_add_range(struct memblock_type *type, ...@@ -635,11 +640,15 @@ static int __init_memblock memblock_add_range(struct memblock_type *type,
#endif #endif
WARN_ON(flags != rgn->flags); WARN_ON(flags != rgn->flags);
nr_new++; nr_new++;
if (insert) if (insert) {
if (start_rgn == -1)
start_rgn = idx;
end_rgn = idx + 1;
memblock_insert_region(type, idx++, base, memblock_insert_region(type, idx++, base,
rbase - base, nid, rbase - base, nid,
flags); flags);
} }
}
/* area below @rend is dealt with, forget about it */ /* area below @rend is dealt with, forget about it */
base = min(rend, end); base = min(rend, end);
} }
...@@ -647,10 +656,14 @@ static int __init_memblock memblock_add_range(struct memblock_type *type, ...@@ -647,10 +656,14 @@ static int __init_memblock memblock_add_range(struct memblock_type *type,
/* insert the remaining portion */ /* insert the remaining portion */
if (base < end) { if (base < end) {
nr_new++; nr_new++;
if (insert) if (insert) {
if (start_rgn == -1)
start_rgn = idx;
end_rgn = idx + 1;
memblock_insert_region(type, idx, base, end - base, memblock_insert_region(type, idx, base, end - base,
nid, flags); nid, flags);
} }
}
if (!nr_new) if (!nr_new)
return 0; return 0;
...@@ -666,7 +679,7 @@ static int __init_memblock memblock_add_range(struct memblock_type *type, ...@@ -666,7 +679,7 @@ static int __init_memblock memblock_add_range(struct memblock_type *type,
insert = true; insert = true;
goto repeat; goto repeat;
} else { } else {
memblock_merge_regions(type); memblock_merge_regions(type, start_rgn, end_rgn);
return 0; return 0;
} }
} }
...@@ -902,7 +915,7 @@ static int __init_memblock memblock_setclr_flag(phys_addr_t base, ...@@ -902,7 +915,7 @@ static int __init_memblock memblock_setclr_flag(phys_addr_t base,
r->flags &= ~flag; r->flags &= ~flag;
} }
memblock_merge_regions(type); memblock_merge_regions(type, start_rgn, end_rgn);
return 0; return 0;
} }
...@@ -1275,7 +1288,7 @@ int __init_memblock memblock_set_node(phys_addr_t base, phys_addr_t size, ...@@ -1275,7 +1288,7 @@ int __init_memblock memblock_set_node(phys_addr_t base, phys_addr_t size,
for (i = start_rgn; i < end_rgn; i++) for (i = start_rgn; i < end_rgn; i++)
memblock_set_region_node(&type->regions[i], nid); memblock_set_region_node(&type->regions[i], nid);
memblock_merge_regions(type); memblock_merge_regions(type, start_rgn, end_rgn);
#endif #endif
return 0; return 0;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment