Hi Russell,

By reading the code of show_mem(), I found that there is an assumption
that the page structs must be continuous for each bank:

        for_each_bank (i, mi) {
                ...
                page = pfn_to_page(pfn1);
                end  = pfn_to_page(pfn2 - 1) + 1;
        
                do {
                        ...
                        page++;  <-- pageframe must be continuous
                        ...
                } while (page < end);
                ...
        }

Therefore, a bank must be fully contained in a section in sparse memory
mode, because page frames are allocated section by section (in
sparse_init()).

However, I didn't find other code which enforces this assumption.
Instead, in arm_memory_present (arch/arm/mm/init.c), it seems that a
bank may contain more than one section:

arm_memory_present:
        ...
        for_each_memblock(memory, reg)
                memory_present(0, memblock_region_memory_base_pfn(reg),
                               memblock_region_memory_end_pfn(reg));
        ...

memory_present:
        ...
        for (pfn = start; pfn < end; pfn += PAGES_PER_SECTION) {
                ...
        }
        ...


Therefore, would you please consider the following patch, which removes
the assumption that a bank must be fully contained in one section?


===========================


>From b2c4bb5807c755d92274e11bb00cc548fea62242 Mon Sep 17 00:00:00 2001
From: Wang Nan <wangn...@huawei.com>
Date: Thu, 2 Jan 2014 13:20:02 +0800
Subject: [PATCH] use pfn_to_page in show_mem

If a bank spans into different sections, the page structures of the bank
may not continous.

This patch uses pfn_to_page to recompute the address of struct page in show_mem
from pfn, makes it to collect correct information even if a bank spans into
different sections.

Signed-off-by: Wang Nan <wangn...@huawei.com>
---
 arch/arm/mm/init.c | 16 +++++++---------
 1 file changed, 7 insertions(+), 9 deletions(-)

diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c
index 1f7b19a..3078e5a 100644
--- a/arch/arm/mm/init.c
+++ b/arch/arm/mm/init.c
@@ -97,16 +97,14 @@ void show_mem(unsigned int filter)

        for_each_bank (i, mi) {
                struct membank *bank = &mi->bank[i];
-               unsigned int pfn1, pfn2;
-               struct page *page, *end;
+               unsigned int pfn, pfn_end;
+               struct page *page;

-               pfn1 = bank_pfn_start(bank);
-               pfn2 = bank_pfn_end(bank);
-
-               page = pfn_to_page(pfn1);
-               end  = pfn_to_page(pfn2 - 1) + 1;
+               pfn = bank_pfn_start(bank);
+               pfn_end = bank_pfn_end(bank);

                do {
+                       page = pfn_to_page(pfn);
                        total++;
                        if (PageReserved(page))
                                reserved++;
@@ -118,8 +116,8 @@ void show_mem(unsigned int filter)
                                free++;
                        else
                                shared += page_count(page) - 1;
-                       page++;
-               } while (page < end);
+                       pfn++;
+               } while (pfn < pfn_end);
        }

        printk("%d pages of RAM\n", total);
-- 
1.8.4





--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to