mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-29 19:21:31 -04:00
PM / reboot: Eliminate race between reboot and suspend
At present, "systemctl suspend" and "shutdown" can run in parrallel. A system can suspend after devices_shutdown(), and resume. Then the shutdown task goes on to power off. This causes many devices are not really shut off. Hence replacing reboot_mutex with system_transition_mutex (renamed from pm_mutex) to achieve the exclusion. The renaming of pm_mutex as system_transition_mutex can be better to reflect the purpose of the mutex. Signed-off-by: Pingfan Liu <[email protected]> Acked-by: Pavel Machek <[email protected]> Signed-off-by: Rafael J. Wysocki <[email protected]>
This commit is contained in:
parent
82837ad5bd
commit
55f2503c3b
10 changed files with 40 additions and 36 deletions
|
|
@ -204,26 +204,26 @@ VI. Are there any precautions to be taken to prevent freezing failures?
|
|||
|
||||
Yes, there are.
|
||||
|
||||
First of all, grabbing the 'pm_mutex' lock to mutually exclude a piece of code
|
||||
First of all, grabbing the 'system_transition_mutex' lock to mutually exclude a piece of code
|
||||
from system-wide sleep such as suspend/hibernation is not encouraged.
|
||||
If possible, that piece of code must instead hook onto the suspend/hibernation
|
||||
notifiers to achieve mutual exclusion. Look at the CPU-Hotplug code
|
||||
(kernel/cpu.c) for an example.
|
||||
|
||||
However, if that is not feasible, and grabbing 'pm_mutex' is deemed necessary,
|
||||
it is strongly discouraged to directly call mutex_[un]lock(&pm_mutex) since
|
||||
However, if that is not feasible, and grabbing 'system_transition_mutex' is deemed necessary,
|
||||
it is strongly discouraged to directly call mutex_[un]lock(&system_transition_mutex) since
|
||||
that could lead to freezing failures, because if the suspend/hibernate code
|
||||
successfully acquired the 'pm_mutex' lock, and hence that other entity failed
|
||||
successfully acquired the 'system_transition_mutex' lock, and hence that other entity failed
|
||||
to acquire the lock, then that task would get blocked in TASK_UNINTERRUPTIBLE
|
||||
state. As a consequence, the freezer would not be able to freeze that task,
|
||||
leading to freezing failure.
|
||||
|
||||
However, the [un]lock_system_sleep() APIs are safe to use in this scenario,
|
||||
since they ask the freezer to skip freezing this task, since it is anyway
|
||||
"frozen enough" as it is blocked on 'pm_mutex', which will be released
|
||||
"frozen enough" as it is blocked on 'system_transition_mutex', which will be released
|
||||
only after the entire suspend/hibernation sequence is complete.
|
||||
So, to summarize, use [un]lock_system_sleep() instead of directly using
|
||||
mutex_[un]lock(&pm_mutex). That would prevent freezing failures.
|
||||
mutex_[un]lock(&system_transition_mutex). That would prevent freezing failures.
|
||||
|
||||
V. Miscellaneous
|
||||
/sys/power/pm_freeze_timeout controls how long it will cost at most to freeze
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ More details follow:
|
|||
sysfs file
|
||||
|
|
||||
v
|
||||
Acquire pm_mutex lock
|
||||
Acquire system_transition_mutex lock
|
||||
|
|
||||
v
|
||||
Send PM_SUSPEND_PREPARE
|
||||
|
|
@ -96,10 +96,10 @@ execution during resume):
|
|||
|
||||
* thaw tasks
|
||||
* send PM_POST_SUSPEND notifications
|
||||
* Release pm_mutex lock.
|
||||
* Release system_transition_mutex lock.
|
||||
|
||||
|
||||
It is to be noted here that the pm_mutex lock is acquired at the very
|
||||
It is to be noted here that the system_transition_mutex lock is acquired at the very
|
||||
beginning, when we are just starting out to suspend, and then released only
|
||||
after the entire cycle is complete (i.e., suspend + resume).
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue