diff mbox

[RFC,v2] PM / hibernate: Introduce snapshot test mode for hibernation

Message ID 1468390116-957-1-git-send-email-yu.c.chen@intel.com (mailing list archive)
State Changes Requested, archived
Headers show

Commit Message

Chen Yu July 13, 2016, 6:08 a.m. UTC
This mode is used to verify if the snapshot data written to
the swap device can be successfully restored to the memory. It
is useful to ease the debugging process on hibernation,
since this mode can not only bypass the BIOSen/bootloader,
but also the system re-initialization.

For example:
$ sudo echo snapshot > /sys/power/pm_test
$ sudo echo disk > /sys/power/state

[  267.959784] PM: Image saving progress:  80%
[  268.038669] PM: Image saving progress:  90%
[  268.111745] PM: Image saving progress: 100%
[  268.129269] PM: Image saving done.
[  268.133485] PM: Wrote 518612 kbytes in 0.75 seconds (691.48 MB/s)
[  268.140564] PM: S|
[  268.160067] hibernation debug: Waiting for 5 seconds.
...
[  273.508638] PM: Looking for hibernation image.
[  273.516583] PM: Image signature found, resuming
[  273.926547] PM: Loading and decompressing image data (129653 pages)...
[  274.122452] PM: Image loading progress:   0%
[  274.322127] PM: Image loading progress:  10%
...

Rebased on top of linux-next.

Suggested-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Signed-off-by: Chen Yu <yu.c.chen@intel.com>
---
 kernel/power/hibernate.c | 10 ++++++++--
 kernel/power/main.c      |  3 +++
 kernel/power/power.h     |  3 +++
 kernel/power/swap.c      |  7 +++++++
 4 files changed, 21 insertions(+), 2 deletions(-)

Comments

