mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [Suspend2][ 0/7] Pageflags support.
@ 2006-06-26 22:31 Nigel Cunningham
  2006-06-26 22:31 ` [Suspend2][ 1/7] [Suspend2] Pagedir.h Nigel Cunningham
                   ` (6 more replies)
  0 siblings, 7 replies; 8+ messages in thread
From: Nigel Cunningham @ 2006-06-26 22:31 UTC (permalink / raw)
  To: linux-kernel


Add routines specific to Suspend2 for serialising pageflags
in an image header and relocating them so that highmem pages
can be also be restored at resume-time after lowmem is restored
and the original cpu context reinstated.

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

* [Suspend2][ 1/7] [Suspend2] Pagedir.h
  2006-06-26 22:31 [Suspend2][ 0/7] Pageflags support Nigel Cunningham
@ 2006-06-26 22:31 ` Nigel Cunningham
  2006-06-26 22:31 ` [Suspend2][ 2/7] [Suspend2] Return number of zones used Nigel Cunningham
                   ` (5 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Nigel Cunningham @ 2006-06-26 22:31 UTC (permalink / raw)
  To: linux-kernel

Add pagedir structs and declarations for variables and functions exported
from pagedir.c.

Signed-off-by: Nigel Cunningham <nigel@suspend2.net>

 kernel/power/pageflags.c |   28 ++++++++++++++++++++++++++++
 1 files changed, 28 insertions(+), 0 deletions(-)

diff --git a/kernel/power/pageflags.c b/kernel/power/pageflags.c
new file mode 100644
index 0000000..81f0825
--- /dev/null
+++ b/kernel/power/pageflags.c
@@ -0,0 +1,28 @@
+/*
+ * kernel/power/pageflags.c
+ *
+ * Copyright (C) 2004-2006 Nigel Cunningham <nigel@suspend2.net>
+ * 
+ * This file is released under the GPLv2.
+ *
+ * Routines for serialising and relocating pageflags in which we
+ * store our image metadata.
+ *
+ */
+
+#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 "modules.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;
+

--
Nigel Cunningham		nigel at suspend2 dot net

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

* [Suspend2][ 2/7] [Suspend2] Return number of zones used.
  2006-06-26 22:31 [Suspend2][ 0/7] Pageflags support Nigel Cunningham
  2006-06-26 22:31 ` [Suspend2][ 1/7] [Suspend2] Pagedir.h Nigel Cunningham
@ 2006-06-26 22:31 ` Nigel Cunningham
  2006-06-26 22:31 ` [Suspend2][ 3/7] [Suspend2] Pages for zone Nigel Cunningham
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Nigel Cunningham @ 2006-06-26 22:31 UTC (permalink / raw)
  To: linux-kernel

Get the number of zones used. Used when relocating the pageflags (below).

Signed-off-by: Nigel Cunningham <nigel@suspend2.net>

 kernel/power/pageflags.c |   11 +++++++++++
 1 files changed, 11 insertions(+), 0 deletions(-)

diff --git a/kernel/power/pageflags.c b/kernel/power/pageflags.c
index 81f0825..3781fc8 100644
--- a/kernel/power/pageflags.c
+++ b/kernel/power/pageflags.c
@@ -26,3 +26,14 @@ dyn_pageflags_t pageset1_copy_map;
 dyn_pageflags_t pageset2_map;
 dyn_pageflags_t in_use_map;
 
+static int num_zones(void)
+{
+	int result = 0;
+	struct zone *zone;
+
+	for_each_zone(zone)
+		result++;
+
+	return result;
+}
+

--
Nigel Cunningham		nigel at suspend2 dot net

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

* [Suspend2][ 3/7] [Suspend2] Pages for zone.
  2006-06-26 22:31 [Suspend2][ 0/7] Pageflags support Nigel Cunningham
  2006-06-26 22:31 ` [Suspend2][ 1/7] [Suspend2] Pagedir.h Nigel Cunningham
  2006-06-26 22:31 ` [Suspend2][ 2/7] [Suspend2] Return number of zones used Nigel Cunningham
@ 2006-06-26 22:31 ` Nigel Cunningham
  2006-06-26 22:31 ` [Suspend2][ 4/7] [Suspend2] Space needed to store one set of pageflags Nigel Cunningham
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Nigel Cunningham @ 2006-06-26 22:31 UTC (permalink / raw)
  To: linux-kernel

Find out how many pages are used for the bitmap for a given zone.

Signed-off-by: Nigel Cunningham <nigel@suspend2.net>

 kernel/power/pageflags.c |    6 ++++++
 1 files changed, 6 insertions(+), 0 deletions(-)

diff --git a/kernel/power/pageflags.c b/kernel/power/pageflags.c
index 3781fc8..ec028d3 100644
--- a/kernel/power/pageflags.c
+++ b/kernel/power/pageflags.c
@@ -37,3 +37,9 @@ static int num_zones(void)
 	return result;
 }
 
+static int pages_for_zone(struct zone *zone)
+{
+	return (zone->spanned_pages + (PAGE_SIZE << 3) - 1) /
+			(PAGE_SIZE << 3);
+}
+

--
Nigel Cunningham		nigel at suspend2 dot net

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

* [Suspend2][ 4/7] [Suspend2] Space needed to store one set of pageflags.
  2006-06-26 22:31 [Suspend2][ 0/7] Pageflags support Nigel Cunningham
                   ` (2 preceding siblings ...)
  2006-06-26 22:31 ` [Suspend2][ 3/7] [Suspend2] Pages for zone Nigel Cunningham
@ 2006-06-26 22:31 ` Nigel Cunningham
  2006-06-26 22:31 ` [Suspend2][ 5/7] [Suspend2] Serialise pageflags Nigel Cunningham
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Nigel Cunningham @ 2006-06-26 22:31 UTC (permalink / raw)
  To: linux-kernel

Return the number of bytes in the image header required to store one set of
pageflags.

Signed-off-by: Nigel Cunningham <nigel@suspend2.net>

 kernel/power/pageflags.c |   13 +++++++++++++
 1 files changed, 13 insertions(+), 0 deletions(-)

diff --git a/kernel/power/pageflags.c b/kernel/power/pageflags.c
index ec028d3..7c00257 100644
--- a/kernel/power/pageflags.c
+++ b/kernel/power/pageflags.c
@@ -43,3 +43,16 @@ static int pages_for_zone(struct zone *z
 			(PAGE_SIZE << 3);
 }
 
+int suspend_pageflags_space_needed(void)
+{
+	int total = 0;
+	struct zone *zone;
+
+	for_each_zone(zone)
+		total += sizeof(int) * 2 + pages_for_zone(zone) * PAGE_SIZE;
+
+	total += sizeof(int);
+
+	return total;
+}
+

--
Nigel Cunningham		nigel at suspend2 dot net

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

* [Suspend2][ 5/7] [Suspend2] Serialise pageflags.
  2006-06-26 22:31 [Suspend2][ 0/7] Pageflags support Nigel Cunningham
                   ` (3 preceding siblings ...)
  2006-06-26 22:31 ` [Suspend2][ 4/7] [Suspend2] Space needed to store one set of pageflags Nigel Cunningham
@ 2006-06-26 22:31 ` Nigel Cunningham
  2006-06-26 22:31 ` [Suspend2][ 6/7] [Suspend2] Relocate pageflags Nigel Cunningham
  2006-06-26 22:31 ` [Suspend2][ 7/7] [Suspend2] Pageflags.h Nigel Cunningham
  6 siblings, 0 replies; 8+ messages in thread
From: Nigel Cunningham @ 2006-06-26 22:31 UTC (permalink / raw)
  To: linux-kernel

Routines for serialising pageflags in an image header.

Signed-off-by: Nigel Cunningham <nigel@suspend2.net>

 kernel/power/pageflags.c |   74 ++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 74 insertions(+), 0 deletions(-)

diff --git a/kernel/power/pageflags.c b/kernel/power/pageflags.c
index 7c00257..0b019de 100644
--- a/kernel/power/pageflags.c
+++ b/kernel/power/pageflags.c
@@ -56,3 +56,77 @@ int suspend_pageflags_space_needed(void)
 	return total;
 }
 
+/* save_dyn_pageflags
+ *
+ * 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, zone_num = 0;
+	struct zone *zone;
+
+	if (!*pagemap)
+		return;
+
+	for_each_zone(zone) {
+		int size = pages_for_zone(zone);
+
+		suspend_active_writer->rw_header_chunk(WRITE, NULL,
+				(char *) &zone_num, sizeof(int));
+		suspend_active_writer->rw_header_chunk(WRITE, NULL,
+				(char *) &size, sizeof(int));
+
+		for (i = 0; i < size; i++)
+			suspend_active_writer->rw_header_chunk(WRITE, NULL,
+				(char *) pagemap[zone_num][i], PAGE_SIZE);
+		zone_num++;
+	}
+	zone_num = -1;
+	suspend_active_writer->rw_header_chunk(WRITE, NULL,
+			(char *) &zone_num, sizeof(int));
+}
+
+/* load_dyn_pageflags
+ *
+ * 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, zone_num = 0, zone_check = 0;
+	struct zone *zone;
+
+	if (!pagemap)
+		return;
+
+	for_each_zone(zone) {
+		int size = 0;
+		suspend_active_writer->rw_header_chunk(READ, NULL,
+				(char *) &zone_check, sizeof(int));
+		if (zone_check != zone_num) {
+			printk("Zone check (%d) != zone_num (%d).\n",
+					zone_check, zone_num);
+			BUG();
+		}
+		suspend_active_writer->rw_header_chunk(READ, NULL,
+				(char *) &size, sizeof(int));
+
+		for (i = 0; i < size; i++)
+			suspend_active_writer->rw_header_chunk(READ, NULL,
+					(char *) pagemap[zone_num][i],
+					PAGE_SIZE);
+		zone_num++;
+	}
+	suspend_active_writer->rw_header_chunk(READ, NULL, (char *) &zone_check,
+			sizeof(int));
+	if (zone_check != -1) {
+		printk("Didn't read end of dyn pageflag data marker.(%x)\n",
+				zone_check);
+		BUG();
+	}
+}
+

--
Nigel Cunningham		nigel at suspend2 dot net

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

* [Suspend2][ 6/7] [Suspend2] Relocate pageflags.
  2006-06-26 22:31 [Suspend2][ 0/7] Pageflags support Nigel Cunningham
                   ` (4 preceding siblings ...)
  2006-06-26 22:31 ` [Suspend2][ 5/7] [Suspend2] Serialise pageflags Nigel Cunningham
@ 2006-06-26 22:31 ` Nigel Cunningham
  2006-06-26 22:31 ` [Suspend2][ 7/7] [Suspend2] Pageflags.h Nigel Cunningham
  6 siblings, 0 replies; 8+ messages in thread
From: Nigel Cunningham @ 2006-06-26 22:31 UTC (permalink / raw)
  To: linux-kernel

Relocate dynamically allocated pageflags to locations that won't be
overwritten by the memory we're about to restore. This is used for
restoring highmem pages after we've done the atomic restore of low memory.

Signed-off-by: Nigel Cunningham <nigel@suspend2.net>

 kernel/power/pageflags.c |   36 ++++++++++++++++++++++++++++++++++++
 1 files changed, 36 insertions(+), 0 deletions(-)

diff --git a/kernel/power/pageflags.c b/kernel/power/pageflags.c
index 0b019de..b61b2a6 100644
--- a/kernel/power/pageflags.c
+++ b/kernel/power/pageflags.c
@@ -130,3 +130,39 @@ void load_dyn_pageflags(dyn_pageflags_t 
 	}
 }
 
+/* relocate_dyn_pageflags
+ *
+ * Description: Relocate a set of pageflags to ensure they don't collide with
+ *              pageset 1 data which will get overwritten on copyback.
+ * Arguments:   dyn_pageflags_t *: Pointer to the bitmap being relocated.
+ */
+
+void relocate_dyn_pageflags(dyn_pageflags_t *pagemap)
+{
+	int i, zone_num = 0;
+	struct zone *zone;
+
+	if (!*pagemap)
+		return;
+
+	suspend_relocate_if_required((void *) pagemap,
+			sizeof(void *) * num_zones());
+	BUG_ON(PagePageset1(virt_to_page(*pagemap)));
+
+	for_each_zone(zone) {
+		int pages = pages_for_zone(zone);
+
+		suspend_relocate_if_required((void *) &((*pagemap)[zone_num]),
+			       sizeof(void *) * pages);
+		BUG_ON(PagePageset1(virt_to_page((*pagemap)[zone_num])));
+
+		for (i = 0; i < pages; i++) {
+			suspend_relocate_if_required(
+				(void *) &((*pagemap)[zone_num][i]),
+				PAGE_SIZE);
+			BUG_ON(PagePageset1(virt_to_page(
+						(*pagemap)[zone_num][i])));
+		}
+		zone_num++;
+	}
+}

--
Nigel Cunningham		nigel at suspend2 dot net

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

* [Suspend2][ 7/7] [Suspend2] Pageflags.h
  2006-06-26 22:31 [Suspend2][ 0/7] Pageflags support Nigel Cunningham
                   ` (5 preceding siblings ...)
  2006-06-26 22:31 ` [Suspend2][ 6/7] [Suspend2] Relocate pageflags Nigel Cunningham
@ 2006-06-26 22:31 ` Nigel Cunningham
  6 siblings, 0 replies; 8+ messages in thread
From: Nigel Cunningham @ 2006-06-26 22:31 UTC (permalink / raw)
  To: linux-kernel

Add header for pageflags variables and macros.

Signed-off-by: Nigel Cunningham <nigel@suspend2.net>

 kernel/power/pageflags.h |   51 ++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 51 insertions(+), 0 deletions(-)

diff --git a/kernel/power/pageflags.h b/kernel/power/pageflags.h
new file mode 100644
index 0000000..c1d1b88
--- /dev/null
+++ b/kernel/power/pageflags.h
@@ -0,0 +1,51 @@
+/*
+ * kernel/power/pageflags.h
+ *
+ * Copyright (C) 2004-2006 Nigel Cunningham <nigel@suspend2.net>
+ *
+ * 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 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_dynpageflag(&in_use_map, page))
+#define SetPageInUse(page) (set_dynpageflag(&in_use_map, page))
+#define ClearPageInUse(page) (clear_dynpageflag(&in_use_map, page))
+
+#define PagePageset1(page) (test_dynpageflag(&pageset1_map, page))
+#define SetPagePageset1(page) (set_dynpageflag(&pageset1_map, page))
+#define ClearPagePageset1(page) (clear_dynpageflag(&pageset1_map, page))
+
+#define PagePageset1Copy(page) (test_dynpageflag(&pageset1_copy_map, page))
+#define SetPagePageset1Copy(page) (set_dynpageflag(&pageset1_copy_map, page))
+#define ClearPagePageset1Copy(page) (clear_dynpageflag(&pageset1_copy_map, page))
+
+#define PagePageset2(page) (test_dynpageflag(&pageset2_map, page))
+#define SetPagePageset2(page) (set_dynpageflag(&pageset2_map, page))
+#define ClearPagePageset2(page) (clear_dynpageflag(&pageset2_map, page))
+
+extern void save_dyn_pageflags(dyn_pageflags_t pagemap);
+extern void load_dyn_pageflags(dyn_pageflags_t pagemap);
+extern void relocate_dyn_pageflags(dyn_pageflags_t *pagemap);
+extern int suspend_pageflags_space_needed(void);

--
Nigel Cunningham		nigel at suspend2 dot net

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

end of thread, other threads:[~2006-06-26 22:34 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2006-06-26 22:31 [Suspend2][ 0/7] Pageflags support Nigel Cunningham
2006-06-26 22:31 ` [Suspend2][ 1/7] [Suspend2] Pagedir.h Nigel Cunningham
2006-06-26 22:31 ` [Suspend2][ 2/7] [Suspend2] Return number of zones used Nigel Cunningham
2006-06-26 22:31 ` [Suspend2][ 3/7] [Suspend2] Pages for zone Nigel Cunningham
2006-06-26 22:31 ` [Suspend2][ 4/7] [Suspend2] Space needed to store one set of pageflags Nigel Cunningham
2006-06-26 22:31 ` [Suspend2][ 5/7] [Suspend2] Serialise pageflags Nigel Cunningham
2006-06-26 22:31 ` [Suspend2][ 6/7] [Suspend2] Relocate pageflags Nigel Cunningham
2006-06-26 22:31 ` [Suspend2][ 7/7] [Suspend2] Pageflags.h Nigel Cunningham

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

all inboxes | Powered by JetHome®