diff options
author | Tony Luck <tony.luck@intel.com> | 2005-06-15 17:06:48 -0400 |
---|---|---|
committer | Tony Luck <tony.luck@intel.com> | 2005-06-15 17:06:48 -0400 |
commit | f2cbb4f01936a3e4225692e03b084b78c56d386d (patch) | |
tree | f89f3d8baa250589a38a4dd2df56f84cddae3c76 /arch/ia64/kernel/process.c | |
parent | 325a479c4c110db278ef3361460a48c4093252cc (diff) | |
parent | 1016888fb69662936b32ab767c7419a3be9a69d3 (diff) |
Auto merge with /home/aegl/GIT/linus
Diffstat (limited to 'arch/ia64/kernel/process.c')
-rw-r--r-- | arch/ia64/kernel/process.c | 55 |
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 | ||
52 | void (*ia64_mark_idle)(int); | 52 | void (*ia64_mark_idle)(int); |
53 | static cpumask_t cpu_idle_map; | 53 | static DEFINE_PER_CPU(unsigned int, cpu_idle_state); |
54 | 54 | ||
55 | unsigned long boot_option_idle_override = 0; | 55 | unsigned long boot_option_idle_override = 0; |
56 | EXPORT_SYMBOL(boot_option_idle_override); | 56 | EXPORT_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 | ||
176 | static int pal_halt = 1; | 176 | static int pal_halt = 1; |
177 | static int can_do_pal_halt = 1; | ||
178 | |||
177 | static int __init nohalt_setup(char * str) | 179 | static 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 | ||
186 | void | ||
187 | update_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 | */ |
187 | void | 195 | void |
188 | default_idle (void) | 196 | default_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 | |||
227 | void cpu_idle_wait(void) | 232 | void 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 | } |
241 | EXPORT_SYMBOL_GPL(cpu_idle_wait); | 258 | EXPORT_SYMBOL_GPL(cpu_idle_wait); |
242 | 259 | ||
@@ -244,7 +261,6 @@ void __attribute__((noreturn)) | |||
244 | cpu_idle (void) | 261 | cpu_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; |