aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorFrederic Weisbecker <fweisbec@gmail.com>2011-10-07 12:22:06 -0400
committerPaul E. McKenney <paulmck@linux.vnet.ibm.com>2011-12-11 13:31:35 -0500
commit280f06774afedf849f0b34248ed6aff57d0f6908 (patch)
tree62ef683226d0569c0e6c3ba34ab2e6d85b2e047f /arch
parent867f236bd12f5091df6dc7cc75f94d7fd982d78a (diff)
nohz: Separate out irq exit and idle loop dyntick logic
The tick_nohz_stop_sched_tick() function, which tries to delay the next timer tick as long as possible, can be called from two places: - From the idle loop to start the dytick idle mode - From interrupt exit if we have interrupted the dyntick idle mode, so that we reprogram the next tick event in case the irq changed some internal state that requires this action. There are only few minor differences between both that are handled by that function, driven by the ts->inidle cpu variable and the inidle parameter. The whole guarantees that we only update the dyntick mode on irq exit if we actually interrupted the dyntick idle mode, and that we enter in RCU extended quiescent state from idle loop entry only. Split this function into: - tick_nohz_idle_enter(), which sets ts->inidle to 1, enters dynticks idle mode unconditionally if it can, and enters into RCU extended quiescent state. - tick_nohz_irq_exit() which only updates the dynticks idle mode when ts->inidle is set (ie: if tick_nohz_idle_enter() has been called). To maintain symmetry, tick_nohz_restart_sched_tick() has been renamed into tick_nohz_idle_exit(). This simplifies the code and micro-optimize the irq exit path (no need for local_irq_save there). This also prepares for the split between dynticks and rcu extended quiescent state logics. We'll need this split to further fix illegal uses of RCU in extended quiescent states in the idle loop. Signed-off-by: Frederic Weisbecker <fweisbec@gmail.com> Cc: Mike Frysinger <vapier@gentoo.org> Cc: Guan Xuetao <gxt@mprc.pku.edu.cn> Cc: David Miller <davem@davemloft.net> Cc: Chris Metcalf <cmetcalf@tilera.com> Cc: Hans-Christian Egtvedt <hans-christian.egtvedt@atmel.com> Cc: Ralf Baechle <ralf@linux-mips.org> Cc: Paul E. McKenney <paulmck@linux.vnet.ibm.com> Cc: Ingo Molnar <mingo@redhat.com> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: Thomas Gleixner <tglx@linutronix.de> Cc: H. Peter Anvin <hpa@zytor.com> Cc: Russell King <linux@arm.linux.org.uk> Cc: Paul Mackerras <paulus@samba.org> Cc: Heiko Carstens <heiko.carstens@de.ibm.com> Cc: Paul Mundt <lethal@linux-sh.org> Signed-off-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com> Reviewed-by: Josh Triplett <josh@joshtriplett.org>
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/kernel/process.c4
-rw-r--r--arch/avr32/kernel/process.c4
-rw-r--r--arch/blackfin/kernel/process.c4
-rw-r--r--arch/microblaze/kernel/process.c4
-rw-r--r--arch/mips/kernel/process.c4
-rw-r--r--arch/openrisc/kernel/idle.c4
-rw-r--r--arch/powerpc/kernel/idle.c4
-rw-r--r--arch/powerpc/platforms/iseries/setup.c8
-rw-r--r--arch/s390/kernel/process.c4
-rw-r--r--arch/sh/kernel/idle.c4
-rw-r--r--arch/sparc/kernel/process_64.c4
-rw-r--r--arch/tile/kernel/process.c4
-rw-r--r--arch/um/kernel/process.c4
-rw-r--r--arch/unicore32/kernel/process.c4
-rw-r--r--arch/x86/kernel/process_32.c4
-rw-r--r--arch/x86/kernel/process_64.c4
16 files changed, 34 insertions, 34 deletions
diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c
index 3d0c6fb74ae4..3f1f8daf703c 100644
--- a/arch/arm/kernel/process.c
+++ b/arch/arm/kernel/process.c
@@ -183,7 +183,7 @@ void cpu_idle(void)
183 183
184 /* endless idle loop with no priority at all */ 184 /* endless idle loop with no priority at all */
185 while (1) { 185 while (1) {
186 tick_nohz_stop_sched_tick(1); 186 tick_nohz_idle_enter();
187 leds_event(led_idle_start); 187 leds_event(led_idle_start);
188 while (!need_resched()) { 188 while (!need_resched()) {
189#ifdef CONFIG_HOTPLUG_CPU 189#ifdef CONFIG_HOTPLUG_CPU
@@ -213,7 +213,7 @@ void cpu_idle(void)
213 } 213 }
214 } 214 }
215 leds_event(led_idle_end); 215 leds_event(led_idle_end);
216 tick_nohz_restart_sched_tick(); 216 tick_nohz_idle_exit();
217 preempt_enable_no_resched(); 217 preempt_enable_no_resched();
218 schedule(); 218 schedule();
219 preempt_disable(); 219 preempt_disable();
diff --git a/arch/avr32/kernel/process.c b/arch/avr32/kernel/process.c
index ef5a2a08fcca..6ee7952248db 100644
--- a/arch/avr32/kernel/process.c
+++ b/arch/avr32/kernel/process.c
@@ -34,10 +34,10 @@ void cpu_idle(void)
34{ 34{
35 /* endless idle loop with no priority at all */ 35 /* endless idle loop with no priority at all */
36 while (1) { 36 while (1) {
37 tick_nohz_stop_sched_tick(1); 37 tick_nohz_idle_enter();
38 while (!need_resched()) 38 while (!need_resched())
39 cpu_idle_sleep(); 39 cpu_idle_sleep();
40 tick_nohz_restart_sched_tick(); 40 tick_nohz_idle_exit();
41 preempt_enable_no_resched(); 41 preempt_enable_no_resched();
42 schedule(); 42 schedule();
43 preempt_disable(); 43 preempt_disable();
diff --git a/arch/blackfin/kernel/process.c b/arch/blackfin/kernel/process.c
index 6a80a9e9fc4a..7b141b5c9e8d 100644
--- a/arch/blackfin/kernel/process.c
+++ b/arch/blackfin/kernel/process.c
@@ -88,10 +88,10 @@ void cpu_idle(void)
88#endif 88#endif
89 if (!idle) 89 if (!idle)
90 idle = default_idle; 90 idle = default_idle;
91 tick_nohz_stop_sched_tick(1); 91 tick_nohz_idle_enter();
92 while (!need_resched()) 92 while (!need_resched())
93 idle(); 93 idle();
94 tick_nohz_restart_sched_tick(); 94 tick_nohz_idle_exit();
95 preempt_enable_no_resched(); 95 preempt_enable_no_resched();
96 schedule(); 96 schedule();
97 preempt_disable(); 97 preempt_disable();
diff --git a/arch/microblaze/kernel/process.c b/arch/microblaze/kernel/process.c
index 95cc295976a7..5407f09b4be4 100644
--- a/arch/microblaze/kernel/process.c
+++ b/arch/microblaze/kernel/process.c
@@ -103,10 +103,10 @@ void cpu_idle(void)
103 if (!idle) 103 if (!idle)
104 idle = default_idle; 104 idle = default_idle;
105 105
106 tick_nohz_stop_sched_tick(1); 106 tick_nohz_idle_enter();
107 while (!need_resched()) 107 while (!need_resched())
108 idle(); 108 idle();
109 tick_nohz_restart_sched_tick(); 109 tick_nohz_idle_exit();
110 110
111 preempt_enable_no_resched(); 111 preempt_enable_no_resched();
112 schedule(); 112 schedule();
diff --git a/arch/mips/kernel/process.c b/arch/mips/kernel/process.c
index c47f96e453c0..c11e5ca2a434 100644
--- a/arch/mips/kernel/process.c
+++ b/arch/mips/kernel/process.c
@@ -56,7 +56,7 @@ void __noreturn cpu_idle(void)
56 56
57 /* endless idle loop with no priority at all */ 57 /* endless idle loop with no priority at all */
58 while (1) { 58 while (1) {
59 tick_nohz_stop_sched_tick(1); 59 tick_nohz_idle_enter();
60 while (!need_resched() && cpu_online(cpu)) { 60 while (!need_resched() && cpu_online(cpu)) {
61#ifdef CONFIG_MIPS_MT_SMTC 61#ifdef CONFIG_MIPS_MT_SMTC
62 extern void smtc_idle_loop_hook(void); 62 extern void smtc_idle_loop_hook(void);
@@ -77,7 +77,7 @@ void __noreturn cpu_idle(void)
77 system_state == SYSTEM_BOOTING)) 77 system_state == SYSTEM_BOOTING))
78 play_dead(); 78 play_dead();
79#endif 79#endif
80 tick_nohz_restart_sched_tick(); 80 tick_nohz_idle_exit();
81 preempt_enable_no_resched(); 81 preempt_enable_no_resched();
82 schedule(); 82 schedule();
83 preempt_disable(); 83 preempt_disable();
diff --git a/arch/openrisc/kernel/idle.c b/arch/openrisc/kernel/idle.c
index d5bc5f813e89..fb6a9bf40006 100644
--- a/arch/openrisc/kernel/idle.c
+++ b/arch/openrisc/kernel/idle.c
@@ -51,7 +51,7 @@ void cpu_idle(void)
51 51
52 /* endless idle loop with no priority at all */ 52 /* endless idle loop with no priority at all */
53 while (1) { 53 while (1) {
54 tick_nohz_stop_sched_tick(1); 54 tick_nohz_idle_enter();
55 55
56 while (!need_resched()) { 56 while (!need_resched()) {
57 check_pgt_cache(); 57 check_pgt_cache();
@@ -69,7 +69,7 @@ void cpu_idle(void)
69 set_thread_flag(TIF_POLLING_NRFLAG); 69 set_thread_flag(TIF_POLLING_NRFLAG);
70 } 70 }
71 71
72 tick_nohz_restart_sched_tick(); 72 tick_nohz_idle_exit();
73 preempt_enable_no_resched(); 73 preempt_enable_no_resched();
74 schedule(); 74 schedule();
75 preempt_disable(); 75 preempt_disable();
diff --git a/arch/powerpc/kernel/idle.c b/arch/powerpc/kernel/idle.c
index 39a2baa6ad58..878572f70ac5 100644
--- a/arch/powerpc/kernel/idle.c
+++ b/arch/powerpc/kernel/idle.c
@@ -56,7 +56,7 @@ void cpu_idle(void)
56 56
57 set_thread_flag(TIF_POLLING_NRFLAG); 57 set_thread_flag(TIF_POLLING_NRFLAG);
58 while (1) { 58 while (1) {
59 tick_nohz_stop_sched_tick(1); 59 tick_nohz_idle_enter();
60 while (!need_resched() && !cpu_should_die()) { 60 while (!need_resched() && !cpu_should_die()) {
61 ppc64_runlatch_off(); 61 ppc64_runlatch_off();
62 62
@@ -93,7 +93,7 @@ void cpu_idle(void)
93 93
94 HMT_medium(); 94 HMT_medium();
95 ppc64_runlatch_on(); 95 ppc64_runlatch_on();
96 tick_nohz_restart_sched_tick(); 96 tick_nohz_idle_exit();
97 preempt_enable_no_resched(); 97 preempt_enable_no_resched();
98 if (cpu_should_die()) 98 if (cpu_should_die())
99 cpu_die(); 99 cpu_die();
diff --git a/arch/powerpc/platforms/iseries/setup.c b/arch/powerpc/platforms/iseries/setup.c
index ea0acbd8966d..e83dfaf89f69 100644
--- a/arch/powerpc/platforms/iseries/setup.c
+++ b/arch/powerpc/platforms/iseries/setup.c
@@ -563,7 +563,7 @@ static void yield_shared_processor(void)
563static void iseries_shared_idle(void) 563static void iseries_shared_idle(void)
564{ 564{
565 while (1) { 565 while (1) {
566 tick_nohz_stop_sched_tick(1); 566 tick_nohz_idle_enter();
567 while (!need_resched() && !hvlpevent_is_pending()) { 567 while (!need_resched() && !hvlpevent_is_pending()) {
568 local_irq_disable(); 568 local_irq_disable();
569 ppc64_runlatch_off(); 569 ppc64_runlatch_off();
@@ -577,7 +577,7 @@ static void iseries_shared_idle(void)
577 } 577 }
578 578
579 ppc64_runlatch_on(); 579 ppc64_runlatch_on();
580 tick_nohz_restart_sched_tick(); 580 tick_nohz_idle_exit();
581 581
582 if (hvlpevent_is_pending()) 582 if (hvlpevent_is_pending())
583 process_iSeries_events(); 583 process_iSeries_events();
@@ -593,7 +593,7 @@ static void iseries_dedicated_idle(void)
593 set_thread_flag(TIF_POLLING_NRFLAG); 593 set_thread_flag(TIF_POLLING_NRFLAG);
594 594
595 while (1) { 595 while (1) {
596 tick_nohz_stop_sched_tick(1); 596 tick_nohz_idle_enter();
597 if (!need_resched()) { 597 if (!need_resched()) {
598 while (!need_resched()) { 598 while (!need_resched()) {
599 ppc64_runlatch_off(); 599 ppc64_runlatch_off();
@@ -610,7 +610,7 @@ static void iseries_dedicated_idle(void)
610 } 610 }
611 611
612 ppc64_runlatch_on(); 612 ppc64_runlatch_on();
613 tick_nohz_restart_sched_tick(); 613 tick_nohz_idle_exit();
614 preempt_enable_no_resched(); 614 preempt_enable_no_resched();
615 schedule(); 615 schedule();
616 preempt_disable(); 616 preempt_disable();
diff --git a/arch/s390/kernel/process.c b/arch/s390/kernel/process.c
index 9451b210a1b4..6224f9dbbc1f 100644
--- a/arch/s390/kernel/process.c
+++ b/arch/s390/kernel/process.c
@@ -91,10 +91,10 @@ static void default_idle(void)
91void cpu_idle(void) 91void cpu_idle(void)
92{ 92{
93 for (;;) { 93 for (;;) {
94 tick_nohz_stop_sched_tick(1); 94 tick_nohz_idle_enter();
95 while (!need_resched()) 95 while (!need_resched())
96 default_idle(); 96 default_idle();
97 tick_nohz_restart_sched_tick(); 97 tick_nohz_idle_exit();
98 preempt_enable_no_resched(); 98 preempt_enable_no_resched();
99 schedule(); 99 schedule();
100 preempt_disable(); 100 preempt_disable();
diff --git a/arch/sh/kernel/idle.c b/arch/sh/kernel/idle.c
index db4ecd731a00..6015743020a0 100644
--- a/arch/sh/kernel/idle.c
+++ b/arch/sh/kernel/idle.c
@@ -89,7 +89,7 @@ void cpu_idle(void)
89 89
90 /* endless idle loop with no priority at all */ 90 /* endless idle loop with no priority at all */
91 while (1) { 91 while (1) {
92 tick_nohz_stop_sched_tick(1); 92 tick_nohz_idle_enter();
93 93
94 while (!need_resched()) { 94 while (!need_resched()) {
95 check_pgt_cache(); 95 check_pgt_cache();
@@ -111,7 +111,7 @@ void cpu_idle(void)
111 start_critical_timings(); 111 start_critical_timings();
112 } 112 }
113 113
114 tick_nohz_restart_sched_tick(); 114 tick_nohz_idle_exit();
115 preempt_enable_no_resched(); 115 preempt_enable_no_resched();
116 schedule(); 116 schedule();
117 preempt_disable(); 117 preempt_disable();
diff --git a/arch/sparc/kernel/process_64.c b/arch/sparc/kernel/process_64.c
index 3739a06a76cb..9c2795ba2cfe 100644
--- a/arch/sparc/kernel/process_64.c
+++ b/arch/sparc/kernel/process_64.c
@@ -95,12 +95,12 @@ void cpu_idle(void)
95 set_thread_flag(TIF_POLLING_NRFLAG); 95 set_thread_flag(TIF_POLLING_NRFLAG);
96 96
97 while(1) { 97 while(1) {
98 tick_nohz_stop_sched_tick(1); 98 tick_nohz_idle_enter();
99 99
100 while (!need_resched() && !cpu_is_offline(cpu)) 100 while (!need_resched() && !cpu_is_offline(cpu))
101 sparc64_yield(cpu); 101 sparc64_yield(cpu);
102 102
103 tick_nohz_restart_sched_tick(); 103 tick_nohz_idle_exit();
104 104
105 preempt_enable_no_resched(); 105 preempt_enable_no_resched();
106 106
diff --git a/arch/tile/kernel/process.c b/arch/tile/kernel/process.c
index 9c45d8bbdf57..920e674aedb9 100644
--- a/arch/tile/kernel/process.c
+++ b/arch/tile/kernel/process.c
@@ -85,7 +85,7 @@ void cpu_idle(void)
85 85
86 /* endless idle loop with no priority at all */ 86 /* endless idle loop with no priority at all */
87 while (1) { 87 while (1) {
88 tick_nohz_stop_sched_tick(1); 88 tick_nohz_idle_enter();
89 while (!need_resched()) { 89 while (!need_resched()) {
90 if (cpu_is_offline(cpu)) 90 if (cpu_is_offline(cpu))
91 BUG(); /* no HOTPLUG_CPU */ 91 BUG(); /* no HOTPLUG_CPU */
@@ -105,7 +105,7 @@ void cpu_idle(void)
105 local_irq_enable(); 105 local_irq_enable();
106 current_thread_info()->status |= TS_POLLING; 106 current_thread_info()->status |= TS_POLLING;
107 } 107 }
108 tick_nohz_restart_sched_tick(); 108 tick_nohz_idle_exit();
109 preempt_enable_no_resched(); 109 preempt_enable_no_resched();
110 schedule(); 110 schedule();
111 preempt_disable(); 111 preempt_disable();
diff --git a/arch/um/kernel/process.c b/arch/um/kernel/process.c
index c5338351aecd..cfb657e92849 100644
--- a/arch/um/kernel/process.c
+++ b/arch/um/kernel/process.c
@@ -246,10 +246,10 @@ void default_idle(void)
246 if (need_resched()) 246 if (need_resched())
247 schedule(); 247 schedule();
248 248
249 tick_nohz_stop_sched_tick(1); 249 tick_nohz_idle_enter();
250 nsecs = disable_timer(); 250 nsecs = disable_timer();
251 idle_sleep(nsecs); 251 idle_sleep(nsecs);
252 tick_nohz_restart_sched_tick(); 252 tick_nohz_idle_exit();
253 } 253 }
254} 254}
255 255
diff --git a/arch/unicore32/kernel/process.c b/arch/unicore32/kernel/process.c
index ba401df971ed..9999b9a84d46 100644
--- a/arch/unicore32/kernel/process.c
+++ b/arch/unicore32/kernel/process.c
@@ -55,7 +55,7 @@ void cpu_idle(void)
55{ 55{
56 /* endless idle loop with no priority at all */ 56 /* endless idle loop with no priority at all */
57 while (1) { 57 while (1) {
58 tick_nohz_stop_sched_tick(1); 58 tick_nohz_idle_enter();
59 while (!need_resched()) { 59 while (!need_resched()) {
60 local_irq_disable(); 60 local_irq_disable();
61 stop_critical_timings(); 61 stop_critical_timings();
@@ -63,7 +63,7 @@ void cpu_idle(void)
63 local_irq_enable(); 63 local_irq_enable();
64 start_critical_timings(); 64 start_critical_timings();
65 } 65 }
66 tick_nohz_restart_sched_tick(); 66 tick_nohz_idle_exit();
67 preempt_enable_no_resched(); 67 preempt_enable_no_resched();
68 schedule(); 68 schedule();
69 preempt_disable(); 69 preempt_disable();
diff --git a/arch/x86/kernel/process_32.c b/arch/x86/kernel/process_32.c
index 795b79f984c2..6d9d4d52cac5 100644
--- a/arch/x86/kernel/process_32.c
+++ b/arch/x86/kernel/process_32.c
@@ -99,7 +99,7 @@ void cpu_idle(void)
99 99
100 /* endless idle loop with no priority at all */ 100 /* endless idle loop with no priority at all */
101 while (1) { 101 while (1) {
102 tick_nohz_stop_sched_tick(1); 102 tick_nohz_idle_enter();
103 while (!need_resched()) { 103 while (!need_resched()) {
104 104
105 check_pgt_cache(); 105 check_pgt_cache();
@@ -116,7 +116,7 @@ void cpu_idle(void)
116 pm_idle(); 116 pm_idle();
117 start_critical_timings(); 117 start_critical_timings();
118 } 118 }
119 tick_nohz_restart_sched_tick(); 119 tick_nohz_idle_exit();
120 preempt_enable_no_resched(); 120 preempt_enable_no_resched();
121 schedule(); 121 schedule();
122 preempt_disable(); 122 preempt_disable();
diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c
index 3bd7e6eebf31..b069e9d7875f 100644
--- a/arch/x86/kernel/process_64.c
+++ b/arch/x86/kernel/process_64.c
@@ -122,7 +122,7 @@ void cpu_idle(void)
122 122
123 /* endless idle loop with no priority at all */ 123 /* endless idle loop with no priority at all */
124 while (1) { 124 while (1) {
125 tick_nohz_stop_sched_tick(1); 125 tick_nohz_idle_enter();
126 while (!need_resched()) { 126 while (!need_resched()) {
127 127
128 rmb(); 128 rmb();
@@ -149,7 +149,7 @@ void cpu_idle(void)
149 __exit_idle(); 149 __exit_idle();
150 } 150 }
151 151
152 tick_nohz_restart_sched_tick(); 152 tick_nohz_idle_exit();
153 preempt_enable_no_resched(); 153 preempt_enable_no_resched();
154 schedule(); 154 schedule();
155 preempt_disable(); 155 preempt_disable();