Merge commit 'perf/core' into perf/hw-breakpoint
[cascardo/linux.git] / arch / x86 / kernel / process.c
index 071166a..2275ce5 100644 (file)
@@ -9,7 +9,7 @@
 #include <linux/pm.h>
 #include <linux/clockchips.h>
 #include <linux/random.h>
-#include <trace/power.h>
+#include <trace/events/power.h>
 #include <asm/system.h>
 #include <asm/apic.h>
 #include <asm/syscalls.h>
@@ -17,6 +17,8 @@
 #include <asm/uaccess.h>
 #include <asm/i387.h>
 #include <asm/ds.h>
+#include <asm/debugreg.h>
+#include <asm/hw_breakpoint.h>
 
 unsigned long idle_halt;
 EXPORT_SYMBOL(idle_halt);
@@ -25,9 +27,6 @@ EXPORT_SYMBOL(idle_nomwait);
 
 struct kmem_cache *task_xstate_cachep;
 
-DEFINE_TRACE(power_start);
-DEFINE_TRACE(power_end);
-
 int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src)
 {
        *dst = *src;
@@ -48,6 +47,8 @@ void free_thread_xstate(struct task_struct *tsk)
                kmem_cache_free(task_xstate_cachep, tsk->thread.xstate);
                tsk->thread.xstate = NULL;
        }
+       if (unlikely(test_tsk_thread_flag(tsk, TIF_DEBUG)))
+               flush_thread_hw_breakpoint(tsk);
 
        WARN(tsk->thread.ds_ctx, "leaking DS context\n");
 }
@@ -108,12 +109,8 @@ void flush_thread(void)
 
        clear_tsk_thread_flag(tsk, TIF_DEBUG);
 
-       tsk->thread.debugreg0 = 0;
-       tsk->thread.debugreg1 = 0;
-       tsk->thread.debugreg2 = 0;
-       tsk->thread.debugreg3 = 0;
-       tsk->thread.debugreg6 = 0;
-       tsk->thread.debugreg7 = 0;
+       if (unlikely(test_tsk_thread_flag(tsk, TIF_DEBUG)))
+               flush_thread_hw_breakpoint(tsk);
        memset(tsk->thread.tls_array, 0, sizeof(tsk->thread.tls_array));
        /*
         * Forget coprocessor state..
@@ -195,16 +192,6 @@ void __switch_to_xtra(struct task_struct *prev_p, struct task_struct *next_p,
        else if (next->debugctlmsr != prev->debugctlmsr)
                update_debugctlmsr(next->debugctlmsr);
 
-       if (test_tsk_thread_flag(next_p, TIF_DEBUG)) {
-               set_debugreg(next->debugreg0, 0);
-               set_debugreg(next->debugreg1, 1);
-               set_debugreg(next->debugreg2, 2);
-               set_debugreg(next->debugreg3, 3);
-               /* no 4 and 5 */
-               set_debugreg(next->debugreg6, 6);
-               set_debugreg(next->debugreg7, 7);
-       }
-
        if (test_tsk_thread_flag(prev_p, TIF_NOTSC) ^
            test_tsk_thread_flag(next_p, TIF_NOTSC)) {
                /* prev and next are different */
@@ -299,9 +286,7 @@ static inline int hlt_use_halt(void)
 void default_idle(void)
 {
        if (hlt_use_halt()) {
-               struct power_trace it;
-
-               trace_power_start(&it, POWER_CSTATE, 1);
+               trace_power_start(POWER_CSTATE, 1);
                current_thread_info()->status &= ~TS_POLLING;
                /*
                 * TS_POLLING-cleared state must be visible before we
@@ -314,7 +299,6 @@ void default_idle(void)
                else
                        local_irq_enable();
                current_thread_info()->status |= TS_POLLING;
-               trace_power_end(&it);
        } else {
                local_irq_enable();
                /* loop is done by the caller */
@@ -372,9 +356,7 @@ EXPORT_SYMBOL_GPL(cpu_idle_wait);
  */
 void mwait_idle_with_hints(unsigned long ax, unsigned long cx)
 {
-       struct power_trace it;
-
-       trace_power_start(&it, POWER_CSTATE, (ax>>4)+1);
+       trace_power_start(POWER_CSTATE, (ax>>4)+1);
        if (!need_resched()) {
                if (cpu_has(&current_cpu_data, X86_FEATURE_CLFLUSH_MONITOR))
                        clflush((void *)&current_thread_info()->flags);
@@ -384,15 +366,13 @@ void mwait_idle_with_hints(unsigned long ax, unsigned long cx)
                if (!need_resched())
                        __mwait(ax, cx);
        }
-       trace_power_end(&it);
 }
 
 /* Default MONITOR/MWAIT with no hints, used for default C1 state */
 static void mwait_idle(void)
 {
-       struct power_trace it;
        if (!need_resched()) {
-               trace_power_start(&it, POWER_CSTATE, 1);
+               trace_power_start(POWER_CSTATE, 1);
                if (cpu_has(&current_cpu_data, X86_FEATURE_CLFLUSH_MONITOR))
                        clflush((void *)&current_thread_info()->flags);
 
@@ -402,7 +382,6 @@ static void mwait_idle(void)
                        __sti_mwait(0, 0);
                else
                        local_irq_enable();
-               trace_power_end(&it);
        } else
                local_irq_enable();
 }
@@ -414,13 +393,11 @@ static void mwait_idle(void)
  */
 static void poll_idle(void)
 {
-       struct power_trace it;
-
-       trace_power_start(&it, POWER_CSTATE, 0);
+       trace_power_start(POWER_CSTATE, 0);
        local_irq_enable();
        while (!need_resched())
                cpu_relax();
-       trace_power_end(&it);
+       trace_power_end(0);
 }
 
 /*
@@ -568,10 +545,8 @@ void __cpuinit select_idle_routine(const struct cpuinfo_x86 *c)
 void __init init_c1e_mask(void)
 {
        /* If we're using c1e_idle, we need to allocate c1e_mask. */
-       if (pm_idle == c1e_idle) {
-               alloc_cpumask_var(&c1e_mask, GFP_KERNEL);
-               cpumask_clear(c1e_mask);
-       }
+       if (pm_idle == c1e_idle)
+               zalloc_cpumask_var(&c1e_mask, GFP_KERNEL);
 }
 
 static int __init idle_setup(char *str)