[RESEND] Question: Whether a bank must be fully contained by a section?
From: Wang Nan <hidden>
Date: 2014-01-03 05:10:05
Subsystem:
arm port, the rest · Maintainers:
Russell King, Linus Torvalds
I have sent this question to linux-kernel at vger.kernel.org, but receive
no answer. I think these should be a better place to discuss this
question. Apologies if you got multiple copies of this email.
=========
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 <redacted> 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 <redacted> --- 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