diff options
Diffstat (limited to 'kernel/time/tick-sched.c')
| -rw-r--r-- | kernel/time/tick-sched.c | 19 |
1 files changed, 13 insertions, 6 deletions
diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c index d3f1ef4d5cbe..e0f59a21c061 100644 --- a/kernel/time/tick-sched.c +++ b/kernel/time/tick-sched.c | |||
| @@ -222,6 +222,15 @@ void tick_nohz_stop_sched_tick(int inidle) | |||
| 222 | 222 | ||
| 223 | cpu = smp_processor_id(); | 223 | cpu = smp_processor_id(); |
| 224 | ts = &per_cpu(tick_cpu_sched, cpu); | 224 | ts = &per_cpu(tick_cpu_sched, cpu); |
| 225 | |||
| 226 | /* | ||
| 227 | * Call to tick_nohz_start_idle stops the last_update_time from being | ||
| 228 | * updated. Thus, it must not be called in the event we are called from | ||
| 229 | * irq_exit() with the prior state different than idle. | ||
| 230 | */ | ||
| 231 | if (!inidle && !ts->inidle) | ||
| 232 | goto end; | ||
| 233 | |||
| 225 | now = tick_nohz_start_idle(ts); | 234 | now = tick_nohz_start_idle(ts); |
| 226 | 235 | ||
| 227 | /* | 236 | /* |
| @@ -239,9 +248,6 @@ void tick_nohz_stop_sched_tick(int inidle) | |||
| 239 | if (unlikely(ts->nohz_mode == NOHZ_MODE_INACTIVE)) | 248 | if (unlikely(ts->nohz_mode == NOHZ_MODE_INACTIVE)) |
| 240 | goto end; | 249 | goto end; |
| 241 | 250 | ||
| 242 | if (!inidle && !ts->inidle) | ||
| 243 | goto end; | ||
| 244 | |||
| 245 | ts->inidle = 1; | 251 | ts->inidle = 1; |
| 246 | 252 | ||
| 247 | if (need_resched()) | 253 | if (need_resched()) |
| @@ -349,7 +355,7 @@ void tick_nohz_stop_sched_tick(int inidle) | |||
| 349 | 355 | ||
| 350 | if (ts->nohz_mode == NOHZ_MODE_HIGHRES) { | 356 | if (ts->nohz_mode == NOHZ_MODE_HIGHRES) { |
| 351 | hrtimer_start(&ts->sched_timer, expires, | 357 | hrtimer_start(&ts->sched_timer, expires, |
| 352 | HRTIMER_MODE_ABS); | 358 | HRTIMER_MODE_ABS_PINNED); |
| 353 | /* Check, if the timer was already in the past */ | 359 | /* Check, if the timer was already in the past */ |
| 354 | if (hrtimer_active(&ts->sched_timer)) | 360 | if (hrtimer_active(&ts->sched_timer)) |
| 355 | goto out; | 361 | goto out; |
| @@ -395,7 +401,7 @@ static void tick_nohz_restart(struct tick_sched *ts, ktime_t now) | |||
| 395 | 401 | ||
| 396 | if (ts->nohz_mode == NOHZ_MODE_HIGHRES) { | 402 | if (ts->nohz_mode == NOHZ_MODE_HIGHRES) { |
| 397 | hrtimer_start_expires(&ts->sched_timer, | 403 | hrtimer_start_expires(&ts->sched_timer, |
| 398 | HRTIMER_MODE_ABS); | 404 | HRTIMER_MODE_ABS_PINNED); |
| 399 | /* Check, if the timer was already in the past */ | 405 | /* Check, if the timer was already in the past */ |
| 400 | if (hrtimer_active(&ts->sched_timer)) | 406 | if (hrtimer_active(&ts->sched_timer)) |
| 401 | break; | 407 | break; |
| @@ -698,7 +704,8 @@ void tick_setup_sched_timer(void) | |||
| 698 | 704 | ||
| 699 | for (;;) { | 705 | for (;;) { |
| 700 | hrtimer_forward(&ts->sched_timer, now, tick_period); | 706 | hrtimer_forward(&ts->sched_timer, now, tick_period); |
| 701 | hrtimer_start_expires(&ts->sched_timer, HRTIMER_MODE_ABS); | 707 | hrtimer_start_expires(&ts->sched_timer, |
| 708 | HRTIMER_MODE_ABS_PINNED); | ||
| 702 | /* Check, if the timer was already in the past */ | 709 | /* Check, if the timer was already in the past */ |
| 703 | if (hrtimer_active(&ts->sched_timer)) | 710 | if (hrtimer_active(&ts->sched_timer)) |
| 704 | break; | 711 | break; |
