aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/time/tick-sched.c
diff options
context:
space:
mode:
authorMichal Hocko <mhocko@suse.cz>2011-08-24 03:39:30 -0400
committerThomas Gleixner <tglx@linutronix.de>2011-09-08 05:10:55 -0400
commit09a1d34f8535ecf9a347ea76f7597730c2bc0c8d (patch)
tree5de69591f64e995737a62cf26d8bb3a927b27d79 /kernel/time/tick-sched.c
parent6beea0cda8ce71c01354e688e5735c47e331e84f (diff)
nohz: Make idle/iowait counter update conditional
get_cpu_{idle,iowait}_time_us update idle/iowait counters unconditionally if the given CPU is in the idle loop. This doesn't work well outside of CPU governors which are singletons so nobody (except for IRQ) can race with them. We will need to use both functions from /proc/stat handler to properly handle nohz idle/iowait times. Make the update depend on a non NULL last_update_time argument. Signed-off-by: Michal Hocko <mhocko@suse.cz> Cc: Dave Jones <davej@redhat.com> Cc: Arnd Bergmann <arnd@arndb.de> Cc: Alexey Dobriyan <adobriyan@gmail.com> Link: http://lkml.kernel.org/r/11f23179472635ce52e78921d47a20216b872f23.1314172057.git.mhocko@suse.cz Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Diffstat (limited to 'kernel/time/tick-sched.c')
-rw-r--r--kernel/time/tick-sched.c41
1 files changed, 35 insertions, 6 deletions
diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c
index 7ab44bca6546..664c4a365439 100644
--- a/kernel/time/tick-sched.c
+++ b/kernel/time/tick-sched.c
@@ -198,7 +198,8 @@ static ktime_t tick_nohz_start_idle(int cpu, struct tick_sched *ts)
198/** 198/**
199 * get_cpu_idle_time_us - get the total idle time of a cpu 199 * get_cpu_idle_time_us - get the total idle time of a cpu
200 * @cpu: CPU number to query 200 * @cpu: CPU number to query
201 * @last_update_time: variable to store update time in 201 * @last_update_time: variable to store update time in. Do not update
202 * counters if NULL.
202 * 203 *
203 * Return the cummulative idle time (since boot) for a given 204 * Return the cummulative idle time (since boot) for a given
204 * CPU, in microseconds. 205 * CPU, in microseconds.
@@ -211,20 +212,35 @@ static ktime_t tick_nohz_start_idle(int cpu, struct tick_sched *ts)
211u64 get_cpu_idle_time_us(int cpu, u64 *last_update_time) 212u64 get_cpu_idle_time_us(int cpu, u64 *last_update_time)
212{ 213{
213 struct tick_sched *ts = &per_cpu(tick_cpu_sched, cpu); 214 struct tick_sched *ts = &per_cpu(tick_cpu_sched, cpu);
215 ktime_t now, idle;
214 216
215 if (!tick_nohz_enabled) 217 if (!tick_nohz_enabled)
216 return -1; 218 return -1;
217 219
218 update_ts_time_stats(cpu, ts, ktime_get(), last_update_time); 220 now = ktime_get();
221 if (last_update_time) {
222 update_ts_time_stats(cpu, ts, now, last_update_time);
223 idle = ts->idle_sleeptime;
224 } else {
225 if (ts->idle_active && !nr_iowait_cpu(cpu)) {
226 ktime_t delta = ktime_sub(now, ts->idle_entrytime);
227
228 idle = ktime_add(ts->idle_sleeptime, delta);
229 } else {
230 idle = ts->idle_sleeptime;
231 }
232 }
233
234 return ktime_to_us(idle);
219 235
220 return ktime_to_us(ts->idle_sleeptime);
221} 236}
222EXPORT_SYMBOL_GPL(get_cpu_idle_time_us); 237EXPORT_SYMBOL_GPL(get_cpu_idle_time_us);
223 238
224/** 239/**
225 * get_cpu_iowait_time_us - get the total iowait time of a cpu 240 * get_cpu_iowait_time_us - get the total iowait time of a cpu
226 * @cpu: CPU number to query 241 * @cpu: CPU number to query
227 * @last_update_time: variable to store update time in 242 * @last_update_time: variable to store update time in. Do not update
243 * counters if NULL.
228 * 244 *
229 * Return the cummulative iowait time (since boot) for a given 245 * Return the cummulative iowait time (since boot) for a given
230 * CPU, in microseconds. 246 * CPU, in microseconds.
@@ -237,13 +253,26 @@ EXPORT_SYMBOL_GPL(get_cpu_idle_time_us);
237u64 get_cpu_iowait_time_us(int cpu, u64 *last_update_time) 253u64 get_cpu_iowait_time_us(int cpu, u64 *last_update_time)
238{ 254{
239 struct tick_sched *ts = &per_cpu(tick_cpu_sched, cpu); 255 struct tick_sched *ts = &per_cpu(tick_cpu_sched, cpu);
256 ktime_t now, iowait;
240 257
241 if (!tick_nohz_enabled) 258 if (!tick_nohz_enabled)
242 return -1; 259 return -1;
243 260
244 update_ts_time_stats(cpu, ts, ktime_get(), last_update_time); 261 now = ktime_get();
262 if (last_update_time) {
263 update_ts_time_stats(cpu, ts, now, last_update_time);
264 iowait = ts->iowait_sleeptime;
265 } else {
266 if (ts->idle_active && nr_iowait_cpu(cpu) > 0) {
267 ktime_t delta = ktime_sub(now, ts->idle_entrytime);
268
269 iowait = ktime_add(ts->iowait_sleeptime, delta);
270 } else {
271 iowait = ts->iowait_sleeptime;
272 }
273 }
245 274
246 return ktime_to_us(ts->iowait_sleeptime); 275 return ktime_to_us(iowait);
247} 276}
248EXPORT_SYMBOL_GPL(get_cpu_iowait_time_us); 277EXPORT_SYMBOL_GPL(get_cpu_iowait_time_us);
249 278