Hi Mathieu,
On 01.09.2017 09:53, Mathieu Malaterre wrote:
So that patch from did cause issues here - it turns out this is a memory
layout that unfortunately I haven't tested the patch with.
I have slightly limited debugging options on the ci20 board I'm using,
but what I think is happening here is that due to this patch, all of the
memory range below 0x30000000 is marked as reserved, which is obviously
incorrect and results in eg. a failure to allocate a memory block for
DMA (and potentially some other resource allocations as well).
The intention of 73fbc1eba7ff was to protect memory below the start of
RAM, but it didn't properly account for holes in the memory. I believe
the following patch should restore the intended behaviour.
diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c
index fe39397..a1c39ec 100644
--- a/arch/mips/kernel/setup.c
+++ b/arch/mips/kernel/setup.c
@@ -374,6 +374,7 @@ static void __init bootmem_init(void)
unsigned long reserved_end;
unsigned long mapstart = ~0UL;
unsigned long bootmap_size;
+ phys_addr_t ramstart = ~0UL;
bool bootmap_valid = false;
int i;
@@ -394,6 +395,21 @@ static void __init bootmem_init(void)
max_low_pfn = 0;
/*
+ * Reserve any memory between the start of RAM and PHYS_OFFSET
+ */
+ for (i = 0; i < boot_mem_map.nr_map; i++) {
+ if (boot_mem_map.map[i].type != BOOT_MEM_RAM)
+ continue;
+
+ ramstart = min(ramstart, boot_mem_map.map[i].addr);
+ }
+
+ if (ramstart > PHYS_OFFSET)
+ add_memory_region(PHYS_OFFSET, ramstart - PHYS_OFFSET,
+ BOOT_MEM_RESERVED);
+
+
+ /*
* Find the highest page frame number we have available.
*/
for (i = 0; i < boot_mem_map.nr_map; i++) {
@@ -663,9 +679,6 @@ static int __init early_parse_mem(char *p)
add_memory_region(start, size, BOOT_MEM_RAM);
- if (start && start > PHYS_OFFSET)
- add_memory_region(PHYS_OFFSET, start - PHYS_OFFSET,
- BOOT_MEM_RESERVED);
return 0;
}
early_param("mem", early_parse_mem);
It also makes sure that the region is protected as expected when the
memory offset is set through device tree, unlike in the original case
which only catered for the bootparam case (although I'm not sure how
likely this is to affect any real system - probably quite unlikely).
Moreover, since the memory ranges are defined in the devicetree I don't
think it is necessary at all to pass mem=... on the ci20. I suspect that
it may have been required on some older kernels and just remains as a
default in the bootloader. So removing both mem=... arguments from the
commandline and not patching the kernel would also fix the problem
you're having.
I'll need to think a bit more about this patch and will send to the mips
mailing list for review/upstreaming.
Marcin