forked from luck/tmp_suning_uos_patched
PM / wakeup: Rework wakeup source timer cancellation
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>
This commit is contained in:
parent
ef8006846a
commit
1fad17fb1b
|
@ -118,7 +118,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);
|
||||||
|
@ -205,6 +204,13 @@ void wakeup_source_remove(struct wakeup_source *ws)
|
||||||
list_del_rcu(&ws->entry);
|
list_del_rcu(&ws->entry);
|
||||||
raw_spin_unlock_irqrestore(&events_lock, flags);
|
raw_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);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user