From: Kumar Gala <hidden> Date: 2008-01-09 17:30:43
There were several issues if a memreserve range existed and happened
to be in highmem:
* The bootmem allocator is only aware of lowmem so calling
reserve_bootmem with a highmem address would cause a BUG_ON
* All highmem pages were provided to the buddy allocator
Added a lmb_is_reserved() api that we now use to determine if a highem
page should continue to be PageReserved or provided to the buddy
allocator.
Also, we incorrectly reported the amount of pages reserved since all
highmem pages are initally marked reserved and we clear the
PageReserved flag as we "free" up the highmem pages.
---
As normal, posted here for review, will be pushed via my for-2.6.25 branch
arch/powerpc/mm/lmb.c | 13 +++++++++++++
arch/powerpc/mm/mem.c | 14 ++++++++++----
include/asm-powerpc/lmb.h | 1 +
3 files changed, 24 insertions(+), 4 deletions(-)
@@ -218,9 +218,13 @@ void __init do_init_bootmem(void)#endif/* reserve the sections we're already using */-for(i=0;i<lmb.reserved.cnt;i++)-reserve_bootmem(lmb.reserved.region[i].base,-lmb_size_bytes(&lmb.reserved,i));+for(i=0;i<lmb.reserved.cnt;i++){+unsignedlongaddr=lmb.reserved.region[i].base++lmb_size_bytes(&lmb.reserved,i)-1;+if(addr<total_lowmem)+reserve_bootmem(lmb.reserved.region[i].base,+lmb_size_bytes(&lmb.reserved,i));+}/* XXX need to clip this if using highmem? */sparse_memory_present_with_active_regions(0);
From: Kumar Gala <hidden> Date: 2008-01-09 19:41:23
On Jan 9, 2008, at 1:30 PM, Scott Wood wrote:
Kumar Gala wrote:
quoted
On Jan 9, 2008, at 12:53 PM, Scott Wood wrote:
quoted
It looks like if the reserved area straddles the highmem boundary,
it'll
only reserve the highmem portion.
Yeah, I thought about that. I'm wondering if we should warn about
this.. its seems like a bad thing to do.
How is the firmware supposed to know where Linux sets its lowmem
limit? I think this is something that needs to be handled.
Yeah I agree with that as well.
I'm thinking I'll add something like:
if (addr < total_lowmem)
reserve_bootmem(lmb.reserved.region[i].base,
lmb_size_bytes(&lmb.reserved,
i));
+ else if (lmb.reserved.region[i].base > total_lowmem) {
+ unsigned long adjusted_size;
+// adjusted_size = xxx;
need to figure out the math here.
+ reserve_bootmem(lmb.reserved.region[i].base,
+ adjusted_size);
+ }
that should solve the problem.
- k