diff options
Diffstat (limited to 'kernel/time/tick-sched.c')
-rw-r--r-- | kernel/time/tick-sched.c | 13 |
1 files changed, 5 insertions, 8 deletions
diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c index cb89fa8db110..1a21b6fdb674 100644 --- a/kernel/time/tick-sched.c +++ b/kernel/time/tick-sched.c | |||
@@ -153,6 +153,7 @@ void tick_nohz_update_jiffies(void) | |||
153 | void tick_nohz_stop_sched_tick(void) | 153 | void tick_nohz_stop_sched_tick(void) |
154 | { | 154 | { |
155 | unsigned long seq, last_jiffies, next_jiffies, delta_jiffies, flags; | 155 | unsigned long seq, last_jiffies, next_jiffies, delta_jiffies, flags; |
156 | unsigned long rt_jiffies; | ||
156 | struct tick_sched *ts; | 157 | struct tick_sched *ts; |
157 | ktime_t last_update, expires, now, delta; | 158 | ktime_t last_update, expires, now, delta; |
158 | struct clock_event_device *dev = __get_cpu_var(tick_cpu_device).evtdev; | 159 | struct clock_event_device *dev = __get_cpu_var(tick_cpu_device).evtdev; |
@@ -216,6 +217,10 @@ void tick_nohz_stop_sched_tick(void) | |||
216 | next_jiffies = get_next_timer_interrupt(last_jiffies); | 217 | next_jiffies = get_next_timer_interrupt(last_jiffies); |
217 | delta_jiffies = next_jiffies - last_jiffies; | 218 | delta_jiffies = next_jiffies - last_jiffies; |
218 | 219 | ||
220 | rt_jiffies = rt_needs_cpu(cpu); | ||
221 | if (rt_jiffies && rt_jiffies < delta_jiffies) | ||
222 | delta_jiffies = rt_jiffies; | ||
223 | |||
219 | if (rcu_needs_cpu(cpu)) | 224 | if (rcu_needs_cpu(cpu)) |
220 | delta_jiffies = 1; | 225 | delta_jiffies = 1; |
221 | /* | 226 | /* |
@@ -509,7 +514,6 @@ static enum hrtimer_restart tick_sched_timer(struct hrtimer *timer) | |||
509 | { | 514 | { |
510 | struct tick_sched *ts = | 515 | struct tick_sched *ts = |
511 | container_of(timer, struct tick_sched, sched_timer); | 516 | container_of(timer, struct tick_sched, sched_timer); |
512 | struct hrtimer_cpu_base *base = timer->base->cpu_base; | ||
513 | struct pt_regs *regs = get_irq_regs(); | 517 | struct pt_regs *regs = get_irq_regs(); |
514 | ktime_t now = ktime_get(); | 518 | ktime_t now = ktime_get(); |
515 | int cpu = smp_processor_id(); | 519 | int cpu = smp_processor_id(); |
@@ -547,15 +551,8 @@ static enum hrtimer_restart tick_sched_timer(struct hrtimer *timer) | |||
547 | touch_softlockup_watchdog(); | 551 | touch_softlockup_watchdog(); |
548 | ts->idle_jiffies++; | 552 | ts->idle_jiffies++; |
549 | } | 553 | } |
550 | /* | ||
551 | * update_process_times() might take tasklist_lock, hence | ||
552 | * drop the base lock. sched-tick hrtimers are per-CPU and | ||
553 | * never accessible by userspace APIs, so this is safe to do. | ||
554 | */ | ||
555 | spin_unlock(&base->lock); | ||
556 | update_process_times(user_mode(regs)); | 554 | update_process_times(user_mode(regs)); |
557 | profile_tick(CPU_PROFILING); | 555 | profile_tick(CPU_PROFILING); |
558 | spin_lock(&base->lock); | ||
559 | } | 556 | } |
560 | 557 | ||
561 | /* Do not restart, when we are in the idle loop */ | 558 | /* Do not restart, when we are in the idle loop */ |