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

Commit 8110efc6 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
* 'pm-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm:
  PM / Freezer: Revert 27920651 "PM / Freezer: Make fake_signal_wake_up() wake TASK_KILLABLE tasks too"
  PM / Freezer: Reimplement wait_event_freezekillable using freezer_do_not_count/freezer_count
  USB: Update last_busy time after autosuspend fails
  PM / Runtime: Automatically retry failed autosuspends
  PM / QoS: Remove redundant check
  PM / OPP: Fix build when CONFIG_PM_OPP is not set
  PM / Runtime: Fix runtime accounting calculation error
  PM / Sleep: Update freezer documentation
  PM / Sleep: Remove unused symbol 'suspend_cpu_hotplug'
  PM / Sleep: Fix race between CPU hotplug and freezer
  ACPI / PM: Add Sony VPCEB17FX to nonvs blacklist
parents 06d8eb1b d6cc7685
Loading
Loading
Loading
Loading
+4 −4
Original line number Diff line number Diff line
@@ -22,12 +22,12 @@ try_to_freeze_tasks() that sets TIF_FREEZE for all of the freezable tasks and
either wakes them up, if they are kernel threads, or sends fake signals to them,
if they are user space processes.  A task that has TIF_FREEZE set, should react
to it by calling the function called refrigerator() (defined in
kernel/power/process.c), which sets the task's PF_FROZEN flag, changes its state
kernel/freezer.c), which sets the task's PF_FROZEN flag, changes its state
to TASK_UNINTERRUPTIBLE and makes it loop until PF_FROZEN is cleared for it.
Then, we say that the task is 'frozen' and therefore the set of functions
handling this mechanism is referred to as 'the freezer' (these functions are
defined in kernel/power/process.c and include/linux/freezer.h).  User space
processes are generally frozen before kernel threads.
defined in kernel/power/process.c, kernel/freezer.c & include/linux/freezer.h).
User space processes are generally frozen before kernel threads.

It is not recommended to call refrigerator() directly.  Instead, it is
recommended to use the try_to_freeze() function (defined in
@@ -95,7 +95,7 @@ after the memory for the image has been freed, we don't want tasks to allocate
additional memory and we prevent them from doing that by freezing them earlier.
[Of course, this also means that device drivers should not allocate substantial
amounts of memory from their .suspend() callbacks before hibernation, but this
is e separate issue.]
is a separate issue.]

3. The third reason is to prevent user space processes and some kernel threads
from interfering with the suspending and resuming of devices.  A user space
+10 −0
Original line number Diff line number Diff line
@@ -789,6 +789,16 @@ will behave normally, not taking the autosuspend delay into account.
Similarly, if the power.use_autosuspend field isn't set then the autosuspend
helper functions will behave just like the non-autosuspend counterparts.

Under some circumstances a driver or subsystem may want to prevent a device
from autosuspending immediately, even though the usage counter is zero and the
autosuspend delay time has expired.  If the ->runtime_suspend() callback
returns -EAGAIN or -EBUSY, and if the next autosuspend delay expiration time is
in the future (as it normally would be if the callback invoked
pm_runtime_mark_last_busy()), the PM core will automatically reschedule the
autosuspend.  The ->runtime_suspend() callback can't do this rescheduling
itself because no suspend requests of any kind are accepted while the device is
suspending (i.e., while the callback is running).

The implementation is well suited for asynchronous use in interrupt contexts.
However such use inevitably involves races, because the PM core can't
synchronize ->runtime_suspend() callbacks with the arrival of I/O requests.
+8 −0
Original line number Diff line number Diff line
@@ -398,6 +398,14 @@ static struct dmi_system_id __initdata acpisleep_dmi_table[] = {
	},
	{
	.callback = init_nvs_nosave,
	.ident = "Sony Vaio VPCEB17FX",
	.matches = {
		DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
		DMI_MATCH(DMI_PRODUCT_NAME, "VPCEB17FX"),
		},
	},
	{
	.callback = init_nvs_nosave,
	.ident = "Sony Vaio VGN-SR11M",
	.matches = {
		DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
+17 −6
Original line number Diff line number Diff line
@@ -29,13 +29,10 @@ static int rpm_suspend(struct device *dev, int rpmflags);
void update_pm_runtime_accounting(struct device *dev)
{
	unsigned long now = jiffies;
	int delta;
	unsigned long delta;

	delta = now - dev->power.accounting_timestamp;

	if (delta < 0)
		delta = 0;

	dev->power.accounting_timestamp = now;

	if (dev->power.disable_depth > 0)
@@ -296,6 +293,9 @@ static int rpm_callback(int (*cb)(struct device *), struct device *dev)
 * the callback was running then carry it out, otherwise send an idle
 * notification for its parent (if the suspend succeeded and both
 * ignore_children of parent->power and irq_safe of dev->power are not set).
 * If ->runtime_suspend failed with -EAGAIN or -EBUSY, and if the RPM_AUTO
 * flag is set and the next autosuspend-delay expiration time is in the
 * future, schedule another autosuspend attempt.
 *
 * This function must be called under dev->power.lock with interrupts disabled.
 */
@@ -416,10 +416,21 @@ static int rpm_suspend(struct device *dev, int rpmflags)
	if (retval) {
		__update_runtime_status(dev, RPM_ACTIVE);
		dev->power.deferred_resume = false;
		if (retval == -EAGAIN || retval == -EBUSY)
		if (retval == -EAGAIN || retval == -EBUSY) {
			dev->power.runtime_error = 0;
		else

			/*
			 * If the callback routine failed an autosuspend, and
			 * if the last_busy time has been updated so that there
			 * is a new autosuspend expiration time, automatically
			 * reschedule another autosuspend.
			 */
			if ((rpmflags & RPM_AUTO) &&
			    pm_runtime_autosuspend_expiration(dev) != 0)
				goto repeat;
		} else {
			pm_runtime_cancel_pending(dev);
		}
		wake_up_all(&dev->power.wait_queue);
		goto out;
	}
+5 −0
Original line number Diff line number Diff line
@@ -1667,6 +1667,11 @@ int usb_runtime_suspend(struct device *dev)
		return -EAGAIN;

	status = usb_suspend_both(udev, PMSG_AUTO_SUSPEND);

	/* Allow a retry if autosuspend failed temporarily */
	if (status == -EAGAIN || status == -EBUSY)
		usb_mark_last_busy(udev);

	/* The PM core reacts badly unless the return code is 0,
	 * -EAGAIN, or -EBUSY, so always return -EBUSY on an error.
	 */
Loading