aboutsummaryrefslogtreecommitdiffstats
path: root/arch/ia64/kernel/process.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/ia64/kernel/process.c')
-rw-r--r--arch/ia64/kernel/process.c59
1 files changed, 30 insertions, 29 deletions
diff --git a/arch/ia64/kernel/process.c b/arch/ia64/kernel/process.c
index 7377d323131d..49937a383b23 100644
--- a/arch/ia64/kernel/process.c
+++ b/arch/ia64/kernel/process.c
@@ -52,7 +52,6 @@
52#include "sigframe.h" 52#include "sigframe.h"
53 53
54void (*ia64_mark_idle)(int); 54void (*ia64_mark_idle)(int);
55static DEFINE_PER_CPU(unsigned int, cpu_idle_state);
56 55
57unsigned long boot_option_idle_override = 0; 56unsigned long boot_option_idle_override = 0;
58EXPORT_SYMBOL(boot_option_idle_override); 57EXPORT_SYMBOL(boot_option_idle_override);
@@ -157,6 +156,17 @@ show_regs (struct pt_regs *regs)
157 show_stack(NULL, NULL); 156 show_stack(NULL, NULL);
158} 157}
159 158
159void tsk_clear_notify_resume(struct task_struct *tsk)
160{
161#ifdef CONFIG_PERFMON
162 if (tsk->thread.pfm_needs_checking)
163 return;
164#endif
165 if (test_ti_thread_flag(task_thread_info(tsk), TIF_RESTORE_RSE))
166 return;
167 clear_ti_thread_flag(task_thread_info(tsk), TIF_NOTIFY_RESUME);
168}
169
160void 170void
161do_notify_resume_user (sigset_t *unused, struct sigscratch *scr, long in_syscall) 171do_notify_resume_user (sigset_t *unused, struct sigscratch *scr, long in_syscall)
162{ 172{
@@ -175,6 +185,10 @@ do_notify_resume_user (sigset_t *unused, struct sigscratch *scr, long in_syscall
175 /* deal with pending signal delivery */ 185 /* deal with pending signal delivery */
176 if (test_thread_flag(TIF_SIGPENDING)||test_thread_flag(TIF_RESTORE_SIGMASK)) 186 if (test_thread_flag(TIF_SIGPENDING)||test_thread_flag(TIF_RESTORE_SIGMASK))
177 ia64_do_signal(scr, in_syscall); 187 ia64_do_signal(scr, in_syscall);
188
189 /* copy user rbs to kernel rbs */
190 if (unlikely(test_thread_flag(TIF_RESTORE_RSE)))
191 ia64_sync_krbs();
178} 192}
179 193
180static int pal_halt = 1; 194static int pal_halt = 1;
@@ -239,33 +253,23 @@ static inline void play_dead(void)
239} 253}
240#endif /* CONFIG_HOTPLUG_CPU */ 254#endif /* CONFIG_HOTPLUG_CPU */
241 255
242void cpu_idle_wait(void) 256static void do_nothing(void *unused)
243{ 257{
244 unsigned int cpu, this_cpu = get_cpu(); 258}
245 cpumask_t map;
246 cpumask_t tmp = current->cpus_allowed;
247
248 set_cpus_allowed(current, cpumask_of_cpu(this_cpu));
249 put_cpu();
250
251 cpus_clear(map);
252 for_each_online_cpu(cpu) {
253 per_cpu(cpu_idle_state, cpu) = 1;
254 cpu_set(cpu, map);
255 }
256
257 __get_cpu_var(cpu_idle_state) = 0;
258 259
259 wmb(); 260/*
260 do { 261 * cpu_idle_wait - Used to ensure that all the CPUs discard old value of
261 ssleep(1); 262 * pm_idle and update to new pm_idle value. Required while changing pm_idle
262 for_each_online_cpu(cpu) { 263 * handler on SMP systems.
263 if (cpu_isset(cpu, map) && !per_cpu(cpu_idle_state, cpu)) 264 *
264 cpu_clear(cpu, map); 265 * Caller must have changed pm_idle to the new value before the call. Old
265 } 266 * pm_idle value will not be used by any CPU after the return of this function.
266 cpus_and(map, map, cpu_online_map); 267 */
267 } while (!cpus_empty(map)); 268void cpu_idle_wait(void)
268 set_cpus_allowed(current, tmp); 269{
270 smp_mb();
271 /* kick all the CPUs so that they exit out of pm_idle */
272 smp_call_function(do_nothing, NULL, 0, 1);
269} 273}
270EXPORT_SYMBOL_GPL(cpu_idle_wait); 274EXPORT_SYMBOL_GPL(cpu_idle_wait);
271 275
@@ -293,9 +297,6 @@ cpu_idle (void)
293#ifdef CONFIG_SMP 297#ifdef CONFIG_SMP
294 min_xtp(); 298 min_xtp();
295#endif 299#endif
296 if (__get_cpu_var(cpu_idle_state))
297 __get_cpu_var(cpu_idle_state) = 0;
298
299 rmb(); 300 rmb();
300 if (mark_idle) 301 if (mark_idle)
301 (*mark_idle)(1); 302 (*mark_idle)(1);