The patch titled swsusp: try to handle holes better has been added to the -mm tree. Its filename is swsusp-try-to-handle-holes-better.patch See http://www.zip.com.au/~akpm/linux/patches/stuff/added-to-mm.txt to find out what to do about this ------------------------------------------------------ Subject: swsusp: try to handle holes better From: "Rafael J. Wysocki" <rjw@xxxxxxx> However, on my box it only detects one nosave region which is between 0xa0000 and 0xe0000 and swsusp seems to omit this region as expected (eg. it doesn't "restore" the VGA memory ;-) ). Andrew, could you please see what happens during suspend on your 4 GB box with this patch applied? Theoretically it should fix the memory shrinker problem which I think occurs because there's a huge gap between the last two continuous RAM regions on this box and without the patch this gap is treated as an area of saveable memory. However, I'm not sure if it fixes the oops - this depends on whether the address ranges corresponding to non-RAM e820 entreis have valid virtual addresses in the kernel identity mapping. If not, it would oops on a different address than before. Besides the patch only makes swsusp aviod explicit memory gaps, but I'm not quite sure if some other non-RAM e820 areas should be saved. If not, there may be some problems during or after resume. Cc: Mel Gorman <mel@xxxxxxxxx> Cc: Pavel Machek <pavel@xxxxxx> Signed-off-by: Andrew Morton <akpm@xxxxxxxx> --- arch/x86_64/kernel/e820.c | 45 +++++++++++++++++++++++++++++++++++ arch/x86_64/kernel/setup.c | 1 include/asm-x86_64/e820.h | 1 3 files changed, 47 insertions(+) diff -puN arch/x86_64/kernel/e820.c~swsusp-try-to-handle-holes-better arch/x86_64/kernel/e820.c --- a/arch/x86_64/kernel/e820.c~swsusp-try-to-handle-holes-better +++ a/arch/x86_64/kernel/e820.c @@ -16,6 +16,7 @@ #include <linux/string.h> #include <linux/kexec.h> #include <linux/module.h> +#include <linux/mm.h> #include <asm/pgtable.h> #include <asm/page.h> @@ -293,6 +294,50 @@ void __init e820_reserve_resources(void) } } +/* Mark pages corresponding to given address range as nosave */ +static void __init +e820_mark_nosave_range(unsigned long start, unsigned long end) +{ + unsigned long pfn, max_pfn; + + printk(" Nosave address range: %016lx - %016lx\n", start, end); + max_pfn = end >> PAGE_SHIFT; + for (pfn = start >> PAGE_SHIFT; pfn < max_pfn; pfn++) + if(pfn_valid(pfn)) + SetPageNosave(pfn_to_page(pfn)); +} + +/* + * Find the ranges of physical addresses that do not correspond to + * e820 RAM areas and mark the corresponding pages as nosave for software + * suspend and suspend to RAM. + * + * This function requires the e820 map to be sorted and without any + * overlapping entries and assumes the first e820 area to be RAM. + */ +void __init e820_mark_nosave_regions(void) +{ + int i; + unsigned long paddr; + + paddr = e820.map[0].addr + e820.map[0].size; + for (i = 1; i < e820.nr_map; i++) { + struct e820entry *ei = &e820.map[i]; + + if (paddr < ei->addr) + e820_mark_nosave_range(round_down(paddr, PAGE_SIZE), + round_up(ei->addr, PAGE_SIZE)); + + if (ei->type != E820_RAM) + e820_mark_nosave_range(round_up(ei->addr, PAGE_SIZE), + round_down(ei->addr + ei->size, PAGE_SIZE)); + + paddr = ei->addr + ei->size; + if (paddr >= (end_pfn << PAGE_SHIFT)) + break; + } +} + /* * Add a memory region to the kernel e820 map. */ diff -puN arch/x86_64/kernel/setup.c~swsusp-try-to-handle-holes-better arch/x86_64/kernel/setup.c --- a/arch/x86_64/kernel/setup.c~swsusp-try-to-handle-holes-better +++ a/arch/x86_64/kernel/setup.c @@ -678,6 +678,7 @@ void __init setup_arch(char **cmdline_p) */ probe_roms(); e820_reserve_resources(); + e820_mark_nosave_regions(); request_resource(&iomem_resource, &video_ram_resource); diff -puN include/asm-x86_64/e820.h~swsusp-try-to-handle-holes-better include/asm-x86_64/e820.h --- a/include/asm-x86_64/e820.h~swsusp-try-to-handle-holes-better +++ a/include/asm-x86_64/e820.h @@ -46,6 +46,7 @@ extern void setup_memory_region(void); extern void contig_e820_setup(void); extern unsigned long e820_end_of_ram(void); extern void e820_reserve_resources(void); +extern void e820_mark_nosave_regions(void); extern void e820_print_map(char *who); extern int e820_any_mapped(unsigned long start, unsigned long end, unsigned type); extern int e820_all_mapped(unsigned long start, unsigned long end, unsigned type); _ Patches currently in -mm which might be from rjw@xxxxxxx are pm-define-pm_event_prethaw.patch pm-pci-and-ide-handle-pm_event_prethaw.patch pm-video-drivers-and-pm_event_prethaw.patch pm-usb-hcds-use-pm_event_prethaw.patch pm-usb-hcds-use-pm_event_prethaw-fix.patch pm-issue-pm_event_prethaw.patch swsusp-write-timer.patch swsusp-write-speedup.patch swsusp-read-timer.patch swsusp-read-speedup.patch swsusp-read-speedup-fix.patch swsusp-read-speedup-cleanup.patch swsusp-read-speedup-cleanup-2.patch swsusp-clean-up-browsing-of-pfns.patch swsusp-struct-snapshot_handle-cleanup.patch swsusp-try-to-handle-holes-better.patch - To unsubscribe from this list: send the line "unsubscribe mm-commits" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html