PM / wakeup: Rework wakeup source timer cancellation
commit 1fad17fb1b
upstream.
If wakeup_source_add() is called right after wakeup_source_remove()
for the same wakeup source, timer_setup() may be called for a
potentially scheduled timer which is incorrect.
To avoid that, move the wakeup source timer cancellation from
wakeup_source_drop() to wakeup_source_remove().
Moreover, make wakeup_source_remove() clear the timer function after
canceling the timer to let wakeup_source_not_registered() treat
unregistered wakeup sources in the same way as the ones that have
never been registered.
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
Cc: 4.4+ <stable@vger.kernel.org> # 4.4+
[ rjw: Subject, changelog, merged two patches together ]
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
committed by
Greg Kroah-Hartman
parent
33c164d59f
commit
6f76eeca25
@ -113,7 +113,6 @@ void wakeup_source_drop(struct wakeup_source *ws)
|
|||||||
if (!ws)
|
if (!ws)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
del_timer_sync(&ws->timer);
|
|
||||||
__pm_relax(ws);
|
__pm_relax(ws);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(wakeup_source_drop);
|
EXPORT_SYMBOL_GPL(wakeup_source_drop);
|
||||||
@ -201,6 +200,13 @@ void wakeup_source_remove(struct wakeup_source *ws)
|
|||||||
list_del_rcu(&ws->entry);
|
list_del_rcu(&ws->entry);
|
||||||
spin_unlock_irqrestore(&events_lock, flags);
|
spin_unlock_irqrestore(&events_lock, flags);
|
||||||
synchronize_srcu(&wakeup_srcu);
|
synchronize_srcu(&wakeup_srcu);
|
||||||
|
|
||||||
|
del_timer_sync(&ws->timer);
|
||||||
|
/*
|
||||||
|
* Clear timer.function to make wakeup_source_not_registered() treat
|
||||||
|
* this wakeup source as not registered.
|
||||||
|
*/
|
||||||
|
ws->timer.function = NULL;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(wakeup_source_remove);
|
EXPORT_SYMBOL_GPL(wakeup_source_remove);
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user