[lkml]   [2012]   [Feb]   [15]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
Messages in this thread
    Patch in this message
    Subject[PATCH 3/3] PM / Sleep: Make __pm_stay_awake() delete wakeup source timers
    From: Rafael J. Wysocki <>

    If __pm_stay_awake() is called after __pm_wakeup_event() for the same
    wakep source object before its timer expires, it won't cancel the
    timer, so the wakeup source will be deactivated from the timer
    function as scheduled by __pm_wakeup_event(). In that case
    __pm_stay_awake() doesn't have any effect beyond incrementing
    the wakeup source's event_count field, although it should cancel
    the timer and make the wakeup source stay active until __pm_relax()
    is called for it.

    Conversely, if __pm_wakeup_event() is called for a wakeup source
    that has been activated by __pm_stay_awake() before, it will set up
    the timer to deactivate the wakeup source, although it should leave
    it active until __pm_relax() is called for it.

    To fix the first of these problems make __pm_stay_awake() delete the
    wakeup source's timer and ensure that it won't be deactivated from
    the timer funtion afterwards by clearing its timer_expires field.

    To fix the second one, make __pm_wakeup_event() skip setting up the
    timer if it sees that the wakeup source is active and its
    timer_expires field is zero, which means that it has been activated
    by __pm_stay_awake().

    Reported-by: Arve Hjønnevåg <>
    Signed-off-by: Rafael J. Wysocki <>
    drivers/base/power/wakeup.c | 12 +++++++++++-
    1 file changed, 11 insertions(+), 1 deletion(-)

    Index: linux/drivers/base/power/wakeup.c
    --- linux.orig/drivers/base/power/wakeup.c
    +++ linux/drivers/base/power/wakeup.c
    @@ -365,9 +365,15 @@ void __pm_stay_awake(struct wakeup_sourc

    spin_lock_irqsave(&ws->lock, flags);
    + del_timer(&ws->timer);
    + ws->timer_expires = 0;
    if (!ws->active)
    spin_unlock_irqrestore(&ws->lock, flags);
    @@ -529,8 +535,12 @@ void __pm_wakeup_event(struct wakeup_sou
    spin_lock_irqsave(&ws->lock, flags);

    - if (!ws->active)
    + if (ws->active) {
    + if (!ws->timer_expires)
    + goto unlock;
    + } else {
    + }

    if (!msec) {
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to
    More majordomo info at
    Please read the FAQ at

     \ /
      Last update: 2012-02-15 23:23    [W:5.589 / U:0.048 seconds]
    ©2003-2017 Jasper Spaans. hosted at Digital OceanAdvertise on this site