aboutsummaryrefslogtreecommitdiffstats
path: root/arch/ia64/kernel/process.c
diff options
context:
space:
mode:
authorTony Luck <tony.luck@intel.com>2005-06-15 17:06:48 -0400
committerTony Luck <tony.luck@intel.com>2005-06-15 17:06:48 -0400
commitf2cbb4f01936a3e4225692e03b084b78c56d386d (patch)
treef89f3d8baa250589a38a4dd2df56f84cddae3c76 /arch/ia64/kernel/process.c
parent325a479c4c110db278ef3361460a48c4093252cc (diff)
parent1016888fb69662936b32ab767c7419a3be9a69d3 (diff)
Auto merge with /home/aegl/GIT/linus
Diffstat (limited to 'arch/ia64/kernel/process.c')
-rw-r--r--arch/ia64/kernel/process.c55
1 files changed, 36 insertions, 19 deletions
diff --git a/arch/ia64/kernel/process.c b/arch/ia64/kernel/process.c
index 7c43aea5f7f7..ebb71f3d6d19 100644
--- a/arch/ia64/kernel/process.c
+++ b/arch/ia64/kernel/process.c
@@ -50,7 +50,7 @@
50#include "sigframe.h" 50#include "sigframe.h"
51 51
52void (*ia64_mark_idle)(int); 52void (*ia64_mark_idle)(int);
53static cpumask_t cpu_idle_map; 53static DEFINE_PER_CPU(unsigned int, cpu_idle_state);
54 54
55unsigned long boot_option_idle_override = 0; 55unsigned long boot_option_idle_override = 0;
56EXPORT_SYMBOL(boot_option_idle_override); 56EXPORT_SYMBOL(boot_option_idle_override);
@@ -173,7 +173,9 @@ do_notify_resume_user (sigset_t *oldset, struct sigscratch *scr, long in_syscall
173 ia64_do_signal(oldset, scr, in_syscall); 173 ia64_do_signal(oldset, scr, in_syscall);
174} 174}
175 175
176static int pal_halt = 1; 176static int pal_halt = 1;
177static int can_do_pal_halt = 1;
178
177static int __init nohalt_setup(char * str) 179static int __init nohalt_setup(char * str)
178{ 180{
179 pal_halt = 0; 181 pal_halt = 0;
@@ -181,16 +183,20 @@ static int __init nohalt_setup(char * str)
181} 183}
182__setup("nohalt", nohalt_setup); 184__setup("nohalt", nohalt_setup);
183 185
186void
187update_pal_halt_status(int status)
188{
189 can_do_pal_halt = pal_halt && status;
190}
191
184/* 192/*
185 * We use this if we don't have any better idle routine.. 193 * We use this if we don't have any better idle routine..
186 */ 194 */
187void 195void
188default_idle (void) 196default_idle (void)
189{ 197{
190 unsigned long pmu_active = ia64_getreg(_IA64_REG_PSR) & (IA64_PSR_PP | IA64_PSR_UP);
191
192 while (!need_resched()) 198 while (!need_resched())
193 if (pal_halt && !pmu_active) 199 if (can_do_pal_halt)
194 safe_halt(); 200 safe_halt();
195 else 201 else
196 cpu_relax(); 202 cpu_relax();
@@ -223,20 +229,31 @@ static inline void play_dead(void)
223} 229}
224#endif /* CONFIG_HOTPLUG_CPU */ 230#endif /* CONFIG_HOTPLUG_CPU */
225 231
226
227void cpu_idle_wait(void) 232void cpu_idle_wait(void)
228{ 233{
229 int cpu; 234 unsigned int cpu, this_cpu = get_cpu();
230 cpumask_t map; 235 cpumask_t map;
231 236
232 for_each_online_cpu(cpu) 237 set_cpus_allowed(current, cpumask_of_cpu(this_cpu));
233 cpu_set(cpu, cpu_idle_map); 238 put_cpu();
234 239
235 wmb(); 240 cpus_clear(map);
236 do { 241 for_each_online_cpu(cpu) {
237 ssleep(1); 242 per_cpu(cpu_idle_state, cpu) = 1;
238 cpus_and(map, cpu_idle_map, cpu_online_map); 243 cpu_set(cpu, map);
239 } while (!cpus_empty(map)); 244 }
245
246 __get_cpu_var(cpu_idle_state) = 0;
247
248 wmb();
249 do {
250 ssleep(1);
251 for_each_online_cpu(cpu) {
252 if (cpu_isset(cpu, map) && !per_cpu(cpu_idle_state, cpu))
253 cpu_clear(cpu, map);
254 }
255 cpus_and(map, map, cpu_online_map);
256 } while (!cpus_empty(map));
240} 257}
241EXPORT_SYMBOL_GPL(cpu_idle_wait); 258EXPORT_SYMBOL_GPL(cpu_idle_wait);
242 259
@@ -244,7 +261,6 @@ void __attribute__((noreturn))
244cpu_idle (void) 261cpu_idle (void)
245{ 262{
246 void (*mark_idle)(int) = ia64_mark_idle; 263 void (*mark_idle)(int) = ia64_mark_idle;
247 int cpu = smp_processor_id();
248 264
249 /* endless idle loop with no priority at all */ 265 /* endless idle loop with no priority at all */
250 while (1) { 266 while (1) {
@@ -255,12 +271,13 @@ cpu_idle (void)
255 while (!need_resched()) { 271 while (!need_resched()) {
256 void (*idle)(void); 272 void (*idle)(void);
257 273
274 if (__get_cpu_var(cpu_idle_state))
275 __get_cpu_var(cpu_idle_state) = 0;
276
277 rmb();
258 if (mark_idle) 278 if (mark_idle)
259 (*mark_idle)(1); 279 (*mark_idle)(1);
260 280
261 if (cpu_isset(cpu, cpu_idle_map))
262 cpu_clear(cpu, cpu_idle_map);
263 rmb();
264 idle = pm_idle; 281 idle = pm_idle;
265 if (!idle) 282 if (!idle)
266 idle = default_idle; 283 idle = default_idle;