[POWERPC] Mark pages that don't exist as nosave
authorJohannes Berg <johannes@sipsolutions.net>
Tue, 8 May 2007 09:25:00 +0000 (19:25 +1000)
committerPaul Mackerras <paulus@samba.org>
Wed, 9 May 2007 06:34:56 +0000 (16:34 +1000)
On some powerpc architectures (notably 64-bit powermac) there is a memory
hole, for example on powermacs between 2G and 4G. Since we use the flat
memory model regardless, these pages must be marked as nosave (for suspend
to disk.)

Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Signed-off-by: Paul Mackerras <paulus@samba.org>
arch/powerpc/mm/mem.c

index 1a6e08f3298f8fa9ccc00910ab97a551136f9577..246eeea40ecec4ba0e5884fe114508bcab70dad9 100644 (file)
@@ -31,6 +31,7 @@
 #include <linux/highmem.h>
 #include <linux/initrd.h>
 #include <linux/pagemap.h>
+#include <linux/suspend.h>
 
 #include <asm/pgalloc.h>
 #include <asm/prom.h>
@@ -276,6 +277,28 @@ void __init do_init_bootmem(void)
        init_bootmem_done = 1;
 }
 
+/* mark pages that don't exist as nosave */
+static int __init mark_nonram_nosave(void)
+{
+       unsigned long lmb_next_region_start_pfn,
+                     lmb_region_max_pfn;
+       int i;
+
+       for (i = 0; i < lmb.memory.cnt - 1; i++) {
+               lmb_region_max_pfn =
+                       (lmb.memory.region[i].base >> PAGE_SHIFT) +
+                       (lmb.memory.region[i].size >> PAGE_SHIFT);
+               lmb_next_region_start_pfn =
+                       lmb.memory.region[i+1].base >> PAGE_SHIFT;
+
+               if (lmb_region_max_pfn < lmb_next_region_start_pfn)
+                       register_nosave_region(lmb_region_max_pfn,
+                                              lmb_next_region_start_pfn);
+       }
+
+       return 0;
+}
+
 /*
  * paging_init() sets up the page tables - in fact we've already done this.
  */
@@ -307,6 +330,8 @@ void __init paging_init(void)
        max_zone_pfns[ZONE_DMA] = top_of_ram >> PAGE_SHIFT;
 #endif
        free_area_init_nodes(max_zone_pfns);
+
+       mark_nonram_nosave();
 }
 #endif /* ! CONFIG_NEED_MULTIPLE_NODES */