[PATCH] ARM: Fix virtual kernel memory printing for sparsemem
Catalin Marinas
catalin.marinas at arm.com
Thu Mar 25 12:01:26 EDT 2010
On Thu, 2010-03-25 at 15:30 +0000, Russell King - ARM Linux wrote:
> On Thu, Mar 25, 2010 at 03:24:29PM +0000, Catalin Marinas wrote:
> > On Thu, 2010-03-25 at 15:10 +0000, Russell King - ARM Linux wrote:
> > > While this looks fine, I'd like to see a lot of Tested-by's against
> > > this before it's merged - we've had similar code in show_mem()
> > > which has proven to be quite problematical to get right for all the
> > > various different combinations we have.
> > >
> > > However, we also have the same method in show_mem() which we know
> > > works fine, so I'd also like to see the problem with using it in
> > > mem_init() fully analysed - rather than a "possibly because".
> >
> > I can remove the "possibly" part :). The page_count() is given a page
> > with some random flags and it thinks it's a compound page. It than tries
> > to access page->first which isn't set, hence the error.
> >
> > The original code assumes that for a given node the map is contiguous
> > and it calculates the page as (map + pfn). This is only true for
> > flatmem. With sparsemem the page calculation is a bit more complicated
> > but handled by pfn_to_page().
>
> And show_mem() ? It seems to suffer from the same problem.
And that's a patch which fixes both (but as you said, it would be good
if more people test it on various platforms).
ARM: Fix kernel memory printing for sparsemem
From: Catalin Marinas <catalin.marinas at arm.com>
The show_mem() and mem_init() function are assuming that the page map is
contiguous and calculates the start and end page of a bank using (map +
pfn). This fails with SPARSEMEM where pfn_to_page() must be used.
Signed-off-by: Catalin Marinas <catalin.marinas at arm.com>
Cc: Will Deacon <Will.Deacon at arm.com>
Cc: Andreas Fenkart <andreas.fenkart at streamunlimited.com>
---
arch/arm/mm/init.c | 14 ++++----------
1 files changed, 4 insertions(+), 10 deletions(-)
diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c
index b69ac3a..4ee740a 100644
--- a/arch/arm/mm/init.c
+++ b/arch/arm/mm/init.c
@@ -83,9 +83,6 @@ void show_mem(void)
printk("Mem-info:\n");
show_free_areas();
for_each_online_node(node) {
- pg_data_t *n = NODE_DATA(node);
- struct page *map = pgdat_page_nr(n, 0) - n->node_start_pfn;
-
for_each_nodebank (i,mi,node) {
struct membank *bank = &mi->bank[i];
unsigned int pfn1, pfn2;
@@ -94,8 +91,8 @@ void show_mem(void)
pfn1 = bank_pfn_start(bank);
pfn2 = bank_pfn_end(bank);
- page = map + pfn1;
- end = map + pfn2;
+ page = pfn_to_page(pfn1);
+ end = pfn_to_page(pfn2 - 1) + 1;
do {
total++;
@@ -600,9 +597,6 @@ void __init mem_init(void)
reserved_pages = free_pages = 0;
for_each_online_node(node) {
- pg_data_t *n = NODE_DATA(node);
- struct page *map = pgdat_page_nr(n, 0) - n->node_start_pfn;
-
for_each_nodebank(i, &meminfo, node) {
struct membank *bank = &meminfo.bank[i];
unsigned int pfn1, pfn2;
@@ -611,8 +605,8 @@ void __init mem_init(void)
pfn1 = bank_pfn_start(bank);
pfn2 = bank_pfn_end(bank);
- page = map + pfn1;
- end = map + pfn2;
+ page = pfn_to_page(pfn1);
+ end = pfn_to_page(pfn2 - 1) + 1;
do {
if (PageReserved(page))
--
Catalin
More information about the linux-arm-kernel
mailing list