diff options
author | Jin Qian <jinqian@android.com> | 2015-05-15 21:10:37 -0400 |
---|---|---|
committer | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2015-05-18 20:47:26 -0400 |
commit | 7f436055cb0c0e17c430fb81197b42e20c2e812c (patch) | |
tree | 586e17c7d05ed5fed9c420ed84e196d7c657b4f0 | |
parent | 87e9b9f1d86c2ee9a10c2a4186a72d0af4cc963e (diff) |
PM / wakeup: add a dummy wakeup_source to record statistics
After a wakeup_source is destroyed, we lost all information such as how
long this wakeup_source has been active. Add a dummy wakeup_source to
record such info.
Signed-off-by: Jin Qian <jinqian@android.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
-rw-r--r-- | drivers/base/power/wakeup.c | 36 |
1 files changed, 36 insertions, 0 deletions
diff --git a/drivers/base/power/wakeup.c b/drivers/base/power/wakeup.c index 7b5ad9a5a6b6..87c2603b9327 100644 --- a/drivers/base/power/wakeup.c +++ b/drivers/base/power/wakeup.c | |||
@@ -56,6 +56,11 @@ static LIST_HEAD(wakeup_sources); | |||
56 | 56 | ||
57 | static DECLARE_WAIT_QUEUE_HEAD(wakeup_count_wait_queue); | 57 | static DECLARE_WAIT_QUEUE_HEAD(wakeup_count_wait_queue); |
58 | 58 | ||
59 | static struct wakeup_source deleted_ws = { | ||
60 | .name = "deleted", | ||
61 | .lock = __SPIN_LOCK_UNLOCKED(deleted_ws.lock), | ||
62 | }; | ||
63 | |||
59 | /** | 64 | /** |
60 | * wakeup_source_prepare - Prepare a new wakeup source for initialization. | 65 | * wakeup_source_prepare - Prepare a new wakeup source for initialization. |
61 | * @ws: Wakeup source to prepare. | 66 | * @ws: Wakeup source to prepare. |
@@ -107,6 +112,34 @@ void wakeup_source_drop(struct wakeup_source *ws) | |||
107 | } | 112 | } |
108 | EXPORT_SYMBOL_GPL(wakeup_source_drop); | 113 | EXPORT_SYMBOL_GPL(wakeup_source_drop); |
109 | 114 | ||
115 | /* | ||
116 | * Record wakeup_source statistics being deleted into a dummy wakeup_source. | ||
117 | */ | ||
118 | static void wakeup_source_record(struct wakeup_source *ws) | ||
119 | { | ||
120 | unsigned long flags; | ||
121 | |||
122 | spin_lock_irqsave(&deleted_ws.lock, flags); | ||
123 | |||
124 | if (ws->event_count) { | ||
125 | deleted_ws.total_time = | ||
126 | ktime_add(deleted_ws.total_time, ws->total_time); | ||
127 | deleted_ws.prevent_sleep_time = | ||
128 | ktime_add(deleted_ws.prevent_sleep_time, | ||
129 | ws->prevent_sleep_time); | ||
130 | deleted_ws.max_time = | ||
131 | ktime_compare(deleted_ws.max_time, ws->max_time) > 0 ? | ||
132 | deleted_ws.max_time : ws->max_time; | ||
133 | deleted_ws.event_count += ws->event_count; | ||
134 | deleted_ws.active_count += ws->active_count; | ||
135 | deleted_ws.relax_count += ws->relax_count; | ||
136 | deleted_ws.expire_count += ws->expire_count; | ||
137 | deleted_ws.wakeup_count += ws->wakeup_count; | ||
138 | } | ||
139 | |||
140 | spin_unlock_irqrestore(&deleted_ws.lock, flags); | ||
141 | } | ||
142 | |||
110 | /** | 143 | /** |
111 | * wakeup_source_destroy - Destroy a struct wakeup_source object. | 144 | * wakeup_source_destroy - Destroy a struct wakeup_source object. |
112 | * @ws: Wakeup source to destroy. | 145 | * @ws: Wakeup source to destroy. |
@@ -119,6 +152,7 @@ void wakeup_source_destroy(struct wakeup_source *ws) | |||
119 | return; | 152 | return; |
120 | 153 | ||
121 | wakeup_source_drop(ws); | 154 | wakeup_source_drop(ws); |
155 | wakeup_source_record(ws); | ||
122 | kfree(ws->name); | 156 | kfree(ws->name); |
123 | kfree(ws); | 157 | kfree(ws); |
124 | } | 158 | } |
@@ -912,6 +946,8 @@ static int wakeup_sources_stats_show(struct seq_file *m, void *unused) | |||
912 | print_wakeup_source_stats(m, ws); | 946 | print_wakeup_source_stats(m, ws); |
913 | rcu_read_unlock(); | 947 | rcu_read_unlock(); |
914 | 948 | ||
949 | print_wakeup_source_stats(m, &deleted_ws); | ||
950 | |||
915 | return 0; | 951 | return 0; |
916 | } | 952 | } |
917 | 953 | ||