diff -ruNp 613-pageflags.patch-old/kernel/power/suspend2_core/pageflags.c 613-pageflags.patch-new/kernel/power/suspend2_core/pageflags.c --- 613-pageflags.patch-old/kernel/power/suspend2_core/pageflags.c 1970-01-01 10:00:00.000000000 +1000 +++ 613-pageflags.patch-new/kernel/power/suspend2_core/pageflags.c 2005-07-04 23:14:19.000000000 +1000 @@ -0,0 +1,126 @@ +/* + * kernel/power/suspend2_core/pageflags.c + * + * Copyright (C) 2004-2005 Nigel Cunningham <[EMAIL PROTECTED]> + * + * This file is released under the GPLv2. + * + * Routines for dynamically allocating and releasing bitmaps + * used as pseudo-pageflags. + * + * Arrays are not contiguous. The first sizeof(void *) bytes are + * the pointer to the next page in the bitmap. This allows us to + * 1) work under low memory conditions where order 0 might be all + * that's available + * 2) save the pages at suspend time, reload and relocate them as + * necessary at resume time without breaking anything (cf + * extent pages). + */ + +#include <linux/kernel.h> +#include <linux/mm.h> +#include <linux/module.h> +#include <linux/bitops.h> +#include <linux/list.h> +#include <linux/suspend.h> +#include "pageflags.h" +#include "plugins.h" +#include "pagedir.h" + +/* Maps used in copying the image back are in builtin.c */ +dyn_pageflags_t pageset1_map; +dyn_pageflags_t pageset1_copy_map; +dyn_pageflags_t pageset2_map; +dyn_pageflags_t in_use_map; +dyn_pageflags_t allocd_pages_map; +#ifdef CONFIG_DEBUG_PAGEALLOC +dyn_pageflags_t unmap_map; +#endif + +/* suspend_allocate_dyn_pageflags + * + * Description: Allocate a bitmap for local page flags. + * Arguments: dyn_pageflags_t *: Pointer to the bitmap. + * + * A version of allocate_dyn_pageflags that saves us then having + * to relocate the flags when resuming. + */ +int suspend_allocate_dyn_pageflags(dyn_pageflags_t *pagemap) +{ + int i; + + BUG_ON(*pagemap); + + if (test_suspend_state(SUSPEND_NOW_RESUMING)) { + /* + * We use kfree unconditionally below. That's not a problem + * because we only use this path when reloading pageset1. + */ + *pagemap = (dyn_pageflags_t) suspend2_get_nonconflicting_page(); + if (! *pagemap) { + printk("Failed to allocate a non-conflicting page for pageflags.\n"); + return 1; + } + } else + *pagemap = kmalloc(sizeof(void *) * PAGES_PER_BITMAP, GFP_ATOMIC); + + for (i = 0; i < PAGES_PER_BITMAP; i++) { + (*pagemap)[i] = (unsigned long *) get_zeroed_page(GFP_ATOMIC); + if (!(*pagemap)[i]) { + printk("Error. Unable to allocate memory for " + "local page flags."); + free_dyn_pageflags(pagemap); + return 1; + } + } + return 0; +} + +/* savepageflags + * + * Description: Save a set of pageflags. + * Arguments: dyn_pageflags_t *: Pointer to the bitmap being saved. + */ + +void save_dyn_pageflags(dyn_pageflags_t pagemap) +{ + int i; + + if (!*pagemap) + return; + + for (i = 0; i < PAGES_PER_BITMAP; i++) + active_writer->ops.writer.write_header_chunk((char *) pagemap[i], PAGE_SIZE); +} + +/* loadpageflags + * + * Description: Load a set of pageflags. + * Arguments: dyn_pageflags_t *: Pointer to the bitmap being loaded. + * (It must be allocated before calling this routine). + */ + +void load_dyn_pageflags(dyn_pageflags_t pagemap) +{ + int i; + + if (!pagemap) + return; + + for (i = 0; i < PAGES_PER_BITMAP; i++) + active_writer->ops.writer.read_header_chunk((char *) pagemap[i], PAGE_SIZE); +} + +void relocate_dyn_pageflags(dyn_pageflags_t *pagemap) +{ + int i; + LIST_HEAD(rejected_pages); + + if (!*pagemap) + return; + + suspend2_relocate_page_if_required((void *) pagemap); + + for (i = 0; i < PAGES_PER_BITMAP; i++) + suspend2_relocate_page_if_required((void *) &((*pagemap)[i])); +} diff -ruNp 613-pageflags.patch-old/kernel/power/suspend2_core/pageflags.h 613-pageflags.patch-new/kernel/power/suspend2_core/pageflags.h --- 613-pageflags.patch-old/kernel/power/suspend2_core/pageflags.h 1970-01-01 10:00:00.000000000 +1000 +++ 613-pageflags.patch-new/kernel/power/suspend2_core/pageflags.h 2005-07-05 23:48:59.000000000 +1000 @@ -0,0 +1,84 @@ +/* + * kernel/power/pageflags.h + * + * Copyright (C) 2004-2005 Nigel Cunningham <[EMAIL PROTECTED]> + * + * This file is released under the GPLv2. + * + * Suspend2 needs a few pageflags while working that aren't otherwise + * used. To save the struct page pageflags, we dynamically allocate + * a bitmap and use that. These are the only non order-0 allocations + * we do. + * + * NOTE!!! + * We assume that PAGE_SIZE - sizeof(void *) is a multiple of + * sizeof(unsigned long). Is this ever false? + */ + +#include <linux/dyn_pageflags.h> +#include <linux/suspend.h> + +extern dyn_pageflags_t in_use_map; +extern dyn_pageflags_t allocd_pages_map; +#ifdef CONFIG_DEBUG_PAGEALLOC +extern dyn_pageflags_t unmap_map; +#endif +extern dyn_pageflags_t pageset2_map; + +/* + * inusemap is used in two ways: + * - During suspend, to tag pages which are not used (to speed up + * count_data_pages); + * - During resume, to tag pages which are in pagedir1. This does not tag + * pagedir2 pages, so !== first use. + */ +#define PageInUse(page) \ + test_bit(PAGEBIT(page), PAGE_UL_PTR(in_use_map, page)) +#define SetPageInUse(page) \ + set_bit(PAGEBIT(page), PAGE_UL_PTR(in_use_map, page)) +#define ClearPageInUse(page) \ + clear_bit(PAGEBIT(page), PAGE_UL_PTR(in_use_map, page)) + +#define PagePageset1(page) \ + (pageset1_map ? test_bit(PAGEBIT(page), PAGE_UL_PTR(pageset1_map, page)): 0) +#define SetPagePageset1(page) \ + set_bit(PAGEBIT(page), PAGE_UL_PTR(pageset1_map, page)) +#define ClearPagePageset1(page) \ + clear_bit(PAGEBIT(page), PAGE_UL_PTR(pageset1_map, page)) + +#define PagePageset1Copy(page) \ + (pageset1_copy_map ? \ + test_bit(PAGEBIT(page), PAGE_UL_PTR(pageset1_copy_map, page)): 0) +#define SetPagePageset1Copy(page) \ + set_bit(PAGEBIT(page), PAGE_UL_PTR(pageset1_copy_map, page)) +#define ClearPagePageset1Copy(page) \ + clear_bit(PAGEBIT(page), PAGE_UL_PTR(pageset1_copy_map, page)) + +#define PagePageset2(page) \ + (pageset2_map ? \ + test_bit(PAGEBIT(page), PAGE_UL_PTR(pageset2_map, page)): 0) +#define SetPagePageset2(page) \ + set_bit(PAGEBIT(page), PAGE_UL_PTR(pageset2_map, page)) +#define ClearPagePageset2(page) \ + clear_bit(PAGEBIT(page), PAGE_UL_PTR(pageset2_map, page)) + +#define PageAllocd(page) \ + test_bit(PAGEBIT(page), PAGE_UL_PTR(allocd_pages_map, page)) +#define SetPageAllocd(page) \ + set_bit(PAGEBIT(page), PAGE_UL_PTR(allocd_pages_map, page)) +#define ClearPageAllocd(page) \ + clear_bit(PAGEBIT(page), PAGE_UL_PTR(alloc_pages_map, page)) + +#define SetPageUnmap(page) \ + set_bit(PAGEBIT(page), PAGE_UL_PTR(unmap_map, page)) +#define PageUnmap(page) \ + test_bit(PAGEBIT(page), PAGE_UL_PTR(unmap_map, page)) + +#define BITMAP_FOR_EACH_SET(bitmap, counter) \ + for (counter = __get_next_bit_on(bitmap, -1); counter < max_mapnr; \ + counter = __get_next_bit_on(bitmap, counter)) + +extern void save_dyn_pageflags(dyn_pageflags_t pagemap); +extern void load_dyn_pageflags(dyn_pageflags_t pagemap); +int suspend_allocate_dyn_pageflags(dyn_pageflags_t *pagemap); +void relocate_dyn_pageflags(dyn_pageflags_t *pagemap);
- 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/