Rafael J. Wysocki July 13, 2016, 12:07 p.m. UTC | #1
On Wed, Jul 13, 2016 at 8:08 AM, Chen Yu <yu.c.chen@intel.com> wrote:
> This mode is used to verify if the snapshot data written to
> the swap device can be successfully restored to the memory. It
> is useful to ease the debugging process on hibernation,
> since this mode can not only bypass the BIOSen/bootloader,
> but also the system re-initialization.
>
> For example:
> $ sudo echo snapshot > /sys/power/pm_test
> $ sudo echo disk > /sys/power/state
>
> [  267.959784] PM: Image saving progress:  80%
> [  268.038669] PM: Image saving progress:  90%
> [  268.111745] PM: Image saving progress: 100%
> [  268.129269] PM: Image saving done.
> [  268.133485] PM: Wrote 518612 kbytes in 0.75 seconds (691.48 MB/s)
> [  268.140564] PM: S|
> [  268.160067] hibernation debug: Waiting for 5 seconds.
> ...
> [  273.508638] PM: Looking for hibernation image.
> [  273.516583] PM: Image signature found, resuming
> [  273.926547] PM: Loading and decompressing image data (129653 pages)...
> [  274.122452] PM: Image loading progress:   0%
> [  274.322127] PM: Image loading progress:  10%
> ...
>
> Rebased on top of linux-next.
>
> Suggested-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
> Signed-off-by: Chen Yu <yu.c.chen@intel.com>
> ---
>  kernel/power/hibernate.c | 10 ++++++++--
>  kernel/power/main.c      |  3 +++
>  kernel/power/power.h     |  3 +++
>  kernel/power/swap.c      |  7 +++++++
>  4 files changed, 21 insertions(+), 2 deletions(-)
>
> diff --git a/kernel/power/hibernate.c b/kernel/power/hibernate.c
> index 51441d8..30cc5b4 100644
> --- a/kernel/power/hibernate.c
> +++ b/kernel/power/hibernate.c
> @@ -43,6 +43,7 @@ static char resume_file[256] = CONFIG_PM_STD_PARTITION;
>  dev_t swsusp_resume_device;
>  sector_t swsusp_resume_block;
>  __visible int in_suspend __nosavedata;
> +static int software_resume(void);
>
>  enum {
>         HIBERNATION_INVALID,
> @@ -647,7 +648,7 @@ static void power_down(void)
>   */
>  int hibernate(void)
>  {
> -       int error, nr_calls = 0;
> +       int error, nr_calls = 0, snapshot_test = 0;

Why can't snapshot_test be a bool variable?

Thanks,
Rafael
--
To unsubscribe from this list: send the line "unsubscribe linux-pm" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Chen Yu July 13, 2016, 12:50 p.m. UTC | #2
DQo+IC0tLS0tT3JpZ2luYWwgTWVzc2FnZS0tLS0tDQo+IEZyb206IHJqd3lzb2NraUBnbWFpbC5j
b20gW21haWx0bzpyand5c29ja2lAZ21haWwuY29tXSBPbiBCZWhhbGYgT2YNCj4gUmFmYWVsIEou
IFd5c29ja2kNCj4gU2VudDogV2VkbmVzZGF5LCBKdWx5IDEzLCAyMDE2IDg6MDcgUE0NCj4gVG86
IENoZW4sIFl1IEMNCj4gQ2M6IExpbnV4IFBNOyBSYWZhZWwgSiAuIFd5c29ja2k7IFBhdmVsIE1h
Y2hlazsgTGVuIEJyb3duOyBMaW51eCBLZXJuZWwNCj4gTWFpbGluZyBMaXN0DQo+IFN1YmplY3Q6
IFJlOiBbUEFUQ0hdW1JGQyB2Ml0gUE0gLyBoaWJlcm5hdGU6IEludHJvZHVjZSBzbmFwc2hvdCB0
ZXN0IG1vZGUgZm9yDQo+IGhpYmVybmF0aW9uDQo+IA0KPiBPbiBXZWQsIEp1bCAxMywgMjAxNiBh
dCA4OjA4IEFNLCBDaGVuIFl1IDx5dS5jLmNoZW5AaW50ZWwuY29tPiB3cm90ZToNCj4gPiBUaGlz
IG1vZGUgaXMgdXNlZCB0byB2ZXJpZnkgaWYgdGhlIHNuYXBzaG90IGRhdGEgd3JpdHRlbiB0byB0
aGUgc3dhcA0KPiA+IGRldmljZSBjYW4gYmUgc3VjY2Vzc2Z1bGx5IHJlc3RvcmVkIHRvIHRoZSBt
ZW1vcnkuIEl0IGlzIHVzZWZ1bCB0bw0KPiA+IGVhc2UgdGhlIGRlYnVnZ2luZyBwcm9jZXNzIG9u
IGhpYmVybmF0aW9uLCBzaW5jZSB0aGlzIG1vZGUgY2FuIG5vdA0KPiA+IG9ubHkgYnlwYXNzIHRo
ZSBCSU9TZW4vYm9vdGxvYWRlciwgYnV0IGFsc28gdGhlIHN5c3RlbQ0KPiA+IHJlLWluaXRpYWxp
emF0aW9uLg0KPiA+DQo+ID4gRm9yIGV4YW1wbGU6DQo+ID4gJCBzdWRvIGVjaG8gc25hcHNob3Qg
PiAvc3lzL3Bvd2VyL3BtX3Rlc3QgJCBzdWRvIGVjaG8gZGlzayA+DQo+ID4gL3N5cy9wb3dlci9z
dGF0ZQ0KPiA+DQo+ID4gWyAgMjY3Ljk1OTc4NF0gUE06IEltYWdlIHNhdmluZyBwcm9ncmVzczog
IDgwJSBbICAyNjguMDM4NjY5XSBQTToNCj4gPiBJbWFnZSBzYXZpbmcgcHJvZ3Jlc3M6ICA5MCUg
WyAgMjY4LjExMTc0NV0gUE06IEltYWdlIHNhdmluZyBwcm9ncmVzczoNCj4gPiAxMDAlIFsgIDI2
OC4xMjkyNjldIFBNOiBJbWFnZSBzYXZpbmcgZG9uZS4NCj4gPiBbICAyNjguMTMzNDg1XSBQTTog
V3JvdGUgNTE4NjEyIGtieXRlcyBpbiAwLjc1IHNlY29uZHMgKDY5MS40OCBNQi9zKSBbDQo+ID4g
MjY4LjE0MDU2NF0gUE06IFN8IFsgIDI2OC4xNjAwNjddIGhpYmVybmF0aW9uIGRlYnVnOiBXYWl0
aW5nIGZvciA1DQo+ID4gc2Vjb25kcy4NCj4gPiAuLi4NCj4gPiBbICAyNzMuNTA4NjM4XSBQTTog
TG9va2luZyBmb3IgaGliZXJuYXRpb24gaW1hZ2UuDQo+ID4gWyAgMjczLjUxNjU4M10gUE06IElt
YWdlIHNpZ25hdHVyZSBmb3VuZCwgcmVzdW1pbmcgWyAgMjczLjkyNjU0N10gUE06DQo+ID4gTG9h
ZGluZyBhbmQgZGVjb21wcmVzc2luZyBpbWFnZSBkYXRhICgxMjk2NTMgcGFnZXMpLi4uDQo+ID4g
WyAgMjc0LjEyMjQ1Ml0gUE06IEltYWdlIGxvYWRpbmcgcHJvZ3Jlc3M6ICAgMCUNCj4gPiBbICAy
NzQuMzIyMTI3XSBQTTogSW1hZ2UgbG9hZGluZyBwcm9ncmVzczogIDEwJSAuLi4NCj4gPg0KPiA+
IFJlYmFzZWQgb24gdG9wIG9mIGxpbnV4LW5leHQuDQo+ID4NCj4gPiBTdWdnZXN0ZWQtYnk6IFJh
ZmFlbCBKLiBXeXNvY2tpIDxyYWZhZWwuai53eXNvY2tpQGludGVsLmNvbT4NCj4gPiBTaWduZWQt
b2ZmLWJ5OiBDaGVuIFl1IDx5dS5jLmNoZW5AaW50ZWwuY29tPg0KPiA+IC0tLQ0KPiA+ICBrZXJu
ZWwvcG93ZXIvaGliZXJuYXRlLmMgfCAxMCArKysrKysrKy0tDQo+ID4gIGtlcm5lbC9wb3dlci9t
YWluLmMgICAgICB8ICAzICsrKw0KPiA+ICBrZXJuZWwvcG93ZXIvcG93ZXIuaCAgICAgfCAgMyAr
KysNCj4gPiAga2VybmVsL3Bvd2VyL3N3YXAuYyAgICAgIHwgIDcgKysrKysrKw0KPiA+ICA0IGZp
bGVzIGNoYW5nZWQsIDIxIGluc2VydGlvbnMoKyksIDIgZGVsZXRpb25zKC0pDQo+ID4NCj4gPiBk
aWZmIC0tZ2l0IGEva2VybmVsL3Bvd2VyL2hpYmVybmF0ZS5jIGIva2VybmVsL3Bvd2VyL2hpYmVy
bmF0ZS5jIGluZGV4DQo+ID4gNTE0NDFkOC4uMzBjYzViNCAxMDA2NDQNCj4gPiAtLS0gYS9rZXJu
ZWwvcG93ZXIvaGliZXJuYXRlLmMNCj4gPiArKysgYi9rZXJuZWwvcG93ZXIvaGliZXJuYXRlLmMN
Cj4gPiBAQCAtNDMsNiArNDMsNyBAQCBzdGF0aWMgY2hhciByZXN1bWVfZmlsZVsyNTZdID0NCj4g
PiBDT05GSUdfUE1fU1REX1BBUlRJVElPTjsgIGRldl90IHN3c3VzcF9yZXN1bWVfZGV2aWNlOyAg
c2VjdG9yX3QNCj4gPiBzd3N1c3BfcmVzdW1lX2Jsb2NrOyAgX192aXNpYmxlIGludCBpbl9zdXNw
ZW5kIF9fbm9zYXZlZGF0YTsNCj4gPiArc3RhdGljIGludCBzb2Z0d2FyZV9yZXN1bWUodm9pZCk7
DQo+ID4NCj4gPiAgZW51bSB7DQo+ID4gICAgICAgICBISUJFUk5BVElPTl9JTlZBTElELA0KPiA+
IEBAIC02NDcsNyArNjQ4LDcgQEAgc3RhdGljIHZvaWQgcG93ZXJfZG93bih2b2lkKQ0KPiA+ICAg
Ki8NCj4gPiAgaW50IGhpYmVybmF0ZSh2b2lkKQ0KPiA+ICB7DQo+ID4gLSAgICAgICBpbnQgZXJy
b3IsIG5yX2NhbGxzID0gMDsNCj4gPiArICAgICAgIGludCBlcnJvciwgbnJfY2FsbHMgPSAwLCBz
bmFwc2hvdF90ZXN0ID0gMDsNCj4gDQo+IFdoeSBjYW4ndCBzbmFwc2hvdF90ZXN0IGJlIGEgYm9v
bCB2YXJpYWJsZT8NCkFoIHllcywgaXQgd2FzIGEgYm9vbCwgSSB3YXMganVzdCB0aGlua2luZyB0
byBhZGQgdGhpcyBuZXcgdmFyaWFibGUNCnNpbWlsYXIgdG8gdGhlIHZhcmlhYmxlICdlcnJvcicu
IEknbGwgY2hhbmdlIGl0IHRvIGJvb2wgaW4gbmV4dCB2ZXJzaW9uLCBhbmQgYWxzbw0KYWRkIGRv
Y3VtZW50IGFzIFBhdmVsIHN1Z2dlc3RlZC4gDQo+IA0KPiBUaGFua3MsDQo+IFJhZmFlbA0KDQp0
aGFua3MsDQpZdQ0K
--
To unsubscribe from this list: send the line "unsubscribe linux-pm" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

diff --git a/kernel/power/hibernate.c b/kernel/power/hibernate.c
index 51441d8..30cc5b4 100644
--- a/kernel/power/hibernate.c
+++ b/kernel/power/hibernate.c
@@ -43,6 +43,7 @@  static char resume_file[256] = CONFIG_PM_STD_PARTITION;
 dev_t swsusp_resume_device;
 sector_t swsusp_resume_block;
 __visible int in_suspend __nosavedata;
+static int software_resume(void);
 
 enum {
 	HIBERNATION_INVALID,
@@ -647,7 +648,7 @@  static void power_down(void)
  */
 int hibernate(void)
 {
-	int error, nr_calls = 0;
+	int error, nr_calls = 0, snapshot_test = 0;
 
 	if (!hibernation_available()) {
 		pr_debug("PM: Hibernation not available.\n");
@@ -699,7 +700,9 @@  int hibernate(void)
 		pr_debug("PM: writing image.\n");
 		error = swsusp_write(flags);
 		swsusp_free();
-		if (!error)
+		if (hibernation_test(TEST_SNAPSHOT))
+			snapshot_test = 1;
+		if (!error && !snapshot_test)
 			power_down();
 		in_suspend = 0;
 		pm_restore_gfp_mask();
@@ -721,6 +724,9 @@  int hibernate(void)
 	atomic_inc(&snapshot_device_available);
  Unlock:
 	unlock_system_sleep();
+	if (snapshot_test)
+		software_resume();
+
 	return error;
 }
 
diff --git a/kernel/power/main.c b/kernel/power/main.c
index 5ea50b1..80fe48e 100644
--- a/kernel/power/main.c
+++ b/kernel/power/main.c
@@ -83,6 +83,9 @@  int pm_test_level = TEST_NONE;
 
 static const char * const pm_tests[__TEST_AFTER_LAST] = {
 	[TEST_NONE] = "none",
+#ifdef CONFIG_HIBERNATION
+	[TEST_SNAPSHOT] = "snapshot",
+#endif
 	[TEST_CORE] = "core",
 	[TEST_CPUS] = "processors",
 	[TEST_PLATFORM] = "platform",
diff --git a/kernel/power/power.h b/kernel/power/power.h
index 064963e..101d636 100644
--- a/kernel/power/power.h
+++ b/kernel/power/power.h
@@ -225,6 +225,9 @@  static inline int restore_highmem(void) { return 0; }
 enum {
 	/* keep first */
 	TEST_NONE,
+#ifdef CONFIG_HIBERNATION
+	TEST_SNAPSHOT,
+#endif
 	TEST_CORE,
 	TEST_CPUS,
 	TEST_PLATFORM,
diff --git a/kernel/power/swap.c b/kernel/power/swap.c
index 160e100..facd71b 100644
--- a/kernel/power/swap.c
+++ b/kernel/power/swap.c
@@ -348,6 +348,13 @@  static int swsusp_swap_check(void)
 	if (res < 0)
 		blkdev_put(hib_resume_bdev, FMODE_WRITE);
 
+	/*
+	 * Update the resume device to the one actually used,
+	 * so software_resume() can use it in case it is invoked
+	 * from hibernate() to test the snapshot.
+	 */
+	swsusp_resume_device = hib_resume_bdev->bd_dev;
+
 	return res;
 }