diff options
Diffstat (limited to 'kernel/time/tick-sched.c')
-rw-r--r-- | kernel/time/tick-sched.c | 9 |
1 files changed, 7 insertions, 2 deletions
diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c index 60c9c60e9108..41be02250e08 100644 --- a/kernel/time/tick-sched.c +++ b/kernel/time/tick-sched.c | |||
@@ -276,10 +276,10 @@ static ktime_t tick_nohz_stop_sched_tick(struct tick_sched *ts, | |||
276 | { | 276 | { |
277 | unsigned long seq, last_jiffies, next_jiffies, delta_jiffies; | 277 | unsigned long seq, last_jiffies, next_jiffies, delta_jiffies; |
278 | ktime_t last_update, expires, ret = { .tv64 = 0 }; | 278 | ktime_t last_update, expires, ret = { .tv64 = 0 }; |
279 | unsigned long rcu_delta_jiffies; | ||
279 | struct clock_event_device *dev = __get_cpu_var(tick_cpu_device).evtdev; | 280 | struct clock_event_device *dev = __get_cpu_var(tick_cpu_device).evtdev; |
280 | u64 time_delta; | 281 | u64 time_delta; |
281 | 282 | ||
282 | |||
283 | /* Read jiffies and the time when jiffies were updated last */ | 283 | /* Read jiffies and the time when jiffies were updated last */ |
284 | do { | 284 | do { |
285 | seq = read_seqbegin(&xtime_lock); | 285 | seq = read_seqbegin(&xtime_lock); |
@@ -288,7 +288,7 @@ static ktime_t tick_nohz_stop_sched_tick(struct tick_sched *ts, | |||
288 | time_delta = timekeeping_max_deferment(); | 288 | time_delta = timekeeping_max_deferment(); |
289 | } while (read_seqretry(&xtime_lock, seq)); | 289 | } while (read_seqretry(&xtime_lock, seq)); |
290 | 290 | ||
291 | if (rcu_needs_cpu(cpu) || printk_needs_cpu(cpu) || | 291 | if (rcu_needs_cpu(cpu, &rcu_delta_jiffies) || printk_needs_cpu(cpu) || |
292 | arch_needs_cpu(cpu)) { | 292 | arch_needs_cpu(cpu)) { |
293 | next_jiffies = last_jiffies + 1; | 293 | next_jiffies = last_jiffies + 1; |
294 | delta_jiffies = 1; | 294 | delta_jiffies = 1; |
@@ -296,6 +296,10 @@ static ktime_t tick_nohz_stop_sched_tick(struct tick_sched *ts, | |||
296 | /* Get the next timer wheel timer */ | 296 | /* Get the next timer wheel timer */ |
297 | next_jiffies = get_next_timer_interrupt(last_jiffies); | 297 | next_jiffies = get_next_timer_interrupt(last_jiffies); |
298 | delta_jiffies = next_jiffies - last_jiffies; | 298 | delta_jiffies = next_jiffies - last_jiffies; |
299 | if (rcu_delta_jiffies < delta_jiffies) { | ||
300 | next_jiffies = last_jiffies + rcu_delta_jiffies; | ||
301 | delta_jiffies = rcu_delta_jiffies; | ||
302 | } | ||
299 | } | 303 | } |
300 | /* | 304 | /* |
301 | * Do not stop the tick, if we are only one off | 305 | * Do not stop the tick, if we are only one off |
@@ -369,6 +373,7 @@ static ktime_t tick_nohz_stop_sched_tick(struct tick_sched *ts, | |||
369 | */ | 373 | */ |
370 | if (!ts->tick_stopped) { | 374 | if (!ts->tick_stopped) { |
371 | select_nohz_load_balancer(1); | 375 | select_nohz_load_balancer(1); |
376 | calc_load_enter_idle(); | ||
372 | 377 | ||
373 | ts->last_tick = hrtimer_get_expires(&ts->sched_timer); | 378 | ts->last_tick = hrtimer_get_expires(&ts->sched_timer); |
374 | ts->tick_stopped = 1; | 379 | ts->tick_stopped = 1; |