Merge branch 'fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/djbw/async_tx
[sfrench/cifs-2.6.git] / arch / ia64 / kernel / process.c
index c613fc0e91cc8bc5d1cdc6f204d4c3e76037b589..49937a383b23cb0f2a650173b8ff3fe3c990691b 100644 (file)
@@ -27,6 +27,7 @@
 #include <linux/interrupt.h>
 #include <linux/delay.h>
 #include <linux/kdebug.h>
+#include <linux/utsname.h>
 
 #include <asm/cpu.h>
 #include <asm/delay.h>
@@ -51,7 +52,6 @@
 #include "sigframe.h"
 
 void (*ia64_mark_idle)(int);
-static DEFINE_PER_CPU(unsigned int, cpu_idle_state);
 
 unsigned long boot_option_idle_override = 0;
 EXPORT_SYMBOL(boot_option_idle_override);
@@ -105,9 +105,11 @@ show_regs (struct pt_regs *regs)
        unsigned long ip = regs->cr_iip + ia64_psr(regs)->ri;
 
        print_modules();
-       printk("\nPid: %d, CPU %d, comm: %20s\n", current->pid, smp_processor_id(), current->comm);
-       printk("psr : %016lx ifs : %016lx ip  : [<%016lx>]    %s\n",
-              regs->cr_ipsr, regs->cr_ifs, ip, print_tainted());
+       printk("\nPid: %d, CPU %d, comm: %20s\n", task_pid_nr(current),
+                       smp_processor_id(), current->comm);
+       printk("psr : %016lx ifs : %016lx ip  : [<%016lx>]    %s (%s)\n",
+              regs->cr_ipsr, regs->cr_ifs, ip, print_tainted(),
+              init_utsname()->release);
        print_symbol("ip is at %s\n", ip);
        printk("unat: %016lx pfs : %016lx rsc : %016lx\n",
               regs->ar_unat, regs->ar_pfs, regs->ar_rsc);
@@ -154,6 +156,17 @@ show_regs (struct pt_regs *regs)
                show_stack(NULL, NULL);
 }
 
+void tsk_clear_notify_resume(struct task_struct *tsk)
+{
+#ifdef CONFIG_PERFMON
+       if (tsk->thread.pfm_needs_checking)
+               return;
+#endif
+       if (test_ti_thread_flag(task_thread_info(tsk), TIF_RESTORE_RSE))
+               return;
+       clear_ti_thread_flag(task_thread_info(tsk), TIF_NOTIFY_RESUME);
+}
+
 void
 do_notify_resume_user (sigset_t *unused, struct sigscratch *scr, long in_syscall)
 {
@@ -172,6 +185,10 @@ do_notify_resume_user (sigset_t *unused, struct sigscratch *scr, long in_syscall
        /* deal with pending signal delivery */
        if (test_thread_flag(TIF_SIGPENDING)||test_thread_flag(TIF_RESTORE_SIGMASK))
                ia64_do_signal(scr, in_syscall);
+
+       /* copy user rbs to kernel rbs */
+       if (unlikely(test_thread_flag(TIF_RESTORE_RSE)))
+               ia64_sync_krbs();
 }
 
 static int pal_halt        = 1;
@@ -236,33 +253,23 @@ static inline void play_dead(void)
 }
 #endif /* CONFIG_HOTPLUG_CPU */
 
-void cpu_idle_wait(void)
+static void do_nothing(void *unused)
 {
-       unsigned int cpu, this_cpu = get_cpu();
-       cpumask_t map;
-       cpumask_t tmp = current->cpus_allowed;
-
-       set_cpus_allowed(current, cpumask_of_cpu(this_cpu));
-       put_cpu();
-
-       cpus_clear(map);
-       for_each_online_cpu(cpu) {
-               per_cpu(cpu_idle_state, cpu) = 1;
-               cpu_set(cpu, map);
-       }
-
-       __get_cpu_var(cpu_idle_state) = 0;
+}
 
-       wmb();
-       do {
-               ssleep(1);
-               for_each_online_cpu(cpu) {
-                       if (cpu_isset(cpu, map) && !per_cpu(cpu_idle_state, cpu))
-                               cpu_clear(cpu, map);
-               }
-               cpus_and(map, map, cpu_online_map);
-       } while (!cpus_empty(map));
-       set_cpus_allowed(current, tmp);
+/*
+ * cpu_idle_wait - Used to ensure that all the CPUs discard old value of
+ * pm_idle and update to new pm_idle value. Required while changing pm_idle
+ * handler on SMP systems.
+ *
+ * Caller must have changed pm_idle to the new value before the call. Old
+ * pm_idle value will not be used by any CPU after the return of this function.
+ */
+void cpu_idle_wait(void)
+{
+       smp_mb();
+       /* kick all the CPUs so that they exit out of pm_idle */
+       smp_call_function(do_nothing, NULL, 0, 1);
 }
 EXPORT_SYMBOL_GPL(cpu_idle_wait);
 
@@ -290,9 +297,6 @@ cpu_idle (void)
 #ifdef CONFIG_SMP
                        min_xtp();
 #endif
-                       if (__get_cpu_var(cpu_idle_state))
-                               __get_cpu_var(cpu_idle_state) = 0;
-
                        rmb();
                        if (mark_idle)
                                (*mark_idle)(1);
@@ -736,6 +740,7 @@ flush_thread (void)
                ia32_drop_ia64_partial_page_list(current);
                current->thread.task_size = IA32_PAGE_OFFSET;
                set_fs(USER_DS);
+               memset(current->thread.tls_array, 0, sizeof(current->thread.tls_array));
        }
 #endif
 }