diff options
Diffstat (limited to 'arch/ia64/kernel/process.c')
-rw-r--r-- | arch/ia64/kernel/process.c | 59 |
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 | ||
54 | void (*ia64_mark_idle)(int); | 54 | void (*ia64_mark_idle)(int); |
55 | static DEFINE_PER_CPU(unsigned int, cpu_idle_state); | ||
56 | 55 | ||
57 | unsigned long boot_option_idle_override = 0; | 56 | unsigned long boot_option_idle_override = 0; |
58 | EXPORT_SYMBOL(boot_option_idle_override); | 57 | EXPORT_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 | ||
159 | void 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 | |||
160 | void | 170 | void |
161 | do_notify_resume_user (sigset_t *unused, struct sigscratch *scr, long in_syscall) | 171 | do_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 | ||
180 | static int pal_halt = 1; | 194 | static 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 | ||
242 | void cpu_idle_wait(void) | 256 | static 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)); | 268 | void 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 | } |
270 | EXPORT_SYMBOL_GPL(cpu_idle_wait); | 274 | EXPORT_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); |