Commit ecc8b655b38a880b578146895e0e1e2d477ca2c0
Exists in
master
and in
7 other branches
Merge branch 'timers-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kern…
…el/git/tip/linux-2.6-tip * 'timers-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip: nohz: adjust tick_nohz_stop_sched_tick() call of s390 as well nohz: prevent tick stop outside of the idle loop
Showing 15 changed files Side-by-side Diff
- arch/arm/kernel/process.c
- arch/avr32/kernel/process.c
- arch/blackfin/kernel/process.c
- arch/mips/kernel/process.c
- arch/powerpc/kernel/idle.c
- arch/powerpc/platforms/iseries/setup.c
- arch/s390/kernel/process.c
- arch/sh/kernel/process_32.c
- arch/sparc64/kernel/process.c
- arch/um/kernel/process.c
- arch/x86/kernel/process_32.c
- arch/x86/kernel/process_64.c
- include/linux/tick.h
- kernel/softirq.c
- kernel/time/tick-sched.c
arch/arm/kernel/process.c
arch/avr32/kernel/process.c
arch/blackfin/kernel/process.c
arch/mips/kernel/process.c
arch/powerpc/kernel/idle.c
arch/powerpc/platforms/iseries/setup.c
... | ... | @@ -561,7 +561,7 @@ |
561 | 561 | static void iseries_shared_idle(void) |
562 | 562 | { |
563 | 563 | while (1) { |
564 | - tick_nohz_stop_sched_tick(); | |
564 | + tick_nohz_stop_sched_tick(1); | |
565 | 565 | while (!need_resched() && !hvlpevent_is_pending()) { |
566 | 566 | local_irq_disable(); |
567 | 567 | ppc64_runlatch_off(); |
... | ... | @@ -591,7 +591,7 @@ |
591 | 591 | set_thread_flag(TIF_POLLING_NRFLAG); |
592 | 592 | |
593 | 593 | while (1) { |
594 | - tick_nohz_stop_sched_tick(); | |
594 | + tick_nohz_stop_sched_tick(1); | |
595 | 595 | if (!need_resched()) { |
596 | 596 | while (!need_resched()) { |
597 | 597 | ppc64_runlatch_off(); |
arch/s390/kernel/process.c
arch/sh/kernel/process_32.c
arch/sparc64/kernel/process.c
arch/um/kernel/process.c
arch/x86/kernel/process_32.c
arch/x86/kernel/process_64.c
include/linux/tick.h
... | ... | @@ -49,6 +49,7 @@ |
49 | 49 | unsigned long check_clocks; |
50 | 50 | enum tick_nohz_mode nohz_mode; |
51 | 51 | ktime_t idle_tick; |
52 | + int inidle; | |
52 | 53 | int tick_stopped; |
53 | 54 | unsigned long idle_jiffies; |
54 | 55 | unsigned long idle_calls; |
55 | 56 | |
... | ... | @@ -105,14 +106,14 @@ |
105 | 106 | #endif /* !CONFIG_GENERIC_CLOCKEVENTS */ |
106 | 107 | |
107 | 108 | # ifdef CONFIG_NO_HZ |
108 | -extern void tick_nohz_stop_sched_tick(void); | |
109 | +extern void tick_nohz_stop_sched_tick(int inidle); | |
109 | 110 | extern void tick_nohz_restart_sched_tick(void); |
110 | 111 | extern void tick_nohz_update_jiffies(void); |
111 | 112 | extern ktime_t tick_nohz_get_sleep_length(void); |
112 | 113 | extern void tick_nohz_stop_idle(int cpu); |
113 | 114 | extern u64 get_cpu_idle_time_us(int cpu, u64 *last_update_time); |
114 | 115 | # else |
115 | -static inline void tick_nohz_stop_sched_tick(void) { } | |
116 | +static inline void tick_nohz_stop_sched_tick(int inidle) { } | |
116 | 117 | static inline void tick_nohz_restart_sched_tick(void) { } |
117 | 118 | static inline void tick_nohz_update_jiffies(void) { } |
118 | 119 | static inline ktime_t tick_nohz_get_sleep_length(void) |
kernel/softirq.c
... | ... | @@ -286,7 +286,7 @@ |
286 | 286 | #ifdef CONFIG_NO_HZ |
287 | 287 | /* Make sure that timer wheel updates are propagated */ |
288 | 288 | if (!in_interrupt() && idle_cpu(smp_processor_id()) && !need_resched()) |
289 | - tick_nohz_stop_sched_tick(); | |
289 | + tick_nohz_stop_sched_tick(0); | |
290 | 290 | rcu_irq_exit(); |
291 | 291 | #endif |
292 | 292 | preempt_enable_no_resched(); |
kernel/time/tick-sched.c
... | ... | @@ -195,7 +195,7 @@ |
195 | 195 | * Called either from the idle loop or from irq_exit() when an idle period was |
196 | 196 | * just interrupted by an interrupt which did not cause a reschedule. |
197 | 197 | */ |
198 | -void tick_nohz_stop_sched_tick(void) | |
198 | +void tick_nohz_stop_sched_tick(int inidle) | |
199 | 199 | { |
200 | 200 | unsigned long seq, last_jiffies, next_jiffies, delta_jiffies, flags; |
201 | 201 | struct tick_sched *ts; |
... | ... | @@ -224,6 +224,11 @@ |
224 | 224 | if (unlikely(ts->nohz_mode == NOHZ_MODE_INACTIVE)) |
225 | 225 | goto end; |
226 | 226 | |
227 | + if (!inidle && !ts->inidle) | |
228 | + goto end; | |
229 | + | |
230 | + ts->inidle = 1; | |
231 | + | |
227 | 232 | if (need_resched()) |
228 | 233 | goto end; |
229 | 234 | |
230 | 235 | |
... | ... | @@ -373,10 +378,13 @@ |
373 | 378 | local_irq_disable(); |
374 | 379 | tick_nohz_stop_idle(cpu); |
375 | 380 | |
376 | - if (!ts->tick_stopped) { | |
381 | + if (!ts->inidle || !ts->tick_stopped) { | |
382 | + ts->inidle = 0; | |
377 | 383 | local_irq_enable(); |
378 | 384 | return; |
379 | 385 | } |
386 | + | |
387 | + ts->inidle = 0; | |
380 | 388 | |
381 | 389 | rcu_exit_nohz(); |
382 | 390 |