Commit ecc8b655b38a880b578146895e0e1e2d477ca2c0

Authored by Linus Torvalds

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
... ... @@ -162,7 +162,7 @@
162 162 if (!idle)
163 163 idle = default_idle;
164 164 leds_event(led_idle_start);
165   - tick_nohz_stop_sched_tick();
  165 + tick_nohz_stop_sched_tick(1);
166 166 while (!need_resched())
167 167 idle();
168 168 leds_event(led_idle_end);
arch/avr32/kernel/process.c
... ... @@ -31,7 +31,7 @@
31 31 {
32 32 /* endless idle loop with no priority at all */
33 33 while (1) {
34   - tick_nohz_stop_sched_tick();
  34 + tick_nohz_stop_sched_tick(1);
35 35 while (!need_resched())
36 36 cpu_idle_sleep();
37 37 tick_nohz_restart_sched_tick();
arch/blackfin/kernel/process.c
... ... @@ -105,7 +105,7 @@
105 105 #endif
106 106 if (!idle)
107 107 idle = default_idle;
108   - tick_nohz_stop_sched_tick();
  108 + tick_nohz_stop_sched_tick(1);
109 109 while (!need_resched())
110 110 idle();
111 111 tick_nohz_restart_sched_tick();
arch/mips/kernel/process.c
... ... @@ -53,7 +53,7 @@
53 53 {
54 54 /* endless idle loop with no priority at all */
55 55 while (1) {
56   - tick_nohz_stop_sched_tick();
  56 + tick_nohz_stop_sched_tick(1);
57 57 while (!need_resched()) {
58 58 #ifdef CONFIG_SMTC_IDLE_HOOK_DEBUG
59 59 extern void smtc_idle_loop_hook(void);
arch/powerpc/kernel/idle.c
... ... @@ -60,7 +60,7 @@
60 60  
61 61 set_thread_flag(TIF_POLLING_NRFLAG);
62 62 while (1) {
63   - tick_nohz_stop_sched_tick();
  63 + tick_nohz_stop_sched_tick(1);
64 64 while (!need_resched() && !cpu_should_die()) {
65 65 ppc64_runlatch_off();
66 66  
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
... ... @@ -142,7 +142,7 @@
142 142 void cpu_idle(void)
143 143 {
144 144 for (;;) {
145   - tick_nohz_stop_sched_tick();
  145 + tick_nohz_stop_sched_tick(1);
146 146 while (!need_resched())
147 147 default_idle();
148 148 tick_nohz_restart_sched_tick();
arch/sh/kernel/process_32.c
... ... @@ -86,7 +86,7 @@
86 86 if (!idle)
87 87 idle = default_idle;
88 88  
89   - tick_nohz_stop_sched_tick();
  89 + tick_nohz_stop_sched_tick(1);
90 90 while (!need_resched())
91 91 idle();
92 92 tick_nohz_restart_sched_tick();
arch/sparc64/kernel/process.c
... ... @@ -96,7 +96,7 @@
96 96 set_thread_flag(TIF_POLLING_NRFLAG);
97 97  
98 98 while(1) {
99   - tick_nohz_stop_sched_tick();
  99 + tick_nohz_stop_sched_tick(1);
100 100  
101 101 while (!need_resched() && !cpu_is_offline(cpu))
102 102 sparc64_yield(cpu);
arch/um/kernel/process.c
... ... @@ -243,7 +243,7 @@
243 243 if (need_resched())
244 244 schedule();
245 245  
246   - tick_nohz_stop_sched_tick();
  246 + tick_nohz_stop_sched_tick(1);
247 247 nsecs = disable_timer();
248 248 idle_sleep(nsecs);
249 249 tick_nohz_restart_sched_tick();
arch/x86/kernel/process_32.c
... ... @@ -128,7 +128,7 @@
128 128  
129 129 /* endless idle loop with no priority at all */
130 130 while (1) {
131   - tick_nohz_stop_sched_tick();
  131 + tick_nohz_stop_sched_tick(1);
132 132 while (!need_resched()) {
133 133  
134 134 check_pgt_cache();
arch/x86/kernel/process_64.c
... ... @@ -120,7 +120,7 @@
120 120 current_thread_info()->status |= TS_POLLING;
121 121 /* endless idle loop with no priority at all */
122 122 while (1) {
123   - tick_nohz_stop_sched_tick();
  123 + tick_nohz_stop_sched_tick(1);
124 124 while (!need_resched()) {
125 125  
126 126 rmb();
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)
... ... @@ -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