Commit b788db79 authored by Rafael J. Wysocki's avatar Rafael J. Wysocki Committed by Linus Torvalds

[PATCH] swsusp: Introduce memory bitmaps

Introduce the memory bitmap data structure and make swsusp use in the suspend
phase.

The current swsusp's internal data structure is not very efficient from the
memory usage point of view, so it seems reasonable to replace it with a data
structure that will require less memory, such as a pair of bitmaps.

The idea is to use bitmaps that may be allocated as sets of individual pages,
so that we can avoid making allocations of order greater than 0.  For this
reason the memory bitmap structure consists of several linked lists of objects
that contain pointers to memory pages with the actual bitmap data.  Still, for
a typical system all of these lists fit in a single page, so it's reasonable
to introduce an additional mechanism allowing us to allocate all of them
efficiently without sacrificing the generality of the design.  This is done
with the help of the chain_allocator structure and associated functions.

We need to use two memory bitmaps during the suspend phase of the
suspend-resume cycle.  One of them is necessary for marking the saveable
pages, and the second is used to mark the pages in which to store the copies
of them (aka image pages).

First, the bitmaps are created and we allocate as many image pages as needed
(the corresponding bits in the second bitmap are set as soon as the pages are
allocated).  Second, the bits corresponding to the saveable pages are set in
the first bitmap and the saveable pages are copied to the image pages.
Finally, the first bitmap is used to save the kernel virtual addresses of the
saveable pages and the second one is used to save the contents of the image
pages.
Signed-off-by: default avatarRafael J. Wysocki <rjw@sisk.pl>
Acked-by: default avatarPavel Machek <pavel@ucw.cz>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 0bcd888d
...@@ -109,9 +109,10 @@ struct snapshot_handle { ...@@ -109,9 +109,10 @@ struct snapshot_handle {
*/ */
#define data_of(handle) ((handle).buffer + (handle).buf_offset) #define data_of(handle) ((handle).buffer + (handle).buf_offset)
extern unsigned int snapshot_additional_pages(struct zone *zone);
extern int snapshot_read_next(struct snapshot_handle *handle, size_t count); extern int snapshot_read_next(struct snapshot_handle *handle, size_t count);
extern int snapshot_write_next(struct snapshot_handle *handle, size_t count); extern int snapshot_write_next(struct snapshot_handle *handle, size_t count);
int snapshot_image_loaded(struct snapshot_handle *handle); extern int snapshot_image_loaded(struct snapshot_handle *handle);
#define SNAPSHOT_IOC_MAGIC '3' #define SNAPSHOT_IOC_MAGIC '3'
#define SNAPSHOT_FREEZE _IO(SNAPSHOT_IOC_MAGIC, 1) #define SNAPSHOT_FREEZE _IO(SNAPSHOT_IOC_MAGIC, 1)
......
This diff is collapsed.
...@@ -193,14 +193,13 @@ int swsusp_shrink_memory(void) ...@@ -193,14 +193,13 @@ int swsusp_shrink_memory(void)
printk("Shrinking memory... "); printk("Shrinking memory... ");
do { do {
size = 2 * count_highmem_pages(); size = 2 * count_highmem_pages();
size += size / 50 + count_data_pages(); size += size / 50 + count_data_pages() + PAGES_FOR_IO;
size += (size + PBES_PER_PAGE - 1) / PBES_PER_PAGE +
PAGES_FOR_IO;
tmp = size; tmp = size;
for_each_zone (zone) for_each_zone (zone)
if (!is_highmem(zone) && populated_zone(zone)) { if (!is_highmem(zone) && populated_zone(zone)) {
tmp -= zone->free_pages; tmp -= zone->free_pages;
tmp += zone->lowmem_reserve[ZONE_NORMAL]; tmp += zone->lowmem_reserve[ZONE_NORMAL];
tmp += snapshot_additional_pages(zone);
} }
if (tmp > 0) { if (tmp > 0) {
tmp = __shrink_memory(tmp); tmp = __shrink_memory(tmp);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment