| From: Doug Berger <opendmb@gmail.com> |
| Date: Wed, 25 Apr 2018 16:40:30 -0700 |
| Subject: PM / wakeup: Only update last time for active wakeup sources |
| |
| commit 2ef7c01c0cdb170142058c6d8fe0697aee4e4d7d upstream. |
| |
| When wakelock support was added, the wakeup_source_add() function |
| was updated to set the last_time value of the wakeup source. This |
| has the unintended side effect of producing confusing output from |
| pm_print_active_wakeup_sources() when a wakeup source is added |
| prior to a sleep that is blocked by a different wakeup source. |
| |
| The function pm_print_active_wakeup_sources() will search for the |
| most recently active wakeup source when no active source is found. |
| If a wakeup source is added after a different wakeup source blocks |
| the system from going to sleep it may have a later last_time value |
| than the blocking source and be output as the last active wakeup |
| source even if it has never actually been active. |
| |
| It looks to me like the change to wakeup_source_add() was made to |
| prevent the wakelock garbage collection from accidentally dropping |
| a wakelock during the narrow window between adding the wakelock to |
| the wakelock list in wakelock_lookup_add() and the activation of |
| the wakeup source in pm_wake_lock(). |
| |
| This commit changes the behavior so that only the last_time of the |
| wakeup source used by a wakelock is initialized prior to adding it |
| to the wakeup source list. This preserves the meaning of the |
| last_time value as the last time the wakeup source was active and |
| allows a wakeup source that has never been active to have a |
| last_time value of 0. |
| |
| Fixes: b86ff9820fd5 (PM / Sleep: Add user space interface for manipulating wakeup sources, v3) |
| Signed-off-by: Doug Berger <opendmb@gmail.com> |
| Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> |
| Signed-off-by: Ben Hutchings <ben@decadent.org.uk> |
| --- |
| drivers/base/power/wakeup.c | 1 - |
| kernel/power/wakelock.c | 1 + |
| 2 files changed, 1 insertion(+), 1 deletion(-) |
| |
| --- a/drivers/base/power/wakeup.c |
| +++ b/drivers/base/power/wakeup.c |
| @@ -135,7 +135,6 @@ void wakeup_source_add(struct wakeup_sou |
| spin_lock_init(&ws->lock); |
| setup_timer(&ws->timer, pm_wakeup_timer_fn, (unsigned long)ws); |
| ws->active = false; |
| - ws->last_time = ktime_get(); |
| |
| spin_lock_irqsave(&events_lock, flags); |
| list_add_rcu(&ws->entry, &wakeup_sources); |
| --- a/kernel/power/wakelock.c |
| +++ b/kernel/power/wakelock.c |
| @@ -175,6 +175,7 @@ static struct wakelock *wakelock_lookup_ |
| return ERR_PTR(-ENOMEM); |
| } |
| wl->ws.name = wl->name; |
| + wl->ws.last_time = ktime_get(); |
| wakeup_source_add(&wl->ws); |
| rb_link_node(&wl->node, parent, node); |
| rb_insert_color(&wl->node, &wakelocks_tree); |