Commit 62327918 authored by Max Filippov's avatar Max Filippov

xtensa: keep sysmem banks ordered in mem_reserve

Rewrite mem_reserve so that it keeps bank order.
Also make its return code more traditional.
Signed-off-by: default avatarMax Filippov <jcmvbkbc@gmail.com>
parent 9d4b52df
...@@ -462,7 +462,7 @@ void __init setup_arch(char **cmdline_p) ...@@ -462,7 +462,7 @@ void __init setup_arch(char **cmdline_p)
#ifdef CONFIG_BLK_DEV_INITRD #ifdef CONFIG_BLK_DEV_INITRD
if (initrd_start < initrd_end) { if (initrd_start < initrd_end) {
initrd_is_mapped = mem_reserve(__pa(initrd_start), initrd_is_mapped = mem_reserve(__pa(initrd_start),
__pa(initrd_end), 0); __pa(initrd_end), 0) == 0;
initrd_below_start_ok = 1; initrd_below_start_ok = 1;
} else { } else {
initrd_start = 0; initrd_start = 0;
......
...@@ -142,6 +142,8 @@ int __init add_sysmem_bank(unsigned long start, unsigned long end) ...@@ -142,6 +142,8 @@ int __init add_sysmem_bank(unsigned long start, unsigned long end)
* mem_reserve(start, end, must_exist) * mem_reserve(start, end, must_exist)
* *
* Reserve some memory from the memory pool. * Reserve some memory from the memory pool.
* If must_exist is set and a part of the region being reserved does not exist
* memory map is not altered.
* *
* Parameters: * Parameters:
* start Start of region, * start Start of region,
...@@ -149,53 +151,69 @@ int __init add_sysmem_bank(unsigned long start, unsigned long end) ...@@ -149,53 +151,69 @@ int __init add_sysmem_bank(unsigned long start, unsigned long end)
* must_exist Must exist in memory pool. * must_exist Must exist in memory pool.
* *
* Returns: * Returns:
* 0 (memory area couldn't be mapped) * 0 (success)
* -1 (success) * < 0 (error)
*/ */
int __init mem_reserve(unsigned long start, unsigned long end, int must_exist) int __init mem_reserve(unsigned long start, unsigned long end, int must_exist)
{ {
int i; struct meminfo *it;
struct meminfo *rm = NULL;
if (start == end) unsigned long sz;
return 0; unsigned long bank_sz = 0;
start = start & PAGE_MASK; start = start & PAGE_MASK;
end = PAGE_ALIGN(end); end = PAGE_ALIGN(end);
sz = end - start;
if (!sz)
return -EINVAL;
for (i = 0; i < sysmem.nr_banks; i++) it = find_bank(start);
if (start < sysmem.bank[i].end
&& end >= sysmem.bank[i].start)
break;
if (i == sysmem.nr_banks) { if (it)
if (must_exist) bank_sz = it->end - it->start;
printk (KERN_WARNING "mem_reserve: [0x%0lx, 0x%0lx) "
"not in any region!\n", start, end); if ((!it || end - it->start > bank_sz) && must_exist) {
return 0; pr_warn("mem_reserve: [0x%0lx, 0x%0lx) not in any region!\n",
start, end);
return -EINVAL;
} }
if (start > sysmem.bank[i].start) { if (it && start - it->start < bank_sz) {
if (end < sysmem.bank[i].end) { if (start == it->start) {
/* split entry */ if (end - it->start < bank_sz) {
if (sysmem.nr_banks >= SYSMEM_BANKS_MAX) it->start = end;
panic("meminfo overflow\n"); return 0;
sysmem.bank[sysmem.nr_banks].start = end; } else {
sysmem.bank[sysmem.nr_banks].end = sysmem.bank[i].end; rm = it;
sysmem.nr_banks++; }
} else {
it->end = start;
if (end - it->start < bank_sz)
return add_sysmem_bank(end,
it->start + bank_sz);
++it;
}
} }
sysmem.bank[i].end = start;
} else if (end < sysmem.bank[i].end) { if (!it)
sysmem.bank[i].start = end; it = sysmem.bank;
for (; it < sysmem.bank + sysmem.nr_banks; ++it) {
if (it->end - start <= sz) {
if (!rm)
rm = it;
} else { } else {
/* remove entry */ if (it->start - start < sz)
sysmem.nr_banks--; it->start = end;
sysmem.bank[i].start = sysmem.bank[sysmem.nr_banks].start; break;
sysmem.bank[i].end = sysmem.bank[sysmem.nr_banks].end; }
} }
return -1;
if (rm)
move_banks(rm, it);
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