Question: Whether a bank must be fully contained by a section?
PATCH RESEND 1/1 Question: Whether a bank must be fully contained by a section?
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?
===========================
Quoted 1 line
From
b2c4bb5807c755d92274e11bb00cc548fea62242Mon Sep 17 00:00:00 2001
From: Wang Nan <[email protected]>
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.
--- arch/arm/mm/init.c | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-)
arch/arm/mm/init.c +7 -9
@@ -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);
Signature · 1 line
1.8.4