linux-mips
[Top] [All Lists]

[PATCH] MIPS: fix pfn_valid() for FLAGMEM

To: linux-mips@linux-mips.org
Subject: [PATCH] MIPS: fix pfn_valid() for FLAGMEM
From: Wu Zhangjin <wuzhangjin@gmail.com>
Date: Thu, 8 Oct 2009 16:57:32 +0800
Cc: Ralf Baechle <ralf@linux-mips.org>, "Rafael J. Wysocki" <rjw@sisk.pl>, Pavel Machek <pavel@ucw.cz>, Wu Zhangjin <wuzhangjin@gmail.com>
Dkim-signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:received:received:from:to:cc:subject:date :message-id:x-mailer; bh=19uObl8u6Ic9ybGnHoNv5fxvphHKJoqXJsGsR50ATzU=; b=kAwTXKmKQZu1H3sSiqApeR7++5YYHIec4j/mJQ01ia6Jv1RQXsNPUF0Mf99MgfaA4Z ODkVW6QiH8A8mNLwHGjJt1mwXd2SLMLaLNmfQm907ZjNEsEZQYKbtKJceiKXodC1cWwt OcMjVKHqmKfCKShkVyNXC+BUStNA/dx9ciUkM=
Domainkey-signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=from:to:cc:subject:date:message-id:x-mailer; b=JTPjIfpjpevbVVnOPiO5GfnAJh9s5ZF9hg1uaZ1xKt6HyyxCGaEqOV8qAfaVzsAVRg vi8hSRKSxQa730ZjBi7tPXeSCb6sKGMBx1pS0+LyCHqMGIDzfjSNMEuNgH38lwciks2Z ATvuWbUO5xdz1h4AChakAk5+xM5KBgYerANjg=
Original-recipient: rfc822;linux-mips@linux-mips.org
Sender: linux-mips-bounce@linux-mips.org
When CONFIG_FLAGMEM enabled, STD/Hiberation will fail on YeeLoong
laptop, This patch fix it:

if pfn is between min_low_pfn and max_mapnr, the old pfn_valid() will
return TRUE, but in reality, if the memory is not continuous, it should
be false. for example:

$ cat /proc/iomem | grep "System RAM"
00000000-0fffffff : System RAM
90000000-bfffffff : System RAM

as we can see, it is not continuous, so, some of the memory is not valid
but regarded as valid by pfn_valid(), and at last make STD/Hibernate
fail when shrinking a too large number of invalid memory.

Here, we fix it via checking pfn is in the "System RAM" or not, if yes,
return TRUE.

Signed-off-by: Wu Zhangjin <wuzhangjin@gmail.com>
---
 arch/mips/include/asm/page.h |   11 ++++-------
 arch/mips/mm/page.c          |   17 +++++++++++++++++
 2 files changed, 21 insertions(+), 7 deletions(-)

diff --git a/arch/mips/include/asm/page.h b/arch/mips/include/asm/page.h
index f266295..16903a6 100644
--- a/arch/mips/include/asm/page.h
+++ b/arch/mips/include/asm/page.h
@@ -168,13 +168,10 @@ typedef struct { unsigned long pgprot; } pgprot_t;
 
 #ifdef CONFIG_FLATMEM
 
-#define pfn_valid(pfn)                                                 \
-({                                                                     \
-       unsigned long __pfn = (pfn);                                    \
-       /* avoid <linux/bootmem.h> include hell */                      \
-       extern unsigned long min_low_pfn;                               \
-                                                                       \
-       __pfn >= min_low_pfn && __pfn < max_mapnr;                      \
+#define pfn_valid(pfn)                         \
+({                                             \
+       extern int is_pfn_valid(unsigned long); \
+       is_pfn_valid(pfn);                      \
 })
 
 #elif defined(CONFIG_SPARSEMEM)
diff --git a/arch/mips/mm/page.c b/arch/mips/mm/page.c
index f5c7375..48a4d2a 100644
--- a/arch/mips/mm/page.c
+++ b/arch/mips/mm/page.c
@@ -689,3 +689,20 @@ void copy_page(void *to, void *from)
 }
 
 #endif /* CONFIG_SIBYTE_DMA_PAGEOPS */
+
+#ifdef CONFIG_FLATMEM
+int is_pfn_valid(unsigned long pfn)
+{
+       int i;
+
+       for (i = 0; i < boot_mem_map.nr_map; i++) {
+               if (boot_mem_map.map[i].type == BOOT_MEM_RAM) {
+                       if ((pfn >= PFN_DOWN(boot_mem_map.map[i].addr)) &&
+                               ((pfn) <= (PFN_UP(boot_mem_map.map[i].addr +
+                                       boot_mem_map.map[i].size))))
+                               return 1;
+               }
+       }
+       return 0;
+}
+#endif
-- 
1.6.2.1


<Prev in Thread] Current Thread [Next in Thread>