On Tuesday, 1 November 2016 00:40:29 GMT James Hogan wrote: > When low memory doesn't reach HIGHMEM_START (e.g. up to 256MB at PA=0 is > common) and highmem is present above HIGHMEM_START (e.g. on Malta the > RAM overlayed by the IO region is aliased at PA=0x90000000), max_low_pfn > will be initially calculated very large and then clipped down to > HIGHMEM_START. > > This causes crashes when reading /sys/kernel/mm/page_idle/bitmap > (i.e. CONFIG_IDLE_PAGE_TRACKING=y) when highmem is disabled. pfn_valid() > will compare against max_mapnr which is derived from max_low_pfn when > there is no highend_pfn set up, and will return true for PFNs right up > to HIGHMEM_START, even though they are beyond the end of low memory and > no page structs will actually exist for these PFNs. > > This is fixed by skipping high memory regions when initially calculating > max_low_pfn if highmem is disabled, so it doesn't get clipped too high. > > Signed-off-by: James Hogan <james.hogan@xxxxxxxxxx> > Cc: Ralf Baechle <ralf@xxxxxxxxxxxxxx> > Cc: linux-mips@xxxxxxxxxxxxxx > --- > arch/mips/kernel/setup.c | 9 +++++++++ > 1 file changed, 9 insertions(+), 0 deletions(-) > > diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c > index 0d57909d9026..cb6e5895bb7e 100644 > --- a/arch/mips/kernel/setup.c > +++ b/arch/mips/kernel/setup.c > @@ -368,6 +368,15 @@ static void __init bootmem_init(void) > end = PFN_DOWN(boot_mem_map.map[i].addr > + boot_mem_map.map[i].size); > > +#ifndef CONFIG_HIGHMEM > + /* > + * Skip highmem here so we get an accurate max_low_pfn if low > + * memory stops short of high memory. > + */ > + if (start >= PFN_DOWN(HIGHMEM_START)) > + continue; > +#endif > + > if (end > max_low_pfn) > max_low_pfn = end; > if (start < min_low_pfn) Hi James, Shouldn't this also clip any region which crosses the boundary from lowmem to highmem? (ie. start < PFN_DOWN(HIGHMEM_START) < end) Thanks, Paul
Attachment:
signature.asc
Description: This is a digitally signed message part.