LKML Archive on lore.kernel.org
help / color / mirror / Atom feed
From: "Rafael J. Wysocki" <rjw@sisk.pl>
To: Johannes Berg <johannes@sipsolutions.net>
Cc: Andrew Morton <akpm@linux-foundation.org>,
	pm list <linux-pm@lists.linux-foundation.org>,
	Pavel@smtp2.linux-foundation.org, Andi Kleen <ak@suse.de>,
	LKML <linux-kernel@vger.kernel.org>
Subject: Re: [linux-pm] Re: [PATCH -mm 2/2] Hibernation: Arbitrary boot kernel support on x86_64
Date: Mon, 27 Aug 2007 13:06:46 +0200	[thread overview]
Message-ID: <200708271306.46778.rjw@sisk.pl> (raw)
In-Reply-To: <1188069225.9529.23.camel@johannes.berg>

On Saturday, 25 August 2007 21:13, Johannes Berg wrote:
> On Fri, 2007-08-24 at 16:23 -0700, Andrew Morton wrote:
> 
> > The preferred way of doing this is via Kconfig, please.  ie: add a
> > CONFIG_HIBERNATION_HEADER to arch/x86_64/Kconfig.
> 
> > It would be better to do something like this in (say) suspend.h:
> > 
> > #ifdef CONFIG_HIBERNATION_HEADER
> > extern int arch_hibernation_header_save(void *addr, unsigned int max_size);
> > extern int arch_hibernation_header_restore(void *addr);
> > #else
> > static inline int arch_hibernation_header_save(void *addr,
> 
> In fact, I guess we don't need to bother with this at all. The generic
> code for doing this (via the utsname based header) is tiny, so as far as
> I can tell it could just be made weak symbols (by this I mean
> init_header_complete() and check_image_kernel()), and then all the
> #ifdefs can just go.

Well, I don't like the "weak symbols" stuff, but I have managed to limit the
number of additional #ifdefs in snapshot.c to just one.

The "generic" patch is now the following:

---
From: Rafael J. Wysocki <rjw@sisk.pl>

Add the bits needed for supporting arbitrary boot kernels to the common
hibernation code.

To support arbitrary boot kernels, make it possible to replace the 'struct
new_utsname' and the kernel version in the hibernation image header by some
architecture specific data that will be used to verify if the image is valid
and to restore the image.

Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
---
 kernel/power/power.h    |   20 +++++++++++++++++-
 kernel/power/snapshot.c |   53 +++++++++++++++++++++++++++++++-----------------
 2 files changed, 54 insertions(+), 19 deletions(-)

Index: linux-2.6.23-rc3/kernel/power/power.h
===================================================================
--- linux-2.6.23-rc3.orig/kernel/power/power.h	2007-08-23 23:13:34.000000000 +0200
+++ linux-2.6.23-rc3/kernel/power/power.h	2007-08-25 21:18:59.000000000 +0200
@@ -11,14 +11,32 @@ struct swsusp_info {
 	unsigned long		size;
 } __attribute__((aligned(PAGE_SIZE)));
 
+#ifdef CONFIG_HIBERNATION
+#ifdef CONFIG_ARCH_HIBERNATION_HEADER
+/* Maximum size of architecture specific data in a hibernation header */
+#define MAX_ARCH_HEADER_SIZE	(sizeof(struct new_utsname) + 4)
 
+extern int arch_hibernation_header_save(void *addr, unsigned int max_size);
+extern int arch_hibernation_header_restore(void *addr);
+
+static inline int init_header_complete(struct swsusp_info *info)
+{
+	return arch_hibernation_header_save(info, MAX_ARCH_HEADER_SIZE);
+}
+
+static inline char *check_image_kernel(struct swsusp_info *info)
+{
+	return arch_hibernation_header_restore(info) ?
+			"architecture specific data" : NULL;
+}
+#endif /* CONFIG_ARCH_HIBERNATION_HEADER */
 
-#ifdef CONFIG_HIBERNATION
 /*
  * Keep some memory free so that I/O operations can succeed without paging
  * [Might this be more than 4 MB?]
  */
 #define PAGES_FOR_IO	((4096 * 1024) >> PAGE_SHIFT)
+
 /*
  * Keep 1 MB of memory free so that device drivers can allocate some pages in
  * their .suspend() routines without breaking the suspend to disk.
Index: linux-2.6.23-rc3/kernel/power/snapshot.c
===================================================================
--- linux-2.6.23-rc3.orig/kernel/power/snapshot.c	2007-08-23 23:13:34.000000000 +0200
+++ linux-2.6.23-rc3/kernel/power/snapshot.c	2007-08-25 21:21:55.000000000 +0200
@@ -1239,17 +1239,39 @@ asmlinkage int swsusp_save(void)
 	return 0;
 }
 
-static void init_header(struct swsusp_info *info)
+#ifndef CONFIG_ARCH_HIBERNATION_HEADER
+static int init_header_complete(struct swsusp_info *info)
 {
-	memset(info, 0, sizeof(struct swsusp_info));
+	memcpy(&info->uts, init_utsname(), sizeof(struct new_utsname));
 	info->version_code = LINUX_VERSION_CODE;
+	return 0;
+}
+
+static char *check_image_kernel(struct swsusp_info *info)
+{
+	if (info->version_code != LINUX_VERSION_CODE)
+		return "kernel version";
+	if (strcmp(info->uts.sysname,init_utsname()->sysname))
+		return "system type";
+	if (strcmp(info->uts.release,init_utsname()->release))
+		return "kernel release";
+	if (strcmp(info->uts.version,init_utsname()->version))
+		return "version";
+	if (strcmp(info->uts.machine,init_utsname()->machine))
+		return "machine";
+	return NULL;
+}
+#endif /* CONFIG_ARCH_HIBERNATION_HEADER */
+
+static int init_header(struct swsusp_info *info)
+{
+	memset(info, 0, sizeof(struct swsusp_info));
 	info->num_physpages = num_physpages;
-	memcpy(&info->uts, init_utsname(), sizeof(struct new_utsname));
-	info->cpus = num_online_cpus();
 	info->image_pages = nr_copy_pages;
 	info->pages = nr_copy_pages + nr_meta_pages + 1;
 	info->size = info->pages;
 	info->size <<= PAGE_SHIFT;
+	return init_header_complete(info);
 }
 
 /**
@@ -1303,7 +1325,11 @@ int snapshot_read_next(struct snapshot_h
 			return -ENOMEM;
 	}
 	if (!handle->offset) {
-		init_header((struct swsusp_info *)buffer);
+		int error;
+
+		error = init_header((struct swsusp_info *)buffer);
+		if (error)
+			return error;
 		handle->buffer = buffer;
 		memory_bm_position_reset(&orig_bm);
 		memory_bm_position_reset(&copy_bm);
@@ -1394,22 +1420,13 @@ duplicate_memory_bitmap(struct memory_bi
 	}
 }
 
-static inline int check_header(struct swsusp_info *info)
+static int check_header(struct swsusp_info *info)
 {
-	char *reason = NULL;
+	char *reason;
 
-	if (info->version_code != LINUX_VERSION_CODE)
-		reason = "kernel version";
-	if (info->num_physpages != num_physpages)
+	reason = check_image_kernel(info);
+	if (!reason && info->num_physpages != num_physpages)
 		reason = "memory size";
-	if (strcmp(info->uts.sysname,init_utsname()->sysname))
-		reason = "system type";
-	if (strcmp(info->uts.release,init_utsname()->release))
-		reason = "kernel release";
-	if (strcmp(info->uts.version,init_utsname()->version))
-		reason = "version";
-	if (strcmp(info->uts.machine,init_utsname()->machine))
-		reason = "machine";
 	if (reason) {
 		printk(KERN_ERR "swsusp: Resume mismatch: %s\n", reason);
 		return -EPERM;

  reply	other threads:[~2007-08-27 10:56 UTC|newest]

Thread overview: 17+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-08-24 10:06 [PATCH -mm 0/2] " Rafael J. Wysocki
2007-08-24 10:09 ` [PATCH -mm 1/2] Hibernation: Arbitrary boot kernel support - generic code Rafael J. Wysocki
2007-08-24 10:11 ` [PATCH -mm 2/2] Hibernation: Arbitrary boot kernel support on x86_64 Rafael J. Wysocki
2007-08-24 10:59   ` [linux-pm] " Johannes Berg
2007-08-24 13:11     ` Rafael J. Wysocki
2007-08-24 20:46   ` Pavel Machek
2007-08-25 18:27     ` Rafael J. Wysocki
2007-08-25 18:32       ` david
2007-08-25 19:51         ` Rafael J. Wysocki
2007-08-25 20:42       ` [PATCH -mm 2/2] Hibernation: Arbitrary boot kernel support on x86_64 (updated) Rafael J. Wysocki
2007-08-27  8:28         ` Pavel Machek
2007-08-24 23:23   ` [PATCH -mm 2/2] Hibernation: Arbitrary boot kernel support on x86_64 Andrew Morton
2007-08-25 19:13     ` [linux-pm] " Johannes Berg
2007-08-27 11:06       ` Rafael J. Wysocki [this message]
2007-08-27 11:09         ` Johannes Berg
2007-08-27 11:12       ` Rafael J. Wysocki
2007-08-25 20:32     ` Rafael J. Wysocki

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=200708271306.46778.rjw@sisk.pl \
    --to=rjw@sisk.pl \
    --cc=Pavel@smtp2.linux-foundation.org \
    --cc=ak@suse.de \
    --cc=akpm@linux-foundation.org \
    --cc=johannes@sipsolutions.net \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-pm@lists.linux-foundation.org \
    --subject='Re: [linux-pm] Re: [PATCH -mm 2/2] Hibernation: Arbitrary boot kernel support on x86_64' \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link

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).