Messages in this thread |  | | Date | Fri, 24 Jul 2020 22:12:42 -0700 (PDT) | Subject | Re: [PATCH 4/4] riscv: Parse all memory blocks to remove unusable memory | From | Palmer Dabbelt <> |
| |
On Wed, 15 Jul 2020 16:30:09 PDT (-0700), Atish Patra wrote: > Currently, maximum physical memory allowed is equal to -PAGE_OFFSET. > That's why we remove any memory blocks spanning beyond that size. However, > it is done only for memblock containing linux kernel which will not work > if there are multiple memblocks. > > Process all memory blocks to figure out how much memory needs to be removed > and remove at the end instead of updating the memblock list in place. > > Signed-off-by: Atish Patra <atish.patra@wdc.com> > --- > arch/riscv/mm/init.c | 31 +++++++++++++++++-------------- > 1 file changed, 17 insertions(+), 14 deletions(-) > > diff --git a/arch/riscv/mm/init.c b/arch/riscv/mm/init.c > index f818a47a72d1..79e9d55bdf1a 100644 > --- a/arch/riscv/mm/init.c > +++ b/arch/riscv/mm/init.c > @@ -147,26 +147,29 @@ void __init setup_bootmem(void) > { > struct memblock_region *reg; > phys_addr_t mem_size = 0; > + phys_addr_t total_mem = 0; > + phys_addr_t mem_start, end = 0; > phys_addr_t vmlinux_end = __pa_symbol(&_end); > phys_addr_t vmlinux_start = __pa_symbol(&_start); > > /* Find the memory region containing the kernel */ > for_each_memblock(memory, reg) { > - phys_addr_t end = reg->base + reg->size; > - > - if (reg->base <= vmlinux_start && vmlinux_end <= end) { > - mem_size = min(reg->size, (phys_addr_t)-PAGE_OFFSET); > - > - /* > - * Remove memblock from the end of usable area to the > - * end of region > - */ > - if (reg->base + mem_size < end) > - memblock_remove(reg->base + mem_size, > - end - reg->base - mem_size); > - } > + end = reg->base + reg->size; > + if (!total_mem) > + mem_start = reg->base; > + if (reg->base <= vmlinux_start && vmlinux_end <= end) > + BUG_ON(reg->size == 0); > + total_mem = total_mem + reg->size; > } > - BUG_ON(mem_size == 0); > + > + /* > + * Remove memblock from the end of usable area to the > + * end of region > + */ > + mem_size = min(total_mem, (phys_addr_t)-PAGE_OFFSET); > + if (mem_start + mem_size < end) > + memblock_remove(mem_start + mem_size, > + end - mem_start - mem_size); > > /* Reserve from the start of the kernel to the end of the kernel */ > memblock_reserve(vmlinux_start, vmlinux_end - vmlinux_start);
Thanks, this one is also on fixes.
|  |