Hi.

On Fri, 2005-03-04 at 22:04, Pavel Machek wrote:
> Hi!
> 
> > > IIRC kernel code/data is marked as PageReserved(), that's why we need
> > > to save that :(. Not sure what to do with data e820 marked as
> > > reserved...
> > 
> > Perhaps we need another page flag, like PG_readonly, and mark the pages
> > reserved by the e820 as PG_reserved | PG_readonly (the same for the areas
> > that are not returned by e820 at all).  Would that be acceptable?
> 
> This flags are little in the short supply, but being able to tell
> kernel code from memory hole seems like "must have", so yes, that
> looks ok.
> 
> You could get subtle and reuse some other pageflag. I do not think
> PG_reserved can have PG_locked... So using for example PG_locked for
> this purpose should be okay.

Will something like this patch help?

Regards,

Nigel

diff -ruNp 208-e820-table-support-old/arch/i386/mm/init.c 
208-e820-table-support-new/arch/i386/mm/init.c
--- 208-e820-table-support-old/arch/i386/mm/init.c      2005-01-12 
17:06:58.481035848 +1100
+++ 208-e820-table-support-new/arch/i386/mm/init.c      2005-01-12 
17:22:55.414559840 +1100
@@ -27,6 +27,7 @@
 #include <linux/slab.h>
 #include <linux/proc_fs.h>
 #include <linux/efi.h>
+#include <linux/suspend.h>
 
 #include <asm/processor.h>
 #include <asm/system.h>
@@ -272,12 +273,15 @@ void __init one_highpage_init(struct pag
 {
        if (page_is_ram(pfn) && !(bad_ppro && page_kills_ppro(pfn))) {
                ClearPageReserved(page);
+               ClearPageNosave(page);
                set_bit(PG_highmem, &page->flags);
                set_page_count(page, 1);
                __free_page(page);
                totalhigh_pages++;
-       } else
+       } else {
                SetPageReserved(page);
+               SetPageNosave(page);
+       }
 }
 
 #ifndef CONFIG_DISCONTIGMEM
@@ -355,7 +359,7 @@ static void __init pagetable_init (void)
 #endif
 }
 
-#if defined(CONFIG_PM_DISK) || defined(CONFIG_SOFTWARE_SUSPEND)
+#ifdef CONFIG_PM
 /*
  * Swap suspend & friends need this for resume because things like the 
intel-agp
  * driver might have split up a kernel 4MB mapping.
@@ -571,6 +575,7 @@ void __init mem_init(void)
        int codesize, reservedpages, datasize, initsize;
        int tmp;
        int bad_ppro;
+       void * addr;
 
 #ifndef CONFIG_DISCONTIGMEM
        if (!mem_map)
@@ -601,12 +606,25 @@ void __init mem_init(void)
        totalram_pages += __free_all_bootmem();
 
        reservedpages = 0;
-       for (tmp = 0; tmp < max_low_pfn; tmp++)
-               /*
-                * Only count reserved RAM pages
-                */
-               if (page_is_ram(tmp) && PageReserved(pfn_to_page(tmp)))
-                       reservedpages++;
+       addr = __va(0);
+       for (tmp = 0; tmp < max_low_pfn; tmp++, addr += PAGE_SIZE) {
+               if (page_is_ram(tmp)) {
+                       /*
+                        * Only count reserved RAM pages
+                        */
+                       if (PageReserved(mem_map+tmp))
+                               reservedpages++;
+                       /*
+                        * Mark nosave pages
+                        */
+                       if (addr >= (void *)&__nosave_begin && addr < (void 
*)&__nosave_end)
+                               SetPageNosave(mem_map+tmp);
+               } else
+                       /*
+                        * Non-RAM pages are always nosave
+                        */
+                       SetPageNosave(mem_map+tmp);
+       }
 
        set_highmem_pages_init(bad_ppro);
 
@@ -705,6 +723,7 @@ void free_initmem(void)
        addr = (unsigned long)(&__init_begin);
        for (; addr < (unsigned long)(&__init_end); addr += PAGE_SIZE) {
                ClearPageReserved(virt_to_page(addr));
+               ClearPageNosave(virt_to_page(addr));
                set_page_count(virt_to_page(addr), 1);
                memset((void *)addr, 0xcc, PAGE_SIZE);
                free_page(addr);
@@ -720,6 +739,7 @@ void free_initrd_mem(unsigned long start
                printk (KERN_INFO "Freeing initrd memory: %ldk freed\n", (end - 
start) >> 10);
        for (; start < end; start += PAGE_SIZE) {
                ClearPageReserved(virt_to_page(start));
+               ClearPageNosave(virt_to_page(start));
                set_page_count(virt_to_page(start), 1);
                free_page(start);
                totalram_pages++;
diff -ruNp 208-e820-table-support-old/mm/bootmem.c 
208-e820-table-support-new/mm/bootmem.c
--- 208-e820-table-support-old/mm/bootmem.c     2005-01-12 17:07:15.902387400 
+1100
+++ 208-e820-table-support-new/mm/bootmem.c     2005-01-12 17:23:44.087160480 
+1100
@@ -280,12 +280,14 @@ static unsigned long __init free_all_boo
 
                        count += BITS_PER_LONG;
                        __ClearPageReserved(page);
+                       ClearPageNosave(page);
                        order = ffs(BITS_PER_LONG) - 1;
                        set_page_refs(page, order);
                        for (j = 1; j < BITS_PER_LONG; j++) {
                                if (j + 16 < BITS_PER_LONG)
                                        prefetchw(page + j + 16);
                                __ClearPageReserved(page + j);
+                               ClearPageNosave(page + j);
                        }
                        __free_pages(page, order);
                        i += BITS_PER_LONG;
@@ -296,6 +298,7 @@ static unsigned long __init free_all_boo
                                if (v & m) {
                                        count++;
                                        __ClearPageReserved(page);
+                                       ClearPageNosave(page);
                                        set_page_refs(page, 0);
                                        __free_page(page);
                                }
@@ -316,6 +319,7 @@ static unsigned long __init free_all_boo
        for (i = 0; i < ((bdata->node_low_pfn-(bdata->node_boot_start >> 
PAGE_SHIFT))/8 + PAGE_SIZE-1)/PAGE_SIZE; i++,page++) {
                count++;
                __ClearPageReserved(page);
+               ClearPageNosave(page);
                set_page_count(page, 1);
                __free_page(page);
        }

-- 
Nigel Cunningham
Software Engineer
Cyclades Corporation

http://cyclades.com

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to