diff options
-rw-r--r-- | include/linux/tick.h | 4 | ||||
-rw-r--r-- | kernel/time/tick-sched.c | 28 | ||||
-rw-r--r-- | kernel/time/timer_list.c | 1 |
3 files changed, 33 insertions, 0 deletions
diff --git a/include/linux/tick.h b/include/linux/tick.h index 0343eed40619..b232ccc0ee29 100644 --- a/include/linux/tick.h +++ b/include/linux/tick.h | |||
@@ -42,6 +42,7 @@ enum tick_nohz_mode { | |||
42 | * @idle_waketime: Time when the idle was interrupted | 42 | * @idle_waketime: Time when the idle was interrupted |
43 | * @idle_exittime: Time when the idle state was left | 43 | * @idle_exittime: Time when the idle state was left |
44 | * @idle_sleeptime: Sum of the time slept in idle with sched tick stopped | 44 | * @idle_sleeptime: Sum of the time slept in idle with sched tick stopped |
45 | * @iowait_sleeptime: Sum of the time slept in idle with sched tick stopped, with IO outstanding | ||
45 | * @sleep_length: Duration of the current idle sleep | 46 | * @sleep_length: Duration of the current idle sleep |
46 | * @do_timer_lst: CPU was the last one doing do_timer before going idle | 47 | * @do_timer_lst: CPU was the last one doing do_timer before going idle |
47 | */ | 48 | */ |
@@ -60,6 +61,7 @@ struct tick_sched { | |||
60 | ktime_t idle_waketime; | 61 | ktime_t idle_waketime; |
61 | ktime_t idle_exittime; | 62 | ktime_t idle_exittime; |
62 | ktime_t idle_sleeptime; | 63 | ktime_t idle_sleeptime; |
64 | ktime_t iowait_sleeptime; | ||
63 | ktime_t sleep_length; | 65 | ktime_t sleep_length; |
64 | unsigned long last_jiffies; | 66 | unsigned long last_jiffies; |
65 | unsigned long next_jiffies; | 67 | unsigned long next_jiffies; |
@@ -123,6 +125,7 @@ extern void tick_nohz_stop_sched_tick(int inidle); | |||
123 | extern void tick_nohz_restart_sched_tick(void); | 125 | extern void tick_nohz_restart_sched_tick(void); |
124 | extern ktime_t tick_nohz_get_sleep_length(void); | 126 | extern ktime_t tick_nohz_get_sleep_length(void); |
125 | extern u64 get_cpu_idle_time_us(int cpu, u64 *last_update_time); | 127 | extern u64 get_cpu_idle_time_us(int cpu, u64 *last_update_time); |
128 | extern u64 get_cpu_iowait_time_us(int cpu, u64 *last_update_time); | ||
126 | # else | 129 | # else |
127 | static inline void tick_nohz_stop_sched_tick(int inidle) { } | 130 | static inline void tick_nohz_stop_sched_tick(int inidle) { } |
128 | static inline void tick_nohz_restart_sched_tick(void) { } | 131 | static inline void tick_nohz_restart_sched_tick(void) { } |
@@ -133,6 +136,7 @@ static inline ktime_t tick_nohz_get_sleep_length(void) | |||
133 | return len; | 136 | return len; |
134 | } | 137 | } |
135 | static inline u64 get_cpu_idle_time_us(int cpu, u64 *unused) { return -1; } | 138 | static inline u64 get_cpu_idle_time_us(int cpu, u64 *unused) { return -1; } |
139 | static inline u64 get_cpu_iowait_time_us(int cpu, u64 *unused) { return -1; } | ||
136 | # endif /* !NO_HZ */ | 140 | # endif /* !NO_HZ */ |
137 | 141 | ||
138 | #endif | 142 | #endif |
diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c index 50953f4c42b2..1d7b9bc1c034 100644 --- a/kernel/time/tick-sched.c +++ b/kernel/time/tick-sched.c | |||
@@ -161,6 +161,8 @@ update_ts_time_stats(struct tick_sched *ts, ktime_t now, u64 *last_update_time) | |||
161 | if (ts->idle_active) { | 161 | if (ts->idle_active) { |
162 | delta = ktime_sub(now, ts->idle_entrytime); | 162 | delta = ktime_sub(now, ts->idle_entrytime); |
163 | ts->idle_sleeptime = ktime_add(ts->idle_sleeptime, delta); | 163 | ts->idle_sleeptime = ktime_add(ts->idle_sleeptime, delta); |
164 | if (nr_iowait_cpu() > 0) | ||
165 | ts->iowait_sleeptime = ktime_add(ts->iowait_sleeptime, delta); | ||
164 | ts->idle_entrytime = now; | 166 | ts->idle_entrytime = now; |
165 | } | 167 | } |
166 | 168 | ||
@@ -220,6 +222,32 @@ u64 get_cpu_idle_time_us(int cpu, u64 *last_update_time) | |||
220 | } | 222 | } |
221 | EXPORT_SYMBOL_GPL(get_cpu_idle_time_us); | 223 | EXPORT_SYMBOL_GPL(get_cpu_idle_time_us); |
222 | 224 | ||
225 | /* | ||
226 | * get_cpu_iowait_time_us - get the total iowait time of a cpu | ||
227 | * @cpu: CPU number to query | ||
228 | * @last_update_time: variable to store update time in | ||
229 | * | ||
230 | * Return the cummulative iowait time (since boot) for a given | ||
231 | * CPU, in microseconds. | ||
232 | * | ||
233 | * This time is measured via accounting rather than sampling, | ||
234 | * and is as accurate as ktime_get() is. | ||
235 | * | ||
236 | * This function returns -1 if NOHZ is not enabled. | ||
237 | */ | ||
238 | u64 get_cpu_iowait_time_us(int cpu, u64 *last_update_time) | ||
239 | { | ||
240 | struct tick_sched *ts = &per_cpu(tick_cpu_sched, cpu); | ||
241 | |||
242 | if (!tick_nohz_enabled) | ||
243 | return -1; | ||
244 | |||
245 | update_ts_time_stats(ts, ktime_get(), last_update_time); | ||
246 | |||
247 | return ktime_to_us(ts->iowait_sleeptime); | ||
248 | } | ||
249 | EXPORT_SYMBOL_GPL(get_cpu_iowait_time_us); | ||
250 | |||
223 | /** | 251 | /** |
224 | * tick_nohz_stop_sched_tick - stop the idle tick from the idle task | 252 | * tick_nohz_stop_sched_tick - stop the idle tick from the idle task |
225 | * | 253 | * |
diff --git a/kernel/time/timer_list.c b/kernel/time/timer_list.c index 1a4a7dd78777..ab8f5e33fa92 100644 --- a/kernel/time/timer_list.c +++ b/kernel/time/timer_list.c | |||
@@ -176,6 +176,7 @@ static void print_cpu(struct seq_file *m, int cpu, u64 now) | |||
176 | P_ns(idle_waketime); | 176 | P_ns(idle_waketime); |
177 | P_ns(idle_exittime); | 177 | P_ns(idle_exittime); |
178 | P_ns(idle_sleeptime); | 178 | P_ns(idle_sleeptime); |
179 | P_ns(iowait_sleeptime); | ||
179 | P(last_jiffies); | 180 | P(last_jiffies); |
180 | P(next_jiffies); | 181 | P(next_jiffies); |
181 | P_ns(idle_expires); | 182 | P_ns(idle_expires); |