diff options
| author | Arjan van de Ven <arjan@linux.intel.com> | 2010-05-09 11:25:23 -0400 |
|---|---|---|
| committer | Ingo Molnar <mingo@elte.hu> | 2010-05-09 13:35:27 -0400 |
| commit | 0224cf4c5ee0d7faec83956b8e21f7d89e3df3bd (patch) | |
| tree | daac87f9766d1a6c71bcff021414d3deaae40da1 | |
| parent | e0e37c200f1357db0dd986edb359c41c57d24f6e (diff) | |
sched: Intoduce get_cpu_iowait_time_us()
For the ondemand cpufreq governor, it is desired that the iowait
time is microaccounted in a similar way as idle time is.
This patch introduces the infrastructure to account and expose
this information via the get_cpu_iowait_time_us() function.
[akpm@linux-foundation.org: fix CONFIG_NO_HZ=n build]
Signed-off-by: Arjan van de Ven <arjan@linux.intel.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Reviewed-by: Rik van Riel <riel@redhat.com>
Acked-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: davej@redhat.com
LKML-Reference: <20100509082523.284feab6@infradead.org>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
| -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); |
