summaryrefslogtreecommitdiffstats
path: root/drivers/base/power
diff options
context:
space:
mode:
authorVincent Guittot <vincent.guittot@linaro.org>2019-02-21 08:59:02 +0100
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2019-02-21 10:29:00 +0100
commit74fb44863084275b952f21ec6a024af0e2e75cb8 (patch)
tree6d5f00f222dba81808cdde588f2660ab8163810a /drivers/base/power
parenta3b22b9f11d9fbc48b0291ea92259a5a810e9438 (diff)
downloadlinux-74fb44863084275b952f21ec6a024af0e2e75cb8.tar.bz2
PM-runtime: Fix deadlock when canceling hrtimer
When rpm_resume() desactivates the autosuspend timer, it should only try to cancel hrtimer but not wait for the handler to finish, because both rpm_resume() and pm_suspend_timer_fn() take the power.lock. A deadlock is possible as follows: CPU0 CPU1 rpm_resume() spin_lock_irqsave pm_suspend_timer_fn() spin_lock_irqsave pm_runtime_deactivate_timer() hrtimer_cancel() It is sufficient to call hrtimer_try_to_cancel() from pm_runtime_deactivate_timer(), because dev->power.timer_expires reset to 0 by it, so use that function instead of hrtimer_cancel(). Fixes: 8234f6734c5d ("PM-runtime: Switch autosuspend over to using hrtimers") Reported-by: Sunzhaosheng Sun(Zhaosheng) <sunzhaosheng@hisilicon.com> Signed-off-by: Vincent Guittot <vincent.guittot@linaro.org> [ rjw: Changelog ] Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Diffstat (limited to 'drivers/base/power')
-rw-r--r--drivers/base/power/runtime.c2
1 files changed, 1 insertions, 1 deletions
diff --git a/drivers/base/power/runtime.c b/drivers/base/power/runtime.c
index 0ea2139c50d8..ccd296dbb95c 100644
--- a/drivers/base/power/runtime.c
+++ b/drivers/base/power/runtime.c
@@ -95,7 +95,7 @@ static void __update_runtime_status(struct device *dev, enum rpm_status status)
static void pm_runtime_deactivate_timer(struct device *dev)
{
if (dev->power.timer_expires > 0) {
- hrtimer_cancel(&dev->power.suspend_timer);
+ hrtimer_try_to_cancel(&dev->power.suspend_timer);
dev->power.timer_expires = 0;
}
}