public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* swsusp with highmem, testing wanted
@ 2004-03-24 23:57 Pavel Machek
  2004-03-25  3:28 ` Benjamin Herrenschmidt
                   ` (3 more replies)
  0 siblings, 4 replies; 18+ messages in thread
From: Pavel Machek @ 2004-03-24 23:57 UTC (permalink / raw)
  To: kernel list; +Cc: seife

Hi!

If you have machine with >=1GB of RAM, do you think you could test
this patch? [I'd like to hear about successes, too; perhaps send it
privately].

							Pavel

--- clean.2.5/kernel/power/swsusp.c	2004-03-11 18:11:26.000000000 +0100
+++ linux-himem-swsusp/kernel/power/swsusp.c	2004-03-25 00:53:56.000000000 +0100
@@ -61,6 +61,7 @@
 #include <linux/bootmem.h>
 #include <linux/syscalls.h>
 #include <linux/console.h>
+#include <linux/highmem.h>
 
 #include <asm/uaccess.h>
 #include <asm/mmu_context.h>
@@ -362,7 +363,69 @@
 	return 0;
 }
 
+struct highmem_page {
+	char *data;
+	struct page *page;
+	struct highmem_page *next;
+};
+
+struct highmem_page *highmem_copy = NULL;
+
 /* if pagedir_p != NULL it also copies the counted pages */
+static int save_highmem(void)
+{
+	int pfn;
+	struct page *page;
+	int chunk_size;
+
+	for (pfn = 0; pfn < max_pfn; pfn++) {
+		struct highmem_page *save;
+		void *kaddr;
+
+		page = pfn_to_page(pfn);
+
+		if (!PageHighMem(page))
+			continue;
+		if (PageReserved(page)) {
+			printk("highmem reserved page?!\n");
+			BUG();
+		}
+		if ((chunk_size=is_head_of_free_region(page))!=0) {
+			pfn += chunk_size - 1;
+			continue;
+		}
+		save = kmalloc(sizeof(struct highmem_page), GFP_ATOMIC);
+		if (!save)
+			panic("Not enough memory");
+		save->next = highmem_copy;
+		save->page = page;
+		save->data = get_zeroed_page(GFP_ATOMIC);
+		if (!save->data)
+			panic("Not enough memory");
+		kaddr = kmap_atomic(page, KM_USER0);
+		memcpy(save->data, kaddr, PAGE_SIZE);
+		kunmap_atomic(kaddr, KM_USER0);
+		highmem_copy = save;
+	}
+	return 0;
+}
+
+static int restore_highmem(void)
+{
+	while (highmem_copy) {
+		struct highmem_page *save = highmem_copy;
+		void *kaddr;
+		highmem_copy = save->next;
+		
+		kaddr = kmap_atomic(save->page, KM_USER0);
+		memcpy(kaddr, save->data, PAGE_SIZE);
+		kunmap_atomic(kaddr, KM_USER0);
+		free_page(save->data);
+		kfree(save);
+	}
+	return 0;
+}
+
 static int count_and_copy_data_pages(struct pbe *pagedir_p)
 {
 	int chunk_size;
@@ -378,7 +441,7 @@
 	for (pfn = 0; pfn < max_pfn; pfn++) {
 		page = pfn_to_page(pfn);
 		if (PageHighMem(page))
-			panic("Swsusp not supported on highmem boxes. Send 1GB of RAM to <pavel@ucw.cz> and try again ;-).");
+			continue;
 
 		if (!PageReserved(page)) {
 			if (PageNosave(page))
@@ -413,6 +476,7 @@
 	return nr_copy_pages;
 }
 
+
 static void free_suspend_pagedir(unsigned long this_pagedir)
 {
 	struct page *page;
@@ -492,10 +556,12 @@
 	struct sysinfo i;
 	unsigned int nr_needed_pages = 0;
 
-	drain_local_pages();
-
 	pagedir_nosave = NULL;
-	printk( "/critical section: Counting pages to copy" );
+	printk( "/critical section: Handling highmem" );
+	save_highmem();
+
+	printk(", counting pages to copy" );
+	drain_local_pages();
 	nr_copy_pages = count_and_copy_data_pages(NULL);
 	nr_needed_pages = nr_copy_pages + PAGES_FOR_IO;
 	
@@ -603,6 +669,11 @@
 
 	PRINTK( "Freeing prev allocated pagedir\n" );
 	free_suspend_pagedir((unsigned long) pagedir_save);
+
+	printk( "Restoring highmem\n" );
+	restore_highmem();
+	printk("done, devices\n");
+
 	device_power_up();
 	spin_unlock_irq(&suspend_pagedir_lock);
 	device_resume();

-- 
When do you have a heart between your knees?
[Johanka's followup: and *two* hearts?]

^ permalink raw reply	[flat|nested] 18+ messages in thread

end of thread, other threads:[~2004-03-26 14:35 UTC | newest]

Thread overview: 18+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2004-03-24 23:57 swsusp with highmem, testing wanted Pavel Machek
2004-03-25  3:28 ` Benjamin Herrenschmidt
     [not found]   ` <20040325120250.GC300@elf.ucw.cz>
2004-03-25 22:41     ` Benjamin Herrenschmidt
2004-03-25 22:59       ` Pavel Machek
2004-03-25 22:44         ` Nigel Cunningham
2004-03-25 23:54           ` Pavel Machek
2004-03-25 23:06             ` Nigel Cunningham
2004-03-26  0:22         ` Benjamin Herrenschmidt
2004-03-25  3:48 ` Jeff Chua
     [not found] ` <20040325073244.GE3377@suse.de>
     [not found]   ` <20040325115129.GB300@elf.ucw.cz>
     [not found]     ` <20040325121418.GK3377@suse.de>
2004-03-25 15:01       ` Pavel Machek
2004-03-25 15:27         ` Jens Axboe
2004-03-25 22:22           ` Pavel Machek
2004-03-26 14:09             ` Jens Axboe
2004-03-26 14:34               ` Pavel Machek
     [not found] ` <20040325100339.GN791@holomorphy.com>
2004-03-25 21:59   ` Pavel Machek
2004-03-26 12:03     ` William Lee Irwin III
2004-03-26 12:08       ` Pavel Machek
2004-03-26 12:36         ` William Lee Irwin III

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox