linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [Suspend2][ 00/16] Suspend.c
@ 2006-06-26 22:33 Nigel Cunningham
  2006-06-26 22:33 ` [Suspend2][ 01/16] [Suspend2] Suspend.c header Nigel Cunningham
                   ` (15 more replies)
  0 siblings, 16 replies; 17+ messages in thread
From: Nigel Cunningham @ 2006-06-26 22:33 UTC (permalink / raw)
  To: linux-kernel


This file implements the highest level routines for Suspend2.

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

* [Suspend2][ 01/16] [Suspend2] Suspend.c header.
  2006-06-26 22:33 [Suspend2][ 00/16] Suspend.c Nigel Cunningham
@ 2006-06-26 22:33 ` Nigel Cunningham
  2006-06-26 22:33 ` [Suspend2][ 02/16] [Suspend2] Routines called when starting or finishing anything Nigel Cunningham
                   ` (14 subsequent siblings)
  15 siblings, 0 replies; 17+ messages in thread
From: Nigel Cunningham @ 2006-06-26 22:33 UTC (permalink / raw)
  To: linux-kernel

Header file for the Suspend2's main c file.

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

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

diff --git a/kernel/power/suspend.c b/kernel/power/suspend.c
new file mode 100644
index 0000000..28bb91c
--- /dev/null
+++ b/kernel/power/suspend.c
@@ -0,0 +1,182 @@
+/*
+ * kernel/power/suspend.c
+ */
+/** \mainpage Suspend2.
+ *
+ * Suspend2 provides support for saving and restoring an image of
+ * system memory to an arbitrary storage device, either on the local computer,
+ * or across some network. The support is entirely OS based, so Suspend2 
+ * works without requiring BIOS, APM or ACPI support. The vast majority of the
+ * code is also architecture independant, so it should be very easy to port
+ * the code to new architectures. Suspend includes support for SMP, 4G HighMem
+ * and preemption. Initramfses and initrds are also supported.
+ *
+ * Suspend2 uses a modular design, in which the method of storing the image is
+ * completely abstracted from the core code, as are transformations on the data
+ * such as compression and/or encryption (multiple 'modules' can be used to
+ * provide arbitrary combinations of functionality). The user interface is also
+ * modular, so that arbitrarily simple or complex interfaces can be used to
+ * provide anything from debugging information through to eye candy.
+ * 
+ * \section Copyright
+ *
+ * Suspend2 is released under the GPLv2.
+ *
+ * Copyright (C) 1998-2001 Gabor Kuti <seasons@fornax.hu><BR>
+ * Copyright (C) 1998,2001,2002 Pavel Machek <pavel@suse.cz><BR>
+ * Copyright (C) 2002-2003 Florent Chabaud <fchabaud@free.fr><BR>
+ * Copyright (C) 2002-2006 Nigel Cunningham <nigel@suspend2.net><BR>
+ *
+ * \section Credits
+ * 
+ * Nigel would like to thank the following people for their work:
+ * 
+ * Pavel Machek <pavel@ucw.cz><BR>
+ * Modifications, defectiveness pointing, being with Gabor at the very beginning,
+ * suspend to swap space, stop all tasks. Port to 2.4.18-ac and 2.5.17.
+ *
+ * Steve Doddi <dirk@loth.demon.co.uk><BR> 
+ * Support the possibility of hardware state restoring.
+ *
+ * Raph <grey.havens@earthling.net><BR>
+ * Support for preserving states of network devices and virtual console
+ * (including X and svgatextmode)
+ *
+ * Kurt Garloff <garloff@suse.de><BR>
+ * Straightened the critical function in order to prevent compilers from
+ * playing tricks with local variables.
+ *
+ * Andreas Mohr <a.mohr@mailto.de>
+ *
+ * Alex Badea <vampire@go.ro><BR>
+ * Fixed runaway init
+ *
+ * Jeff Snyder <je4d@pobox.com><BR>
+ * ACPI patch
+ *
+ * Nathan Friess <natmanz@shaw.ca><BR>
+ * Some patches.
+ *
+ * Michael Frank <mhf@linuxmail.org><BR>
+ * Extensive testing and help with improving stability. Nigel was constantly
+ * amazed by the quality and quantity of Michael's help.
+ *
+ * Bernard Blackham <bernard@blackham.com.au><BR>
+ * Web page & Wiki administration, some coding. Another person without whom
+ * Suspend would not be where it is.
+ *
+ * ..and of course the myriads of Suspend2 users who have helped diagnose
+ * and fix bugs, made suggestions on how to improve the code, proofread
+ * documentation, and donated time and money.
+ *
+ * Thanks also to corporate sponsors:
+ *
+ * <B>Cyclades.com.</B> Nigel's employers from Dec 2004, who allow him to work on
+ * Suspend and PM related issues on company time.
+ * 
+ * <B>LinuxFund.org.</B> Sponsored Nigel's work on Suspend for four months Oct 2003
+ * to Jan 2004.
+ *
+ * <B>LAC Linux.</B> Donated P4 hardware that enabled development and ongoing
+ * maintenance of SMP and Highmem support.
+ *
+ * <B>OSDL.</B> Provided access to various hardware configurations, make occasional
+ * small donations to the project.
+ */
+
+#define SUSPEND_MAIN_C
+
+#include <linux/suspend.h>
+#include <linux/module.h>
+#include <linux/console.h>
+#include <linux/version.h>
+#include <linux/reboot.h>
+#include <linux/mm.h>
+#include <linux/highmem.h>
+#include <linux/freezer.h>
+#include <asm/uaccess.h>
+#include <asm/setup.h>
+
+#include "version.h"
+#include "suspend2.h"
+#include "suspend.h"
+#include "modules.h"
+#include "proc.h"
+#include "pageflags.h"
+#include "prepare_image.h"
+#include "io.h"
+#include "ui.h"
+#include "suspend2_common.h"
+#include "extent.h"
+#include "power_off.h"
+#include "storage.h"
+#include "power.h"
+
+#ifdef  CONFIG_X86
+#include <asm/i387.h> /* for kernel_fpu_end */
+#endif
+
+int suspend2_running;
+ 
+/* Variables to be preserved over suspend */
+long pageset1_sizelow = 0, pageset2_sizelow = 0, image_size_limit = 0;
+unsigned long suspend_orig_mem_free = 0;
+
+static char *debug_info_buffer;
+static char suspend_core_version[] = SUSPEND_CORE_VERSION;
+
+extern __nosavedata char suspend_resume_commandline[COMMAND_LINE_SIZE];
+
+unsigned long suspend_action = 0;
+unsigned long suspend_result = 0;
+unsigned long suspend_debug_state = 0;
+
+int suspend2_in_suspend __nosavedata;
+extern void copyback_post(void);
+extern int suspend2_suspend(void);
+extern int extra_pd1_pages_used;
+
+static int orig_system_state;
+
+/* 
+ * ---  Variables -----
+ * 
+ * The following are used by the arch specific low level routines 
+ * and only needed if suspend2 is compiled in. Other variables,
+ * used by the freezer even if suspend2 is not compiled in, are
+ * found in process.c
+ */
+
+/*! How long I/O took. */
+int suspend_io_time[2][2];
+
+/* Compression ratio */
+__nosavedata unsigned long bytes_in = 0, bytes_out = 0;
+
+/*! Pageset metadata. */
+struct pagedir pagedir1 = { 0, 0}, pagedir2 = { 0, 0}; 
+
+/* Suspend2 variables used by built-in routines. */
+
+/*! The number of suspends we have started (some may have been cancelled) */
+unsigned int nr_suspends = 0;
+
+/* 
+ * For resume2= kernel option. It's pointless to compile
+ * suspend2 without any writers, but compilation shouldn't
+ * fail if you do.
+ */
+
+unsigned long suspend_state = ((1 << SUSPEND_BOOT_TIME) |
+		(1 << SUSPEND_RESUME_NOT_DONE) | (1 << SUSPEND_IGNORE_LOGLEVEL));
+
+mm_segment_t	oldfs;
+
+char resume2_file[256] = CONFIG_SUSPEND2_DEFAULT_RESUME2;
+
+static atomic_t actions_running;
+
+extern int block_dump;
+
+int block_dump_save;
+

--
Nigel Cunningham		nigel at suspend2 dot net

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

* [Suspend2][ 02/16] [Suspend2] Routines called when starting or finishing anything.
  2006-06-26 22:33 [Suspend2][ 00/16] Suspend.c Nigel Cunningham
  2006-06-26 22:33 ` [Suspend2][ 01/16] [Suspend2] Suspend.c header Nigel Cunningham
@ 2006-06-26 22:33 ` Nigel Cunningham
  2006-06-26 22:33 ` [Suspend2][ 03/16] [Suspend2] Save image Nigel Cunningham
                   ` (13 subsequent siblings)
  15 siblings, 0 replies; 17+ messages in thread
From: Nigel Cunningham @ 2006-06-26 22:33 UTC (permalink / raw)
  To: linux-kernel

Routines called when starting or completing any action.

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

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

diff --git a/kernel/power/suspend.c b/kernel/power/suspend.c
index 28bb91c..01c930a 100644
--- a/kernel/power/suspend.c
+++ b/kernel/power/suspend.c
@@ -180,3 +180,54 @@ extern int block_dump;
 
 int block_dump_save;
 
+/*
+ * Basic clean-up routine.
+ */
+void suspend_finish_anything(int finishing_cycle)
+{
+	if (atomic_dec_and_test(&actions_running)) {
+		suspend_cleanup_modules(finishing_cycle);
+		suspend_put_modules();
+		clear_suspend_state(SUSPEND_RUNNING);
+	}
+
+	set_fs(oldfs);
+
+	if (finishing_cycle)
+		block_dump = block_dump_save;
+}
+
+/*
+ * Basic set-up routine.
+ */
+int suspend_start_anything(int starting_cycle)
+{
+	oldfs = get_fs();
+
+	if (atomic_add_return(1, &actions_running) == 1) {
+       		set_fs(KERNEL_DS);
+
+		set_suspend_state(SUSPEND_RUNNING);
+
+		if (suspend_get_modules()) {
+			printk("Get modules failed!\n");
+			clear_suspend_state(SUSPEND_RUNNING);
+			set_fs(oldfs);
+			return -EBUSY;
+		}
+
+		if (suspend_initialise_modules(starting_cycle)) {
+			printk("Initialise modules failed!\n");
+			suspend_finish_anything(starting_cycle);
+			return -EBUSY;
+		}
+
+		if (starting_cycle) {
+			block_dump_save = block_dump;
+			block_dump = 0;
+		}
+	}
+
+	return 0;
+}
+

--
Nigel Cunningham		nigel at suspend2 dot net

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

* [Suspend2][ 03/16] [Suspend2] Save image.
  2006-06-26 22:33 [Suspend2][ 00/16] Suspend.c Nigel Cunningham
  2006-06-26 22:33 ` [Suspend2][ 01/16] [Suspend2] Suspend.c header Nigel Cunningham
  2006-06-26 22:33 ` [Suspend2][ 02/16] [Suspend2] Routines called when starting or finishing anything Nigel Cunningham
@ 2006-06-26 22:33 ` Nigel Cunningham
  2006-06-26 22:33 ` [Suspend2][ 04/16] [Suspend2] Get debug info Nigel Cunningham
                   ` (12 subsequent siblings)
  15 siblings, 0 replies; 17+ messages in thread
From: Nigel Cunningham @ 2006-06-26 22:33 UTC (permalink / raw)
  To: linux-kernel

Save the image. The first function is the one called by the suspend_main
after the image is prepared, which saves pageset two (LRU pages) and then
sends us into the atomic copy routine. After resume (or the cycle is
cancelled), we return back to this routine. Save_image_part1, is called
after the atomic copy, to do the saving of that part of the image.

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

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

diff --git a/kernel/power/suspend.c b/kernel/power/suspend.c
index 01c930a..8ef1200 100644
--- a/kernel/power/suspend.c
+++ b/kernel/power/suspend.c
@@ -231,3 +231,141 @@ int suspend_start_anything(int starting_
 	return 0;
 }
 
+/*
+ * save_image
+ * Result code (int): Zero on success, non zero on failure.
+ * Functionality    : High level routine which performs the steps necessary
+ *                    to prepare and save the image after preparatory steps
+ *                    have been taken.
+ * Key Assumptions  : Processes frozen, sufficient memory available, drivers
+ *                    suspended.
+ * Called from      : suspend_suspend_2
+ */
+static int save_image(void)
+{
+	int temp_result;
+
+	suspend_message(SUSPEND_ANY_SECTION, SUSPEND_LOW, 1,
+		" - Final values: %d and %d.\n",
+		pagedir1.pageset_size, 
+		pagedir2.pageset_size);
+
+	suspend_cond_pause(1, "About to write pagedir2.");
+
+	temp_result = write_pageset(&pagedir2, 2);
+	
+	if (temp_result == -1 || test_result_state(SUSPEND_ABORTED))
+		return -1;
+
+	suspend_cond_pause(1, "About to copy pageset 1.");
+
+	if (test_result_state(SUSPEND_ABORTED))
+		return -1;
+
+	suspend_deactivate_storage(1);
+
+	suspend_prepare_status(DONT_CLEAR_BAR, "Doing atomic copy.");
+	
+	suspend2_running = 1; /* For the swsusp code we use :< */
+
+	suspend2_in_suspend = 1;
+	
+	if (device_suspend(PMSG_FREEZE))
+		return 1;
+	
+	suspend2_suspend();
+
+	suspend2_running = 0;
+
+	device_resume();
+	
+	/* Resume time? */
+	if (!suspend2_in_suspend) {
+		copyback_post();
+		return 0;
+	}
+
+	/* Nope. Suspending. So, see if we can save the image... */
+	if (!save_image_part1()) {
+		suspend_power_down();
+
+		if (read_pageset2(1))
+			panic("Attempt to reload pagedir 2 failed. Try rebooting.");
+
+		if (!test_result_state(SUSPEND_ABORT_REQUESTED) &&
+		    !test_action_state(SUSPEND_TEST_FILTER_SPEED) &&
+		    !test_action_state(SUSPEND_TEST_BIO) &&
+		    suspend_powerdown_method != PM_SUSPEND_MEM)
+			printk(KERN_EMERG name_suspend
+				"Suspend failed, trying to recover...\n");
+		barrier();
+		mb();
+	}
+
+	return 0;
+}
+
+/*
+ * Save the second part of the image.
+ */
+int save_image_part1(void)
+{
+	int temp_result;
+
+	if (suspend_activate_storage(1))
+		panic("Failed to reactivate our storage.");
+	
+	suspend_update_status(pagedir2.pageset_size,
+			pagedir1.pageset_size + pagedir2.pageset_size,
+			NULL);
+	
+	if (test_result_state(SUSPEND_ABORTED))
+		goto abort_reloading_pagedir_two;
+
+	suspend_cond_pause(1, "About to write pageset1.");
+
+	/*
+	 * End of critical section.
+	 */
+	
+	suspend_message(SUSPEND_ANY_SECTION, SUSPEND_LOW, 1,
+			"-- Writing pageset1\n");
+
+	temp_result = write_pageset(&pagedir1, 1);
+
+	/* We didn't overwrite any memory, so no reread needs to be done. */
+	if (test_action_state(SUSPEND_TEST_FILTER_SPEED))
+		return -1;
+
+	if (temp_result == -1 || test_result_state(SUSPEND_ABORTED))
+		goto abort_reloading_pagedir_two;
+
+	suspend_cond_pause(1, "About to write header.");
+
+	if (test_result_state(SUSPEND_ABORTED))
+		goto abort_reloading_pagedir_two;
+
+	temp_result = write_image_header();
+
+	if (test_action_state(SUSPEND_TEST_BIO))
+		return -1;
+
+	if (temp_result || (test_result_state(SUSPEND_ABORTED)))
+		goto abort_reloading_pagedir_two;
+
+	suspend_cond_pause(1, "About to power down or reboot.");
+
+	return 0;
+
+abort_reloading_pagedir_two:
+	temp_result = read_pageset2(1);
+
+	/* If that failed, we're sunk. Panic! */
+	if (temp_result)
+		panic("Attempt to reload pagedir 2 while aborting "
+				"a suspend failed.");
+
+	return -1;		
+
+}
+

--
Nigel Cunningham		nigel at suspend2 dot net

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

* [Suspend2][ 04/16] [Suspend2] Get debug info.
  2006-06-26 22:33 [Suspend2][ 00/16] Suspend.c Nigel Cunningham
                   ` (2 preceding siblings ...)
  2006-06-26 22:33 ` [Suspend2][ 03/16] [Suspend2] Save image Nigel Cunningham
@ 2006-06-26 22:33 ` Nigel Cunningham
  2006-06-26 22:33 ` [Suspend2][ 05/16] [Suspend2] Allocate/free bitmaps Nigel Cunningham
                   ` (11 subsequent siblings)
  15 siblings, 0 replies; 17+ messages in thread
From: Nigel Cunningham @ 2006-06-26 22:33 UTC (permalink / raw)
  To: linux-kernel

Routines that together provide the user with debugging info via
/proc/suspend2/debug_info.

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

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

diff --git a/kernel/power/suspend.c b/kernel/power/suspend.c
index 8ef1200..769ae96 100644
--- a/kernel/power/suspend.c
+++ b/kernel/power/suspend.c
@@ -369,3 +369,103 @@ abort_reloading_pagedir_two:
 
 }
 
+static int io_MB_per_second(int read_write)
+{
+	if (!suspend_io_time[read_write][1])
+		return 0;
+
+	return MB((unsigned long) suspend_io_time[read_write][0]) * HZ /
+		suspend_io_time[read_write][1];
+}
+
+/* get_debug_info
+ * Functionality:	Store debug info in a buffer.
+ * Called from:		suspend2_try_suspend.
+ */
+#define SNPRINTF(a...) 	len += snprintf_used(debug_info_buffer + len, \
+		PAGE_SIZE - len - 1, ## a)
+static int get_suspend_debug_info(void)
+{
+	int len = 0;
+	if (!debug_info_buffer) {
+		debug_info_buffer = (char *) get_zeroed_page(GFP_ATOMIC);
+		if (!debug_info_buffer) {
+			printk("Error! Unable to allocate buffer for"
+					"software suspend debug info.\n");
+			return 0;
+		}
+	}
+
+	SNPRINTF("Suspend2 debugging info:\n");
+	SNPRINTF("- SUSPEND core   : %s\n", SUSPEND_CORE_VERSION);
+	SNPRINTF("- Kernel Version : %s\n", UTS_RELEASE);
+	SNPRINTF("- Compiler vers. : %d.%d\n", __GNUC__, __GNUC_MINOR__);
+	SNPRINTF("- Attempt number : %d\n", nr_suspends);
+	SNPRINTF("- Parameters     : %ld %ld %ld %d %d %ld\n",
+			suspend_result,
+			suspend_action,
+			suspend_debug_state,
+			suspend_default_console_level,
+			image_size_limit,
+			suspend_powerdown_method);
+	SNPRINTF("- Overall expected compression percentage: %d.\n",
+			100 - suspend_expected_compression_ratio());
+	len+= suspend_print_module_debug_info(debug_info_buffer + len, 
+			PAGE_SIZE - len - 1);
+	if (suspend_io_time[0][1]) {
+		if ((io_MB_per_second(0) < 5) || (io_MB_per_second(1) < 5)) {
+			SNPRINTF("- I/O speed: Write %d KB/s",
+			  (KB((unsigned long) suspend_io_time[0][0]) * HZ /
+			  suspend_io_time[0][1]));
+			if (suspend_io_time[1][1])
+				SNPRINTF(", Read %d KB/s",
+				  (KB((unsigned long) suspend_io_time[1][0]) * HZ /
+				  suspend_io_time[1][1]));
+		} else {
+			SNPRINTF("- I/O speed: Write %d MB/s",
+			 (MB((unsigned long) suspend_io_time[0][0]) * HZ /
+			  suspend_io_time[0][1]));
+			if (suspend_io_time[1][1])
+				SNPRINTF(", Read %d MB/s",
+				 (MB((unsigned long) suspend_io_time[1][0]) * HZ /
+				  suspend_io_time[1][1]));
+		}
+		SNPRINTF(".\n");
+	}
+	else
+		SNPRINTF("- No I/O speed stats available.\n");
+	SNPRINTF("- Extra pages    : %d used/%d.\n",
+			extra_pd1_pages_used, extra_pd1_pages_allowance);
+
+	return len;
+}
+
+/*
+ * debuginfo_read_proc
+ * Functionality   : Displays information that may be helpful in debugging
+ *                   software suspend.
+ */
+int debuginfo_read_proc(char *page, char **start, off_t off, int count,
+		int *eof, void *data)
+{
+	int info_len, copy_len;
+
+	info_len = get_suspend_debug_info();
+
+	copy_len = min(info_len - (int) off, count);
+	if (copy_len < 0)
+		copy_len = 0;
+
+	if (copy_len) {
+		memcpy(page, debug_info_buffer + off, copy_len);
+		*start = page;
+	} 
+
+	if (copy_len + off == info_len)
+		*eof = 1;
+
+	free_page((unsigned long) debug_info_buffer);
+	debug_info_buffer = NULL;
+	return copy_len;
+}
+

--
Nigel Cunningham		nigel at suspend2 dot net

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

* [Suspend2][ 05/16] [Suspend2] Allocate/free bitmaps.
  2006-06-26 22:33 [Suspend2][ 00/16] Suspend.c Nigel Cunningham
                   ` (3 preceding siblings ...)
  2006-06-26 22:33 ` [Suspend2][ 04/16] [Suspend2] Get debug info Nigel Cunningham
@ 2006-06-26 22:33 ` Nigel Cunningham
  2006-06-26 22:33 ` [Suspend2][ 06/16] [Suspend2] Check if still keeping an existing image Nigel Cunningham
                   ` (10 subsequent siblings)
  15 siblings, 0 replies; 17+ messages in thread
From: Nigel Cunningham @ 2006-06-26 22:33 UTC (permalink / raw)
  To: linux-kernel

Allocation and freeing routines for the bitmaps Suspend2 uses.

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

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

diff --git a/kernel/power/suspend.c b/kernel/power/suspend.c
index 769ae96..06ab034 100644
--- a/kernel/power/suspend.c
+++ b/kernel/power/suspend.c
@@ -469,3 +469,22 @@ int debuginfo_read_proc(char *page, char
 	return copy_len;
 }
 
+static int allocate_bitmaps(void)
+{
+	if (allocate_dyn_pageflags(&in_use_map) ||
+	    allocate_dyn_pageflags(&pageset1_map) ||
+	    allocate_dyn_pageflags(&pageset1_copy_map) ||
+	    allocate_dyn_pageflags(&pageset2_map))
+		return 1;
+
+	return 0;
+}
+
+static void free_metadata(void)
+{
+	free_dyn_pageflags(&pageset1_map);
+	free_dyn_pageflags(&pageset1_copy_map);
+	free_dyn_pageflags(&pageset2_map);
+	free_dyn_pageflags(&in_use_map);
+}
+

--
Nigel Cunningham		nigel at suspend2 dot net

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

* [Suspend2][ 06/16] [Suspend2] Check if still keeping an existing image.
  2006-06-26 22:33 [Suspend2][ 00/16] Suspend.c Nigel Cunningham
                   ` (4 preceding siblings ...)
  2006-06-26 22:33 ` [Suspend2][ 05/16] [Suspend2] Allocate/free bitmaps Nigel Cunningham
@ 2006-06-26 22:33 ` Nigel Cunningham
  2006-06-26 22:33 ` [Suspend2][ 07/16] [Suspend2] Suspend2 init/cleanup Nigel Cunningham
                   ` (9 subsequent siblings)
  15 siblings, 0 replies; 17+ messages in thread
From: Nigel Cunningham @ 2006-06-26 22:33 UTC (permalink / raw)
  To: linux-kernel

Suspend2 supports a keep-the-image mode, which can be used when the
contents of mounted filesystems don't change. Writeable storage can still
be used, but it needs to be unmounted while suspending and remounted on
resume.

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

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

diff --git a/kernel/power/suspend.c b/kernel/power/suspend.c
index 06ab034..6457d75 100644
--- a/kernel/power/suspend.c
+++ b/kernel/power/suspend.c
@@ -488,3 +488,17 @@ static void free_metadata(void)
 	free_dyn_pageflags(&in_use_map);
 }
 
+static int check_still_keeping_image(void)
+{
+	if (test_action_state(SUSPEND_KEEP_IMAGE)) {
+		printk("Image already stored: powering down immediately.");
+		suspend_power_down();
+		return 1;	/* Just in case we're using S3 */
+	}
+
+	printk("Invalidating previous image.\n");
+	suspend_active_writer->invalidate_image();
+
+	return 0;
+}
+

--
Nigel Cunningham		nigel at suspend2 dot net

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

* [Suspend2][ 07/16] [Suspend2] Suspend2 init/cleanup.
  2006-06-26 22:33 [Suspend2][ 00/16] Suspend.c Nigel Cunningham
                   ` (5 preceding siblings ...)
  2006-06-26 22:33 ` [Suspend2][ 06/16] [Suspend2] Check if still keeping an existing image Nigel Cunningham
@ 2006-06-26 22:33 ` Nigel Cunningham
  2006-06-26 22:33 ` [Suspend2][ 08/16] [Suspend2] Can suspend? Nigel Cunningham
                   ` (8 subsequent siblings)
  15 siblings, 0 replies; 17+ messages in thread
From: Nigel Cunningham @ 2006-06-26 22:33 UTC (permalink / raw)
  To: linux-kernel

Basic initialisation and cleanup for a suspend cycle.

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

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

diff --git a/kernel/power/suspend.c b/kernel/power/suspend.c
index 6457d75..504eed7 100644
--- a/kernel/power/suspend.c
+++ b/kernel/power/suspend.c
@@ -502,3 +502,76 @@ static int check_still_keeping_image(voi
 	return 0;
 }
 
+static int suspend_init(void)
+{
+	suspend_result = 0;
+
+	printk(name_suspend "Initiating a software suspend cycle.\n");
+
+	nr_suspends++;
+	clear_suspend_state(SUSPEND_NOW_RESUMING);
+	
+	orig_system_state = system_state;
+	
+	suspend_io_time[0][0] = suspend_io_time[0][1] = 
+		suspend_io_time[1][0] =
+		suspend_io_time[1][1] = 0;
+
+	free_metadata();	/* We might have kept it */
+
+	if (!test_suspend_state(SUSPEND_CAN_SUSPEND))
+		return 0;
+	
+	if (allocate_bitmaps())
+		return 0;
+	
+	suspend_prepare_console();
+	disable_nonboot_cpus();
+
+	return 1;
+}
+
+void suspend_cleanup(void)
+{
+	int i;
+
+	i = get_suspend_debug_info();
+
+	suspend_free_extra_pagedir_memory();
+	
+	pagedir1.pageset_size = pagedir2.pageset_size = 0;
+
+	system_state = orig_system_state;
+
+	thaw_processes(FREEZER_KERNEL_THREADS);
+
+#ifdef CONFIG_SUSPEND2_KEEP_IMAGE
+	if (test_action_state(SUSPEND_KEEP_IMAGE) &&
+	    !test_result_state(SUSPEND_ABORTED)) {
+		suspend_message(SUSPEND_ANY_SECTION, SUSPEND_LOW, 1,
+			name_suspend "Not invalidating the image due "
+			"to Keep Image being enabled.\n");
+		set_result_state(SUSPEND_KEPT_IMAGE);
+	} else
+#endif
+		if (suspend_active_writer)
+			suspend_active_writer->invalidate_image();
+
+	free_metadata();
+
+	if (debug_info_buffer) {
+		/* Printk can only handle 1023 bytes, including
+		 * its level mangling. */
+		for (i = 0; i < 3; i++)
+			printk("%s", debug_info_buffer + (1023 * i));
+		free_page((unsigned long) debug_info_buffer);
+		debug_info_buffer = NULL;
+	}
+
+	thaw_processes(FREEZER_ALL_THREADS);
+	enable_nonboot_cpus();
+	suspend_cleanup_console();
+
+	up(&pm_sem);
+}
+

--
Nigel Cunningham		nigel at suspend2 dot net

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

* [Suspend2][ 08/16] [Suspend2] Can suspend?
  2006-06-26 22:33 [Suspend2][ 00/16] Suspend.c Nigel Cunningham
                   ` (6 preceding siblings ...)
  2006-06-26 22:33 ` [Suspend2][ 07/16] [Suspend2] Suspend2 init/cleanup Nigel Cunningham
@ 2006-06-26 22:33 ` Nigel Cunningham
  2006-06-26 22:33 ` [Suspend2][ 09/16] [Suspend2] Top level routine for do_suspend Nigel Cunningham
                   ` (7 subsequent siblings)
  15 siblings, 0 replies; 17+ messages in thread
From: Nigel Cunningham @ 2006-06-26 22:33 UTC (permalink / raw)
  To: linux-kernel

Test whether resume2= points to a recognised signature. That is, can we
even try to suspend?

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

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

diff --git a/kernel/power/suspend.c b/kernel/power/suspend.c
index 504eed7..bda4c2a 100644
--- a/kernel/power/suspend.c
+++ b/kernel/power/suspend.c
@@ -575,3 +575,27 @@ void suspend_cleanup(void)
 	up(&pm_sem);
 }
 
+static int can_suspend(void)
+{
+	if (down_trylock(&pm_sem)) {
+		set_result_state(SUSPEND_ABORTED);
+		set_result_state(SUSPEND_PM_SEM);
+		return 0;
+	}
+
+	if (!test_suspend_state(SUSPEND_CAN_SUSPEND))
+		suspend_attempt_to_parse_resume_device();
+
+	if (!test_suspend_state(SUSPEND_CAN_SUSPEND)) {
+		printk(name_suspend "Software suspend is disabled.\n"
+			"This may be because you haven't put something along "
+			"the lines of\n\nresume2=swap:/dev/hda1\n\n"
+			"in lilo.conf or equivalent. (Where /dev/hda1 is your "
+			"swap partition).\n");
+		set_result_state(SUSPEND_ABORTED);
+		return 0;
+	}
+	
+	return 1;
+}
+

--
Nigel Cunningham		nigel at suspend2 dot net

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

* [Suspend2][ 09/16] [Suspend2] Top level routine for do_suspend.
  2006-06-26 22:33 [Suspend2][ 00/16] Suspend.c Nigel Cunningham
                   ` (7 preceding siblings ...)
  2006-06-26 22:33 ` [Suspend2][ 08/16] [Suspend2] Can suspend? Nigel Cunningham
@ 2006-06-26 22:33 ` Nigel Cunningham
  2006-06-26 22:33 ` [Suspend2][ 10/16] [Suspend2] Image exists proc entry Nigel Cunningham
                   ` (6 subsequent siblings)
  15 siblings, 0 replies; 17+ messages in thread
From: Nigel Cunningham @ 2006-06-26 22:33 UTC (permalink / raw)
  To: linux-kernel

Our top level routine for suspending - activate storage, check if we can
suspend, check if a kept image is still to be used (powerdown if so), then
prepare and save the image (including powering down). When we return from
save_image, we've either aborted during saving, or resumed at a later time.

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

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

diff --git a/kernel/power/suspend.c b/kernel/power/suspend.c
index bda4c2a..40f54f7 100644
--- a/kernel/power/suspend.c
+++ b/kernel/power/suspend.c
@@ -599,3 +599,44 @@ static int can_suspend(void)
 	return 1;
 }
 
+/*
+ * suspend_main
+ * Functionality   : First level of code for software suspend invocations.
+ *                   Stores and restores load averages (to avoid a spike),
+ *                   allocates bitmaps, freezes processes and eats memory
+ *                   as required before suspending drivers and invoking
+ *                   the 'low level' code to save the state to disk.
+ *                   By the time we return from do_suspend2_suspend, we
+ *                   have either failed to save the image or successfully
+ *                   suspended and reloaded the image. The difference can
+ *                   be discerned by checking SUSPEND_ABORTED.
+ * Called From     : 
+ */
+void suspend_main(void)
+{
+	if (suspend_activate_storage(0))
+		return;
+
+	if (!can_suspend())
+		goto cleanup;
+
+	/*
+	 * If kept image and still keeping image and suspending to RAM, we will 
+	 * return 1 after suspending and resuming (provided the power doesn't
+	 * run out.
+	 */
+	if (test_result_state(SUSPEND_KEPT_IMAGE) && check_still_keeping_image()) 
+		goto cleanup;
+
+
+	if (suspend_init() && !suspend_prepare_image() && !test_result_state(SUSPEND_ABORTED) &&
+		!test_action_state(SUSPEND_FREEZER_TEST)) {
+		suspend_prepare_status(DONT_CLEAR_BAR, "Starting to save the image..");
+		save_image();
+	}
+	
+cleanup:
+	suspend_cleanup();
+	suspend_deactivate_storage(0);
+}
+

--
Nigel Cunningham		nigel at suspend2 dot net

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

* [Suspend2][ 10/16] [Suspend2] Image exists proc entry.
  2006-06-26 22:33 [Suspend2][ 00/16] Suspend.c Nigel Cunningham
                   ` (8 preceding siblings ...)
  2006-06-26 22:33 ` [Suspend2][ 09/16] [Suspend2] Top level routine for do_suspend Nigel Cunningham
@ 2006-06-26 22:33 ` Nigel Cunningham
  2006-06-26 22:33 ` [Suspend2][ 11/16] [Suspend2] General proc entries for suspend Nigel Cunningham
                   ` (5 subsequent siblings)
  15 siblings, 0 replies; 17+ messages in thread
From: Nigel Cunningham @ 2006-06-26 22:33 UTC (permalink / raw)
  To: linux-kernel

Routines for the image_exists proc entry. Read to determine whether an
image exists at the place resume2= points to (-1 equals can't determine, 0
for no image, 1 for there is).

If an image exists, we also print the kernel version and suspend version
used to create the image on additional lines. 

Echoing to the file invalidates any image that exists.

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

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

diff --git a/kernel/power/suspend.c b/kernel/power/suspend.c
index 40f54f7..4eabb21 100644
--- a/kernel/power/suspend.c
+++ b/kernel/power/suspend.c
@@ -640,3 +640,54 @@ cleanup:
 	suspend_deactivate_storage(0);
 }
 
+/* image_exists_read
+ * 
+ * Return 0 or 1, depending on whether an image is found.
+ */
+static int image_exists_read(char *page, char **start, off_t off, int count,
+		int *eof, void *data)
+{
+	int len = 0;
+	char *result;
+	
+	if (suspend_activate_storage(0))
+		return count;
+
+	if (!test_suspend_state(SUSPEND_RESUME_DEVICE_OK))
+		suspend_attempt_to_parse_resume_device();
+
+	if (!suspend_active_writer) {
+		len = sprintf(page, "-1\n");
+	} else {
+		result = get_have_image_data();
+		if (result) {
+			len = sprintf(page, "%s",  result);
+			free_page((unsigned long) result);
+		}
+	}
+
+	*eof = 1;
+
+	suspend_deactivate_storage(0);
+
+	return len;
+}
+
+/* image_exists_write
+ * 
+ * Invalidate an image if one exists.
+ */
+static int image_exists_write(struct file *file, const char *buffer,
+		unsigned long count, void *data)
+{
+	if (suspend_activate_storage(0))
+		return count;
+
+	if (suspend_active_writer && suspend_active_writer->image_exists())
+		suspend_active_writer->invalidate_image();
+
+	suspend_deactivate_storage(0);
+
+	return count;
+}
+

--
Nigel Cunningham		nigel at suspend2 dot net

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

* [Suspend2][ 11/16] [Suspend2] General proc entries for suspend.
  2006-06-26 22:33 [Suspend2][ 00/16] Suspend.c Nigel Cunningham
                   ` (9 preceding siblings ...)
  2006-06-26 22:33 ` [Suspend2][ 10/16] [Suspend2] Image exists proc entry Nigel Cunningham
@ 2006-06-26 22:33 ` Nigel Cunningham
  2006-06-26 22:33 ` [Suspend2][ 12/16] [Suspend2] Core load routine Nigel Cunningham
                   ` (4 subsequent siblings)
  15 siblings, 0 replies; 17+ messages in thread
From: Nigel Cunningham @ 2006-06-26 22:33 UTC (permalink / raw)
  To: linux-kernel

Implement the proc entries for Suspend2's core - debug_info,
extra_pages_allowance, ignore_rootfs, image_exists, image_size_limit,
last_result, reboot, resume2, resume_commandline, version. If PM_DEBUG is
enabled, there are also entries for testing the freezer, block io, filters
speed, for adding delays at different steps and disabling pageset2. If ACPI
is enabled, the user can select sleep states S3, S4 or S5 as powerdown
methods. Keepimage mode, since it could cause damage if used without
consideration, depends on a compile time option.

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

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

diff --git a/kernel/power/suspend.c b/kernel/power/suspend.c
index 4eabb21..429d2eb 100644
--- a/kernel/power/suspend.c
+++ b/kernel/power/suspend.c
@@ -691,3 +691,208 @@ static int image_exists_write(struct fil
 	return count;
 }
 
+/*
+ * Core proc entries that aren't built in.
+ *
+ * This array contains entries that are automatically registered at
+ * boot. Modules and the console code register their own entries separately.
+ */
+static struct suspend_proc_data proc_params[] = {
+	{ .filename			= "debug_info",
+	  .permissions			= PROC_READONLY,
+	  .type				= SUSPEND_PROC_DATA_CUSTOM,
+	  .data = {
+		  .special = {
+			  .read_proc	= debuginfo_read_proc,
+		  }
+	  }
+	},
+	
+	{ .filename			= "extra_pages_allowance",
+	  .permissions			= PROC_RW,
+	  .type				= SUSPEND_PROC_DATA_LONG,
+	  .data = {
+		  .a_long = {
+			  .variable	= &extra_pd1_pages_allowance,
+			  .minimum	= 0,
+			  .maximum	= INT_MAX,
+		  }
+	  }
+	},
+	
+	{ .filename			= "ignore_rootfs",
+	  .permissions			= PROC_RW,
+	  .type				= SUSPEND_PROC_DATA_BIT,
+	  .data = {
+		  .bit = {
+			  .bit_vector	= &suspend_action,
+			  .bit		= SUSPEND_IGNORE_ROOTFS,
+		  }
+	  }
+	},
+	
+	{ .filename			= "image_exists",
+	  .permissions			= PROC_RW,
+	  .type				= SUSPEND_PROC_DATA_CUSTOM,
+	  .needs_storage_manager	= 3,
+	  .data = {
+		  .special = {
+			  .read_proc	= image_exists_read,
+			  .write_proc	= image_exists_write,
+		  }
+	  }
+	},
+
+	{ .filename			= "image_size_limit",
+	  .permissions			= PROC_RW,
+	  .type				= SUSPEND_PROC_DATA_LONG,
+	  .data = {
+		  .a_long = {
+			  .variable	= &image_size_limit,
+			  .minimum	= -2,
+			  .maximum	= 32767,
+		  }
+	  }
+	},
+
+	{ .filename			= "last_result",
+	  .permissions			= PROC_READONLY,
+	  .type				= SUSPEND_PROC_DATA_UL,
+	  .data = {
+		  .ul = {
+			  .variable	=  &suspend_result,
+		  }
+	  }
+	},
+	
+	{ .filename			= "reboot",
+	  .permissions			= PROC_RW,
+	  .type				= SUSPEND_PROC_DATA_BIT,
+	  .data = {
+		  .bit = {
+			  .bit_vector	= &suspend_action,
+			  .bit		= SUSPEND_REBOOT,
+		  }
+	  }
+	},
+	  
+	{ .filename			= "resume2",
+	  .permissions			= PROC_RW,
+	  .type				= SUSPEND_PROC_DATA_STRING,
+	  .needs_storage_manager	= 2,
+	  .data = {
+		  .string = {
+			  .variable	= resume2_file,
+			  .max_length	= 255,
+		  }
+	  },
+	  .write_proc			= attempt_to_parse_resume_device2,
+	},
+
+	{ .filename			= "resume_commandline",
+	  .permissions			= PROC_RW,
+	  .type				= SUSPEND_PROC_DATA_STRING,
+	  .data = {
+		  .string = {
+			  .variable	= suspend_resume_commandline,
+			  .max_length	= COMMAND_LINE_SIZE,
+		  }
+	  },
+	},
+
+	{ .filename			= "version",
+	  .permissions			= PROC_READONLY,
+	  .type				= SUSPEND_PROC_DATA_STRING,
+	  .data = {
+		  .string = {
+			  .variable	= suspend_core_version,
+		  }
+	  }
+	},
+
+#ifdef CONFIG_PM_DEBUG
+	{ .filename			= "freezer_test",
+	  .permissions			= PROC_RW,
+	  .type				= SUSPEND_PROC_DATA_BIT,
+	  .data = {
+		  .bit = {
+			  .bit_vector	= &suspend_action,
+			  .bit		= SUSPEND_FREEZER_TEST,
+		  }
+	  }
+	},
+
+	{ .filename			= "test_bio",
+	  .permissions			= PROC_RW,
+	  .type				= SUSPEND_PROC_DATA_BIT,
+	  .data = {
+		  .bit = {
+			  .bit_vector	= &suspend_action,
+			  .bit		= SUSPEND_TEST_BIO,
+		  }
+	  }
+	},
+
+	{ .filename			= "test_filter_speed",
+	  .permissions			= PROC_RW,
+	  .type				= SUSPEND_PROC_DATA_BIT,
+	  .data = {
+		  .bit = {
+			  .bit_vector	= &suspend_action,
+			  .bit		= SUSPEND_TEST_FILTER_SPEED,
+		  }
+	  }
+	},
+
+	{ .filename			= "slow",
+	  .permissions			= PROC_RW,
+	  .type				= SUSPEND_PROC_DATA_BIT,
+	  .data = {
+		  .bit = {
+			  .bit_vector	= &suspend_action,
+			  .bit		= SUSPEND_SLOW,
+		  }
+	  }
+	},
+	
+	{ .filename			= "no_pageset2",
+	  .permissions			= PROC_RW,
+	  .type				= SUSPEND_PROC_DATA_BIT,
+	  .data = {
+		  .bit = {
+			  .bit_vector	= &suspend_action,
+			  .bit		= SUSPEND_NO_PAGESET2,
+		  }
+	  }
+	},
+	
+#endif
+	  
+#if defined(CONFIG_ACPI)
+	{ .filename			= "powerdown_method",
+	  .permissions			= PROC_RW,
+	  .type				= SUSPEND_PROC_DATA_UL,
+	  .data = {
+		  .ul = {
+			  .variable	= &suspend_powerdown_method,
+			  .minimum	= 0,
+			  .maximum	= 5,
+		  }
+	  }
+	},
+#endif
+
+#ifdef CONFIG_SUSPEND2_KEEP_IMAGE
+	{ .filename			= "keep_image",
+	  .permissions			= PROC_RW,
+	  .type				= SUSPEND_PROC_DATA_BIT,
+	  .data = {
+		  .bit = {
+			  .bit_vector	= &suspend_action,
+			  .bit		= SUSPEND_KEEP_IMAGE,
+		  }
+	  }
+	},
+#endif
+};
+       

--
Nigel Cunningham		nigel at suspend2 dot net

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

* [Suspend2][ 12/16] [Suspend2] Core load routine.
  2006-06-26 22:33 [Suspend2][ 00/16] Suspend.c Nigel Cunningham
                   ` (10 preceding siblings ...)
  2006-06-26 22:33 ` [Suspend2][ 11/16] [Suspend2] General proc entries for suspend Nigel Cunningham
@ 2006-06-26 22:33 ` Nigel Cunningham
  2006-06-26 22:34 ` [Suspend2][ 13/16] [Suspend2] do_resume routine Nigel Cunningham
                   ` (3 subsequent siblings)
  15 siblings, 0 replies; 17+ messages in thread
From: Nigel Cunningham @ 2006-06-26 22:33 UTC (permalink / raw)
  To: linux-kernel

Routine called when the Suspend2 core is loaded.

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

 kernel/power/suspend.c |   16 +++++++++++++++-
 1 files changed, 15 insertions(+), 1 deletions(-)

diff --git a/kernel/power/suspend.c b/kernel/power/suspend.c
index 429d2eb..f7138c1 100644
--- a/kernel/power/suspend.c
+++ b/kernel/power/suspend.c
@@ -895,4 +895,18 @@ static struct suspend_proc_data proc_par
 	},
 #endif
 };
-       
+ 
+static __init int core_load(void)
+{
+	int i, numfiles = sizeof(proc_params) / sizeof(struct suspend_proc_data);
+
+	printk("Suspend2 Core.\n");
+
+	suspend_initialise_module_lists();
+
+	for (i=0; i< numfiles; i++)
+		suspend_register_procfile(&proc_params[i]);
+
+	return 0;
+}
+

--
Nigel Cunningham		nigel at suspend2 dot net

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

* [Suspend2][ 13/16] [Suspend2] do_resume routine.
  2006-06-26 22:33 [Suspend2][ 00/16] Suspend.c Nigel Cunningham
                   ` (11 preceding siblings ...)
  2006-06-26 22:33 ` [Suspend2][ 12/16] [Suspend2] Core load routine Nigel Cunningham
@ 2006-06-26 22:34 ` Nigel Cunningham
  2006-06-26 22:34 ` [Suspend2][ 14/16] [Suspend2] Try to suspend Nigel Cunningham
                   ` (2 subsequent siblings)
  15 siblings, 0 replies; 17+ messages in thread
From: Nigel Cunningham @ 2006-06-26 22:34 UTC (permalink / raw)
  To: linux-kernel

Main routine for seeing if we can resume - and doing it!

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

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

diff --git a/kernel/power/suspend.c b/kernel/power/suspend.c
index f7138c1..0f751d1 100644
--- a/kernel/power/suspend.c
+++ b/kernel/power/suspend.c
@@ -910,3 +910,101 @@ static __init int core_load(void)
 	return 0;
 }
 
+/*
+ * Called from init kernel_thread.
+ * We check if we have an image and if so we try to resume.
+ * We also start ksuspendd if configuration looks right.
+ */
+int suspend_resume(void)
+{
+	int read_image_result = 0;
+
+	if (sizeof(swp_entry_t) != sizeof(long)) {
+		printk(KERN_WARNING name_suspend
+			"The size of swp_entry_t != size of long. "
+			"Please report this!\n");
+		return 1;
+	}
+	
+	if (!resume2_file[0])
+		printk(KERN_WARNING name_suspend
+			"You need to use a resume2= command line parameter to "
+			"tell Suspend2 where to look for an image.\n");
+
+	suspend_activate_storage(0);
+
+	if (!(test_suspend_state(SUSPEND_RESUME_DEVICE_OK)) &&
+		!suspend_attempt_to_parse_resume_device()) {
+		/* 
+		 * Without a usable storage device we can do nothing - 
+		 * even if noresume is given
+		 */
+
+		if (!suspend_num_writers)
+			printk(KERN_ALERT name_suspend
+				"No writers have been registered.\n");
+		else
+			printk(KERN_ALERT name_suspend
+				"Missing or invalid storage location "
+				"(resume2= parameter). Please correct and "
+				"rerun lilo (or equivalent) before "
+				"suspending.\n");
+		suspend_deactivate_storage(0);
+		return 1;
+	}
+
+	suspend_orig_mem_free = real_nr_free_pages();
+
+	read_image_result = read_pageset1(); /* non fatal error ignored */
+
+	if (test_suspend_state(SUSPEND_NORESUME_SPECIFIED))
+		printk(KERN_WARNING name_suspend "Resuming disabled as requested.\n");
+
+	suspend_deactivate_storage(0);
+	
+	if (read_image_result)
+		return 1;
+
+	suspend2_running = 1;
+
+	suspend_atomic_restore();
+
+	BUG();
+
+	return 0;
+}
+
+/* -- Functions for kickstarting a suspend or resume --- */
+
+/*
+ * Check if we have an image and if so try to resume.
+ */
+void __suspend_try_resume(void)
+{
+	set_suspend_state(SUSPEND_TRYING_TO_RESUME);
+	
+	clear_suspend_state(SUSPEND_RESUME_NOT_DONE);
+
+	suspend_resume();
+
+	clear_suspend_state(SUSPEND_IGNORE_LOGLEVEL);
+	clear_suspend_state(SUSPEND_TRYING_TO_RESUME);
+}
+
+/* Wrapper for when called from init/do_mounts.c */
+void suspend2_try_resume(void)
+{
+	if (suspend_start_anything(0))
+		return;
+
+	__suspend_try_resume();
+
+	/* 
+	 * For initramfs, we have to clear the boot time
+	 * flag after trying to resume
+	 */
+	clear_suspend_state(SUSPEND_BOOT_TIME);
+
+	suspend_finish_anything(0);
+}
+

--
Nigel Cunningham		nigel at suspend2 dot net

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

* [Suspend2][ 14/16] [Suspend2] Try to suspend.
  2006-06-26 22:33 [Suspend2][ 00/16] Suspend.c Nigel Cunningham
                   ` (12 preceding siblings ...)
  2006-06-26 22:34 ` [Suspend2][ 13/16] [Suspend2] do_resume routine Nigel Cunningham
@ 2006-06-26 22:34 ` Nigel Cunningham
  2006-06-26 22:34 ` [Suspend2][ 15/16] [Suspend2] __init routines Nigel Cunningham
  2006-06-26 22:34 ` [Suspend2][ 16/16] [Suspend2] Suspend,c header file Nigel Cunningham
  15 siblings, 0 replies; 17+ messages in thread
From: Nigel Cunningham @ 2006-06-26 22:34 UTC (permalink / raw)
  To: linux-kernel

Called when /proc/suspend2/do_suspend is written to. It is essentially a
wrapper around suspend_main(), invoking the start_anything and
finish_anything routines first.

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

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

diff --git a/kernel/power/suspend.c b/kernel/power/suspend.c
index 0f751d1..85307c6 100644
--- a/kernel/power/suspend.c
+++ b/kernel/power/suspend.c
@@ -1008,3 +1008,19 @@ void suspend2_try_resume(void)
 	suspend_finish_anything(0);
 }
 
+/*
+ * suspend2_try_suspend
+ * Functionality   : Wrapper around suspend_main.
+ * Called From     : drivers/acpi/sleep/main.c
+ *                   kernel/reboot.c
+ */
+void suspend2_try_suspend(void)
+{
+	if (suspend_start_anything(0))
+		return;
+
+	suspend_main();
+
+	suspend_finish_anything(0);
+}
+

--
Nigel Cunningham		nigel at suspend2 dot net

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

* [Suspend2][ 15/16] [Suspend2] __init routines
  2006-06-26 22:33 [Suspend2][ 00/16] Suspend.c Nigel Cunningham
                   ` (13 preceding siblings ...)
  2006-06-26 22:34 ` [Suspend2][ 14/16] [Suspend2] Try to suspend Nigel Cunningham
@ 2006-06-26 22:34 ` Nigel Cunningham
  2006-06-26 22:34 ` [Suspend2][ 16/16] [Suspend2] Suspend,c header file Nigel Cunningham
  15 siblings, 0 replies; 17+ messages in thread
From: Nigel Cunningham @ 2006-06-26 22:34 UTC (permalink / raw)
  To: linux-kernel

Support for resume2=, noresume2 and retry_resume command line options.

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

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

diff --git a/kernel/power/suspend.c b/kernel/power/suspend.c
index 85307c6..78c77d6 100644
--- a/kernel/power/suspend.c
+++ b/kernel/power/suspend.c
@@ -1024,3 +1024,43 @@ void suspend2_try_suspend(void)
 	suspend_finish_anything(0);
 }
 
+/* --  Commandline Parameter Handling ---
+ *
+ * Resume setup: obtain the storage device.
+ */
+static int __init resume2_setup(char *str)
+{
+	if (!*str)
+		return 0;
+	
+	strncpy(resume2_file, str, 255);
+	return 0;
+}
+
+/*
+ * Allow the user to set the debug parameter from lilo, prior to resuming.
+ */
+/*
+ * Allow the user to specify that we should ignore any image found and
+ * invalidate the image if necesssary. This is equivalent to running
+ * the task queue and a sync and then turning off the power. The same
+ * precautions should be taken: fsck if you're not journalled.
+ */
+static int __init noresume2_setup(char *str)
+{
+	set_suspend_state(SUSPEND_NORESUME_SPECIFIED);
+	return 0;
+}
+
+static int __init suspend_retry_resume_setup(char *str)
+{
+	set_suspend_state(SUSPEND_RETRY_RESUME);
+	return 0;
+}
+
+__setup("noresume2", noresume2_setup);
+__setup("resume2=", resume2_setup);
+__setup("suspend_retry_resume", suspend_retry_resume_setup);
+
+late_initcall(core_load);
+EXPORT_SYMBOL(suspend_state);

--
Nigel Cunningham		nigel at suspend2 dot net

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

* [Suspend2][ 16/16] [Suspend2] Suspend,c header file.
  2006-06-26 22:33 [Suspend2][ 00/16] Suspend.c Nigel Cunningham
                   ` (14 preceding siblings ...)
  2006-06-26 22:34 ` [Suspend2][ 15/16] [Suspend2] __init routines Nigel Cunningham
@ 2006-06-26 22:34 ` Nigel Cunningham
  15 siblings, 0 replies; 17+ messages in thread
From: Nigel Cunningham @ 2006-06-26 22:34 UTC (permalink / raw)
  To: linux-kernel

Header file for kernel/power/suspend.c.

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

 kernel/power/suspend.h  |   19 +++++++++++++++++++
 kernel/power/suspend2.h |   31 +++++++++++++++++++++++++++++++
 2 files changed, 50 insertions(+), 0 deletions(-)

diff --git a/kernel/power/suspend.h b/kernel/power/suspend.h
new file mode 100644
index 0000000..0f54b5e
--- /dev/null
+++ b/kernel/power/suspend.h
@@ -0,0 +1,19 @@
+/*
+ * kernel/power/suspend.h
+ *
+ * Copyright (C) 2004-2006 Nigel Cunningham <nigel@suspend2.net>
+ *
+ * This file is released under the GPLv2.
+ *
+ * It contains declarations used throughout swsusp.
+ *
+ */
+
+#ifndef KERNEL_POWER_SUSPEND_H
+#define KERNEL_POWER_SUSPEND_H
+
+extern suspend_pagedir_t *pagedir_nosave __nosavedata;
+extern int save_image_part1(void);
+extern int suspend_atomic_restore(void);
+
+#endif
diff --git a/kernel/power/suspend2.h b/kernel/power/suspend2.h
new file mode 100644
index 0000000..c271c6b
--- /dev/null
+++ b/kernel/power/suspend2.h
@@ -0,0 +1,31 @@
+/*
+ * kernel/power/suspend2.h
+ *
+ * Copyright (C) 2004-2006 Nigel Cunningham <nigel@suspend2.net>
+ *
+ * This file is released under the GPLv2.
+ *
+ * It contains declarations used throughout swsusp and suspend2.
+ *
+ */
+#ifndef KERNEL_POWER_SUSPEND_CORE_H
+#define KERNEL_POWER_SUSPEND_CORE_H
+
+#include <linux/delay.h>
+#include <linux/bootmem.h>
+
+extern unsigned long suspend_orig_mem_free;
+
+#define KB(x) ((x) << (PAGE_SHIFT - 10))
+#define MB(x) ((x) >> (20 - PAGE_SHIFT))
+
+extern int suspend_start_anything(int starting_cycle);
+extern void suspend_finish_anything(int finishing_cycle);
+
+#if 1
+#define PRINTK(a...) do { } while(0)
+#else
+#define PRINTK(fmt, arg...) printk(KERN_DEBUG fmt, ##arg)
+#endif
+
+#endif

--
Nigel Cunningham		nigel at suspend2 dot net

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

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

Thread overview: 17+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2006-06-26 22:33 [Suspend2][ 00/16] Suspend.c Nigel Cunningham
2006-06-26 22:33 ` [Suspend2][ 01/16] [Suspend2] Suspend.c header Nigel Cunningham
2006-06-26 22:33 ` [Suspend2][ 02/16] [Suspend2] Routines called when starting or finishing anything Nigel Cunningham
2006-06-26 22:33 ` [Suspend2][ 03/16] [Suspend2] Save image Nigel Cunningham
2006-06-26 22:33 ` [Suspend2][ 04/16] [Suspend2] Get debug info Nigel Cunningham
2006-06-26 22:33 ` [Suspend2][ 05/16] [Suspend2] Allocate/free bitmaps Nigel Cunningham
2006-06-26 22:33 ` [Suspend2][ 06/16] [Suspend2] Check if still keeping an existing image Nigel Cunningham
2006-06-26 22:33 ` [Suspend2][ 07/16] [Suspend2] Suspend2 init/cleanup Nigel Cunningham
2006-06-26 22:33 ` [Suspend2][ 08/16] [Suspend2] Can suspend? Nigel Cunningham
2006-06-26 22:33 ` [Suspend2][ 09/16] [Suspend2] Top level routine for do_suspend Nigel Cunningham
2006-06-26 22:33 ` [Suspend2][ 10/16] [Suspend2] Image exists proc entry Nigel Cunningham
2006-06-26 22:33 ` [Suspend2][ 11/16] [Suspend2] General proc entries for suspend Nigel Cunningham
2006-06-26 22:33 ` [Suspend2][ 12/16] [Suspend2] Core load routine Nigel Cunningham
2006-06-26 22:34 ` [Suspend2][ 13/16] [Suspend2] do_resume routine Nigel Cunningham
2006-06-26 22:34 ` [Suspend2][ 14/16] [Suspend2] Try to suspend Nigel Cunningham
2006-06-26 22:34 ` [Suspend2][ 15/16] [Suspend2] __init routines Nigel Cunningham
2006-06-26 22:34 ` [Suspend2][ 16/16] [Suspend2] Suspend,c header file Nigel Cunningham

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).