Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6c16f42a authored by Rafael J. Wysocki's avatar Rafael J. Wysocki
Browse files

Merge branch 'pm-sleep'

* pm-sleep:
  PM / hibernate: Fix rtree_next_node() to avoid walking off list ends
  x86/power/64: Use __pa() for physical address computation
  PM / sleep: Update some system sleep documentation
parents 694d0d0b 924d8696
Loading
Loading
Loading
Loading
+26 −1
Original line number Original line Diff line number Diff line
@@ -164,7 +164,32 @@ load n/2 modules more and try again.
Again, if you find the offending module(s), it(they) must be unloaded every time
Again, if you find the offending module(s), it(they) must be unloaded every time
before hibernation, and please report the problem with it(them).
before hibernation, and please report the problem with it(them).


c) Advanced debugging
c) Using the "test_resume" hibernation option

/sys/power/disk generally tells the kernel what to do after creating a
hibernation image.  One of the available options is "test_resume" which
causes the just created image to be used for immediate restoration.  Namely,
after doing:

# echo test_resume > /sys/power/disk
# echo disk > /sys/power/state

a hibernation image will be created and a resume from it will be triggered
immediately without involving the platform firmware in any way.

That test can be used to check if failures to resume from hibernation are
related to bad interactions with the platform firmware.  That is, if the above
works every time, but resume from actual hibernation does not work or is
unreliable, the platform firmware may be responsible for the failures.

On architectures and platforms that support using different kernels to restore
hibernation images (that is, the kernel used to read the image from storage and
load it into memory is different from the one included in the image) or support
kernel address space randomization, it also can be used to check if failures
to resume may be related to the differences between the restore and image
kernels.

d) Advanced debugging


In case that hibernation does not work on your system even in the minimal
In case that hibernation does not work on your system even in the minimal
configuration and compiling more drivers as modules is not practical or some
configuration and compiling more drivers as modules is not practical or some
+76 −75
Original line number Original line Diff line number Diff line
Power Management Interface
Power Management Interface for System Sleep



Copyright (c) 2016 Intel Corp., Rafael J. Wysocki <rafael.j.wysocki@intel.com>
The power management subsystem provides a unified sysfs interface to 

userspace, regardless of what architecture or platform one is
The power management subsystem provides userspace with a unified sysfs interface
running. The interface exists in /sys/power/ directory (assuming sysfs
for system sleep regardless of the underlying system architecture or platform.
is mounted at /sys). 
The interface is located in the /sys/power/ directory (assuming that sysfs is

mounted at /sys).
/sys/power/state controls system power state. Reading from this file

returns what states are supported, which is hard-coded to 'freeze',
/sys/power/state is the system sleep state control file.
'standby' (Power-On Suspend), 'mem' (Suspend-to-RAM), and 'disk'

(Suspend-to-Disk). 
Reading from it returns a list of supported sleep states, encoded as:


Writing to this file one of those strings causes the system to
'freeze' (Suspend-to-Idle)
transition into that state. Please see the file
'standby' (Power-On Suspend)
Documentation/power/states.txt for a description of each of those
'mem' (Suspend-to-RAM)
states.
'disk' (Suspend-to-Disk)



Suspend-to-Idle is always supported.  Suspend-to-Disk is always supported
/sys/power/disk controls the operating mode of the suspend-to-disk
too as long the kernel has been configured to support hibernation at all
mechanism. Suspend-to-disk can be handled in several ways. We have a
(ie. CONFIG_HIBERNATION is set in the kernel configuration file).  Support
few options for putting the system to sleep - using the platform driver
for Suspend-to-RAM and Power-On Suspend depends on the capabilities of the
(e.g. ACPI or other suspend_ops), powering off the system or rebooting the
platform.
system (for testing).


If one of the strings listed in /sys/power/state is written to it, the system
Additionally, /sys/power/disk can be used to turn on one of the two testing
will attempt to transition into the corresponding sleep state.  Refer to
modes of the suspend-to-disk mechanism: 'testproc' or 'test'.  If the
Documentation/power/states.txt for a description of each of those states.
suspend-to-disk mechanism is in the 'testproc' mode, writing 'disk' to

/sys/power/state will cause the kernel to disable nonboot CPUs and freeze
/sys/power/disk controls the operating mode of hibernation (Suspend-to-Disk).
tasks, wait for 5 seconds, unfreeze tasks and enable nonboot CPUs.  If it is
Specifically, it tells the kernel what to do after creating a hibernation image.
in the 'test' mode, writing 'disk' to /sys/power/state will cause the kernel

to disable nonboot CPUs and freeze tasks, shrink memory, suspend devices, wait
Reading from it returns a list of supported options encoded as:
for 5 seconds, resume devices, unfreeze tasks and enable nonboot CPUs.  Then,

we are able to look in the log messages and work out, for example, which code
'platform' (put the system into sleep using a platform-provided method)
is being slow and which device drivers are misbehaving.
'shutdown' (shut the system down)

'reboot' (reboot the system)
Reading from this file will display all supported modes and the currently
'suspend' (trigger a Suspend-to-RAM transition)
selected one in brackets, for example
'test_resume' (resume-after-hibernation test mode)


	[shutdown] reboot test testproc
The currently selected option is printed in square brackets.


Writing to this file will accept one of
The 'platform' option is only available if the platform provides a special

mechanism to put the system to sleep after creating a hibernation image (ACPI
       'platform' (only if the platform supports it)
does that, for example).  The 'suspend' option is available if Suspend-to-RAM
       'shutdown'
is supported.  Refer to Documentation/power/basic_pm_debugging.txt for the
       'reboot'
description of the 'test_resume' option.
       'testproc'

       'test'
To select an option, write the string representing it to /sys/power/disk.


/sys/power/image_size controls the size of the image created by
/sys/power/image_size controls the size of hibernation images.
the suspend-to-disk mechanism.  It can be written a string

representing a non-negative integer that will be used as an upper
It can be written a string representing a non-negative integer that will be
limit of the image size, in bytes.  The suspend-to-disk mechanism will
used as a best-effort upper limit of the image size, in bytes.  The hibernation
do its best to ensure the image size will not exceed that number.  However,
core will do its best to ensure that the image size will not exceed that number.
if this turns out to be impossible, it will try to suspend anyway using the
However, if that turns out to be impossible to achieve, a hibernation image will
smallest image possible.  In particular, if "0" is written to this file, the
still be created and its size will be as small as possible.  In particular,
suspend image will be as small as possible.
writing '0' to this file will enforce hibernation images to be as small as

possible.
Reading from this file will display the current image size limit, which

is set to 2/5 of available RAM by default.
Reading from this file returns the current image size limit, which is set to

around 2/5 of available RAM by default.
/sys/power/pm_trace controls the code which saves the last PM event point in

the RTC across reboots, so that you can debug a machine that just hangs
/sys/power/pm_trace controls the PM trace mechanism saving the last suspend
during suspend (or more commonly, during resume).  Namely, the RTC is only
or resume event point in the RTC across reboots.
used to save the last PM event point if this file contains '1'.  Initially it

contains '0' which may be changed to '1' by writing a string representing a
It helps to debug hard lockups or reboots due to device driver failures that
nonzero integer into it.
occur during system suspend or resume (which is more common) more effectively.


To use this debugging feature you should attempt to suspend the machine, then
If /sys/power/pm_trace contains '1', the fingerprint of each suspend/resume
reboot it and run
event point in turn will be stored in the RTC memory (overwriting the actual

RTC information), so it will survive a system crash if one occurs right after
	dmesg -s 1000000 | grep 'hash matches'
storing it and it can be used later to identify the driver that caused the crash

to happen (see Documentation/power/s2ram.txt for more information).
CAUTION: Using it will cause your machine's real-time (CMOS) clock to be

set to a random invalid time after a resume.
Initially it contains '0' which may be changed to '1' by writing a string
representing a nonzero integer into it.
+1 −1
Original line number Original line Diff line number Diff line
@@ -113,7 +113,7 @@ static int set_up_temporary_mappings(void)
			return result;
			return result;
	}
	}


	temp_level4_pgt = (unsigned long)pgd - __PAGE_OFFSET;
	temp_level4_pgt = __pa(pgd);
	return 0;
	return 0;
}
}


+5 −5
Original line number Original line Diff line number Diff line
@@ -835,9 +835,9 @@ static bool memory_bm_pfn_present(struct memory_bitmap *bm, unsigned long pfn)
 */
 */
static bool rtree_next_node(struct memory_bitmap *bm)
static bool rtree_next_node(struct memory_bitmap *bm)
{
{
	if (!list_is_last(&bm->cur.node->list, &bm->cur.zone->leaves)) {
		bm->cur.node = list_entry(bm->cur.node->list.next,
		bm->cur.node = list_entry(bm->cur.node->list.next,
					  struct rtree_node, list);
					  struct rtree_node, list);
	if (&bm->cur.node->list != &bm->cur.zone->leaves) {
		bm->cur.node_pfn += BM_BITS_PER_BLOCK;
		bm->cur.node_pfn += BM_BITS_PER_BLOCK;
		bm->cur.node_bit  = 0;
		bm->cur.node_bit  = 0;
		touch_softlockup_watchdog();
		touch_softlockup_watchdog();
@@ -845,9 +845,9 @@ static bool rtree_next_node(struct memory_bitmap *bm)
	}
	}


	/* No more nodes, goto next zone */
	/* No more nodes, goto next zone */
	if (!list_is_last(&bm->cur.zone->list, &bm->zones)) {
		bm->cur.zone = list_entry(bm->cur.zone->list.next,
		bm->cur.zone = list_entry(bm->cur.zone->list.next,
				  struct mem_zone_bm_rtree, list);
				  struct mem_zone_bm_rtree, list);
	if (&bm->cur.zone->list != &bm->zones) {
		bm->cur.node = list_entry(bm->cur.zone->leaves.next,
		bm->cur.node = list_entry(bm->cur.zone->leaves.next,
					  struct rtree_node, list);
					  struct rtree_node, list);
		bm->cur.node_pfn = 0;
		bm->cur.node_pfn = 0;