diff options
Diffstat (limited to 'kernel/time')
| -rw-r--r-- | kernel/time/tick-sched.c | 84 | ||||
| -rw-r--r-- | kernel/time/timer_list.c | 1 |
2 files changed, 71 insertions, 14 deletions
diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c index f992762d7f51..1d7b9bc1c034 100644 --- a/kernel/time/tick-sched.c +++ b/kernel/time/tick-sched.c | |||
| @@ -150,14 +150,32 @@ static void tick_nohz_update_jiffies(ktime_t now) | |||
| 150 | touch_softlockup_watchdog(); | 150 | touch_softlockup_watchdog(); |
| 151 | } | 151 | } |
| 152 | 152 | ||
| 153 | /* | ||
| 154 | * Updates the per cpu time idle statistics counters | ||
| 155 | */ | ||
| 156 | static void | ||
| 157 | update_ts_time_stats(struct tick_sched *ts, ktime_t now, u64 *last_update_time) | ||
| 158 | { | ||
| 159 | ktime_t delta; | ||
| 160 | |||
| 161 | if (ts->idle_active) { | ||
| 162 | delta = ktime_sub(now, ts->idle_entrytime); | ||
| 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); | ||
| 166 | ts->idle_entrytime = now; | ||
| 167 | } | ||
| 168 | |||
| 169 | if (last_update_time) | ||
| 170 | *last_update_time = ktime_to_us(now); | ||
| 171 | |||
| 172 | } | ||
| 173 | |||
| 153 | static void tick_nohz_stop_idle(int cpu, ktime_t now) | 174 | static void tick_nohz_stop_idle(int cpu, ktime_t now) |
| 154 | { | 175 | { |
| 155 | struct tick_sched *ts = &per_cpu(tick_cpu_sched, cpu); | 176 | struct tick_sched *ts = &per_cpu(tick_cpu_sched, cpu); |
| 156 | ktime_t delta; | ||
| 157 | 177 | ||
| 158 | delta = ktime_sub(now, ts->idle_entrytime); | 178 | update_ts_time_stats(ts, now, NULL); |
| 159 | ts->idle_lastupdate = now; | ||
| 160 | ts->idle_sleeptime = ktime_add(ts->idle_sleeptime, delta); | ||
| 161 | ts->idle_active = 0; | 179 | ts->idle_active = 0; |
| 162 | 180 | ||
| 163 | sched_clock_idle_wakeup_event(0); | 181 | sched_clock_idle_wakeup_event(0); |
| @@ -165,20 +183,32 @@ static void tick_nohz_stop_idle(int cpu, ktime_t now) | |||
| 165 | 183 | ||
| 166 | static ktime_t tick_nohz_start_idle(struct tick_sched *ts) | 184 | static ktime_t tick_nohz_start_idle(struct tick_sched *ts) |
| 167 | { | 185 | { |
| 168 | ktime_t now, delta; | 186 | ktime_t now; |
| 169 | 187 | ||
| 170 | now = ktime_get(); | 188 | now = ktime_get(); |
| 171 | if (ts->idle_active) { | 189 | |
| 172 | delta = ktime_sub(now, ts->idle_entrytime); | 190 | update_ts_time_stats(ts, now, NULL); |
| 173 | ts->idle_lastupdate = now; | 191 | |
| 174 | ts->idle_sleeptime = ktime_add(ts->idle_sleeptime, delta); | ||
| 175 | } | ||
| 176 | ts->idle_entrytime = now; | 192 | ts->idle_entrytime = now; |
| 177 | ts->idle_active = 1; | 193 | ts->idle_active = 1; |
| 178 | sched_clock_idle_sleep_event(); | 194 | sched_clock_idle_sleep_event(); |
| 179 | return now; | 195 | return now; |
| 180 | } | 196 | } |
| 181 | 197 | ||
| 198 | /** | ||
| 199 | * get_cpu_idle_time_us - get the total idle time of a cpu | ||
| 200 | * @cpu: CPU number to query | ||
| 201 | * @last_update_time: variable to store update time in | ||
| 202 | * | ||
| 203 | * Return the cummulative idle time (since boot) for a given | ||
| 204 | * CPU, in microseconds. The idle time returned includes | ||
| 205 | * the iowait time (unlike what "top" and co report). | ||
| 206 | * | ||
| 207 | * This time is measured via accounting rather than sampling, | ||
| 208 | * and is as accurate as ktime_get() is. | ||
| 209 | * | ||
| 210 | * This function returns -1 if NOHZ is not enabled. | ||
| 211 | */ | ||
| 182 | u64 get_cpu_idle_time_us(int cpu, u64 *last_update_time) | 212 | u64 get_cpu_idle_time_us(int cpu, u64 *last_update_time) |
| 183 | { | 213 | { |
| 184 | struct tick_sched *ts = &per_cpu(tick_cpu_sched, cpu); | 214 | struct tick_sched *ts = &per_cpu(tick_cpu_sched, cpu); |
| @@ -186,15 +216,38 @@ u64 get_cpu_idle_time_us(int cpu, u64 *last_update_time) | |||
| 186 | if (!tick_nohz_enabled) | 216 | if (!tick_nohz_enabled) |
| 187 | return -1; | 217 | return -1; |
| 188 | 218 | ||
| 189 | if (ts->idle_active) | 219 | update_ts_time_stats(ts, ktime_get(), last_update_time); |
| 190 | *last_update_time = ktime_to_us(ts->idle_lastupdate); | ||
| 191 | else | ||
| 192 | *last_update_time = ktime_to_us(ktime_get()); | ||
| 193 | 220 | ||
| 194 | return ktime_to_us(ts->idle_sleeptime); | 221 | return ktime_to_us(ts->idle_sleeptime); |
| 195 | } | 222 | } |
| 196 | EXPORT_SYMBOL_GPL(get_cpu_idle_time_us); | 223 | EXPORT_SYMBOL_GPL(get_cpu_idle_time_us); |
| 197 | 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 | |||
| 198 | /** | 251 | /** |
| 199 | * 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 |
| 200 | * | 253 | * |
| @@ -262,6 +315,9 @@ void tick_nohz_stop_sched_tick(int inidle) | |||
| 262 | goto end; | 315 | goto end; |
| 263 | } | 316 | } |
| 264 | 317 | ||
| 318 | if (nohz_ratelimit(cpu)) | ||
| 319 | goto end; | ||
| 320 | |||
| 265 | ts->idle_calls++; | 321 | ts->idle_calls++; |
| 266 | /* Read jiffies and the time when jiffies were updated last */ | 322 | /* Read jiffies and the time when jiffies were updated last */ |
| 267 | do { | 323 | do { |
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); |
