aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorFrederic Weisbecker <fweisbec@gmail.com>2011-10-08 10:01:00 -0400
committerPaul E. McKenney <paulmck@linux.vnet.ibm.com>2011-12-11 13:31:36 -0500
commit2bbb6817c0ac1b5f2a68d720f364f98eeb1ac4fd (patch)
tree05bb5ba54671a8eaeca4fe4406a75e820317e473 /arch
parent280f06774afedf849f0b34248ed6aff57d0f6908 (diff)
nohz: Allow rcu extended quiescent state handling seperately from tick stop
It is assumed that rcu won't be used once we switch to tickless mode and until we restart the tick. However this is not always true, as in x86-64 where we dereference the idle notifiers after the tick is stopped. To prepare for fixing this, add two new APIs: tick_nohz_idle_enter_norcu() and tick_nohz_idle_exit_norcu(). If no use of RCU is made in the idle loop between tick_nohz_enter_idle() and tick_nohz_exit_idle() calls, the arch must instead call the new *_norcu() version such that the arch doesn't need to call rcu_idle_enter() and rcu_idle_exit(). Otherwise the arch must call tick_nohz_enter_idle() and tick_nohz_exit_idle() and also call explicitly: - rcu_idle_enter() after its last use of RCU before the CPU is put to sleep. - rcu_idle_exit() before the first use of RCU after the CPU is woken up. 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>
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 3f1f8daf703c..47e34c091276 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_idle_enter(); 186 tick_nohz_idle_enter_norcu();
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_idle_exit(); 216 tick_nohz_idle_exit_norcu();
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 6ee7952248db..34c8c703bb16 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_idle_enter(); 37 tick_nohz_idle_enter_norcu();
38 while (!need_resched()) 38 while (!need_resched())
39 cpu_idle_sleep(); 39 cpu_idle_sleep();
40 tick_nohz_idle_exit(); 40 tick_nohz_idle_exit_norcu();
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 7b141b5c9e8d..57e07498a0e7 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_idle_enter(); 91 tick_nohz_idle_enter_norcu();
92 while (!need_resched()) 92 while (!need_resched())
93 idle(); 93 idle();
94 tick_nohz_idle_exit(); 94 tick_nohz_idle_exit_norcu();
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 5407f09b4be4..13d59f34b94e 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_idle_enter(); 106 tick_nohz_idle_enter_norcu();
107 while (!need_resched()) 107 while (!need_resched())
108 idle(); 108 idle();
109 tick_nohz_idle_exit(); 109 tick_nohz_idle_exit_norcu();
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 c11e5ca2a434..17fb3a270160 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_idle_enter(); 59 tick_nohz_idle_enter_norcu();
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_idle_exit(); 80 tick_nohz_idle_exit_norcu();
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 fb6a9bf40006..2e82cd0fa5e1 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_idle_enter(); 54 tick_nohz_idle_enter_norcu();
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_idle_exit(); 72 tick_nohz_idle_exit_norcu();
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 878572f70ac5..2e782a36d8f2 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_idle_enter(); 59 tick_nohz_idle_enter_norcu();
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_idle_exit(); 96 tick_nohz_idle_exit_norcu();
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 e83dfaf89f69..d69d3d185e89 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_idle_enter(); 566 tick_nohz_idle_enter_norcu();
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_idle_exit(); 580 tick_nohz_idle_exit_norcu();
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_idle_enter(); 596 tick_nohz_idle_enter_norcu();
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_idle_exit(); 613 tick_nohz_idle_exit_norcu();
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 6224f9dbbc1f..6fa987367ae6 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_idle_enter(); 94 tick_nohz_idle_enter_norcu();
95 while (!need_resched()) 95 while (!need_resched())
96 default_idle(); 96 default_idle();
97 tick_nohz_idle_exit(); 97 tick_nohz_idle_exit_norcu();
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 6015743020a0..ad58e7535a7c 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_idle_enter(); 92 tick_nohz_idle_enter_norcu();
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_idle_exit(); 114 tick_nohz_idle_exit_norcu();
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 9c2795ba2cfe..4a0e7d79cb92 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_idle_enter(); 98 tick_nohz_idle_enter_norcu();
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_idle_exit(); 103 tick_nohz_idle_exit_norcu();
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 920e674aedb9..53ac89595ab1 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_idle_enter(); 88 tick_nohz_idle_enter_norcu();
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_idle_exit(); 108 tick_nohz_idle_exit_norcu();
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 cfb657e92849..55d2cf455f63 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_idle_enter(); 249 tick_nohz_idle_enter_norcu();
250 nsecs = disable_timer(); 250 nsecs = disable_timer();
251 idle_sleep(nsecs); 251 idle_sleep(nsecs);
252 tick_nohz_idle_exit(); 252 tick_nohz_idle_exit_norcu();
253 } 253 }
254} 254}
255 255
diff --git a/arch/unicore32/kernel/process.c b/arch/unicore32/kernel/process.c
index 9999b9a84d46..095ff5a57928 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_idle_enter(); 58 tick_nohz_idle_enter_norcu();
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_idle_exit(); 66 tick_nohz_idle_exit_norcu();
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 6d9d4d52cac5..f94da3920c36 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_idle_enter(); 102 tick_nohz_idle_enter_norcu();
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_idle_exit(); 119 tick_nohz_idle_exit_norcu();
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 b069e9d7875f..18e8cf3581f6 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_idle_enter(); 125 tick_nohz_idle_enter_norcu();
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_idle_exit(); 152 tick_nohz_idle_exit_norcu();
153 preempt_enable_no_resched(); 153 preempt_enable_no_resched();
154 schedule(); 154 schedule();
155 preempt_disable(); 155 preempt_disable();