mirror of https://gitee.com/openkylin/linux.git
PM: Allow wakeup events to abort freezing of tasks
If there is a wakeup event during the freezing of tasks, suspend or hibernation will fail anyway. Since try_to_freeze_tasks() can take up to 20 seconds to complete or fail, aborting it as soon as a wakeup event is detected improves the worst case wakeup latency. Based on a patch from Arve Hjønnevåg. Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl> Acked-by: Pavel Machek <pavel@ucw.cz>
This commit is contained in:
parent
5fc62aad4e
commit
dbeeec5fe8
|
@ -308,6 +308,8 @@ static inline int unregister_pm_notifier(struct notifier_block *nb)
|
|||
}
|
||||
|
||||
#define pm_notifier(fn, pri) do { (void)(fn); } while (0)
|
||||
|
||||
static inline bool pm_check_wakeup_events(void) { return true; }
|
||||
#endif /* !CONFIG_PM_SLEEP */
|
||||
|
||||
extern struct mutex pm_mutex;
|
||||
|
|
|
@ -40,6 +40,7 @@ static int try_to_freeze_tasks(bool sig_only)
|
|||
struct timeval start, end;
|
||||
u64 elapsed_csecs64;
|
||||
unsigned int elapsed_csecs;
|
||||
bool wakeup = false;
|
||||
|
||||
do_gettimeofday(&start);
|
||||
|
||||
|
@ -78,6 +79,11 @@ static int try_to_freeze_tasks(bool sig_only)
|
|||
if (!todo || time_after(jiffies, end_time))
|
||||
break;
|
||||
|
||||
if (!pm_check_wakeup_events()) {
|
||||
wakeup = true;
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* We need to retry, but first give the freezing tasks some
|
||||
* time to enter the regrigerator.
|
||||
|
@ -97,8 +103,9 @@ static int try_to_freeze_tasks(bool sig_only)
|
|||
* but it cleans up leftover PF_FREEZE requests.
|
||||
*/
|
||||
printk("\n");
|
||||
printk(KERN_ERR "Freezing of tasks failed after %d.%02d seconds "
|
||||
printk(KERN_ERR "Freezing of tasks %s after %d.%02d seconds "
|
||||
"(%d tasks refusing to freeze, wq_busy=%d):\n",
|
||||
wakeup ? "aborted" : "failed",
|
||||
elapsed_csecs / 100, elapsed_csecs % 100,
|
||||
todo - wq_busy, wq_busy);
|
||||
|
||||
|
@ -107,7 +114,7 @@ static int try_to_freeze_tasks(bool sig_only)
|
|||
read_lock(&tasklist_lock);
|
||||
do_each_thread(g, p) {
|
||||
task_lock(p);
|
||||
if (freezing(p) && !freezer_should_skip(p))
|
||||
if (!wakeup && freezing(p) && !freezer_should_skip(p))
|
||||
sched_show_task(p);
|
||||
cancel_freezing(p);
|
||||
task_unlock(p);
|
||||
|
|
Loading…
Reference in New Issue