diff options
author | Thomas Renninger <trenn@suse.de> | 2011-01-07 05:29:44 -0500 |
---|---|---|
committer | Len Brown <len.brown@intel.com> | 2011-01-12 18:05:16 -0500 |
commit | f77cfe4ea21760268c0277fa3e4b02dfd2a2c2f4 (patch) | |
tree | ffd83ee874d1cbe062cd70cade50c017725ba586 /arch | |
parent | f878133bf022717b880d0e0995b8f91436fd605c (diff) |
cpuidle/x86/perf: fix power:cpu_idle double end events and throw cpu_idle events from the cpuidle layer
Currently intel_idle and acpi_idle driver show double cpu_idle "exit idle"
events -> this patch fixes it and makes cpu_idle events throwing less complex.
It also introduces cpu_idle events for all architectures which use
the cpuidle subsystem, namely:
- arch/arm/mach-at91/cpuidle.c
- arch/arm/mach-davinci/cpuidle.c
- arch/arm/mach-kirkwood/cpuidle.c
- arch/arm/mach-omap2/cpuidle34xx.c
- arch/drivers/acpi/processor_idle.c (for all cases, not only mwait)
- arch/x86/kernel/process.c (did throw events before, but was a mess)
- drivers/idle/intel_idle.c (did throw events before)
Convention should be:
Fire cpu_idle events inside the current pm_idle function (not somewhere
down the the callee tree) to keep things easy.
Current possible pm_idle functions in X86:
c1e_idle, poll_idle, cpuidle_idle_call, mwait_idle, default_idle
-> this is really easy is now.
This affects userspace:
The type field of the cpu_idle power event can now direclty get
mapped to:
/sys/devices/system/cpu/cpuX/cpuidle/stateX/{name,desc,usage,time,...}
instead of throwing very CPU/mwait specific values.
This change is not visible for the intel_idle driver.
For the acpi_idle driver it should only be visible if the vendor
misses out C-states in his BIOS.
Another (perf timechart) patch reads out cpuidle info of cpu_idle
events from:
/sys/.../cpuidle/stateX/*, then the cpuidle events are mapped
to the correct C-/cpuidle state again, even if e.g. vendors miss
out C-states in their BIOS and for example only export C1 and C3.
-> everything is fine.
Signed-off-by: Thomas Renninger <trenn@suse.de>
CC: Robert Schoene <robert.schoene@tu-dresden.de>
CC: Jean Pihet <j-pihet@ti.com>
CC: Arjan van de Ven <arjan@linux.intel.com>
CC: Ingo Molnar <mingo@elte.hu>
CC: Frederic Weisbecker <fweisbec@gmail.com>
CC: linux-pm@lists.linux-foundation.org
CC: linux-acpi@vger.kernel.org
CC: linux-kernel@vger.kernel.org
CC: linux-perf-users@vger.kernel.org
CC: linux-omap@vger.kernel.org
Signed-off-by: Len Brown <len.brown@intel.com>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/x86/kernel/process.c | 6 | ||||
-rw-r--r-- | arch/x86/kernel/process_32.c | 4 | ||||
-rw-r--r-- | arch/x86/kernel/process_64.c | 6 |
3 files changed, 4 insertions, 12 deletions
diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c index 09c08a1c706f..67e96e67157b 100644 --- a/arch/x86/kernel/process.c +++ b/arch/x86/kernel/process.c | |||
@@ -386,6 +386,8 @@ void default_idle(void) | |||
386 | else | 386 | else |
387 | local_irq_enable(); | 387 | local_irq_enable(); |
388 | current_thread_info()->status |= TS_POLLING; | 388 | current_thread_info()->status |= TS_POLLING; |
389 | trace_power_end(smp_processor_id()); | ||
390 | trace_cpu_idle(PWR_EVENT_EXIT, smp_processor_id()); | ||
389 | } else { | 391 | } else { |
390 | local_irq_enable(); | 392 | local_irq_enable(); |
391 | /* loop is done by the caller */ | 393 | /* loop is done by the caller */ |
@@ -443,8 +445,6 @@ EXPORT_SYMBOL_GPL(cpu_idle_wait); | |||
443 | */ | 445 | */ |
444 | void mwait_idle_with_hints(unsigned long ax, unsigned long cx) | 446 | void mwait_idle_with_hints(unsigned long ax, unsigned long cx) |
445 | { | 447 | { |
446 | trace_power_start(POWER_CSTATE, (ax>>4)+1, smp_processor_id()); | ||
447 | trace_cpu_idle((ax>>4)+1, smp_processor_id()); | ||
448 | if (!need_resched()) { | 448 | if (!need_resched()) { |
449 | if (cpu_has(__this_cpu_ptr(&cpu_info), X86_FEATURE_CLFLUSH_MONITOR)) | 449 | if (cpu_has(__this_cpu_ptr(&cpu_info), X86_FEATURE_CLFLUSH_MONITOR)) |
450 | clflush((void *)¤t_thread_info()->flags); | 450 | clflush((void *)¤t_thread_info()->flags); |
@@ -471,6 +471,8 @@ static void mwait_idle(void) | |||
471 | __sti_mwait(0, 0); | 471 | __sti_mwait(0, 0); |
472 | else | 472 | else |
473 | local_irq_enable(); | 473 | local_irq_enable(); |
474 | trace_power_end(smp_processor_id()); | ||
475 | trace_cpu_idle(PWR_EVENT_EXIT, smp_processor_id()); | ||
474 | } else | 476 | } else |
475 | local_irq_enable(); | 477 | local_irq_enable(); |
476 | } | 478 | } |
diff --git a/arch/x86/kernel/process_32.c b/arch/x86/kernel/process_32.c index 4b9befa0e347..8d128783af47 100644 --- a/arch/x86/kernel/process_32.c +++ b/arch/x86/kernel/process_32.c | |||
@@ -57,8 +57,6 @@ | |||
57 | #include <asm/syscalls.h> | 57 | #include <asm/syscalls.h> |
58 | #include <asm/debugreg.h> | 58 | #include <asm/debugreg.h> |
59 | 59 | ||
60 | #include <trace/events/power.h> | ||
61 | |||
62 | asmlinkage void ret_from_fork(void) __asm__("ret_from_fork"); | 60 | asmlinkage void ret_from_fork(void) __asm__("ret_from_fork"); |
63 | 61 | ||
64 | /* | 62 | /* |
@@ -113,8 +111,6 @@ void cpu_idle(void) | |||
113 | stop_critical_timings(); | 111 | stop_critical_timings(); |
114 | pm_idle(); | 112 | pm_idle(); |
115 | start_critical_timings(); | 113 | start_critical_timings(); |
116 | trace_power_end(smp_processor_id()); | ||
117 | trace_cpu_idle(PWR_EVENT_EXIT, smp_processor_id()); | ||
118 | } | 114 | } |
119 | tick_nohz_restart_sched_tick(); | 115 | tick_nohz_restart_sched_tick(); |
120 | preempt_enable_no_resched(); | 116 | preempt_enable_no_resched(); |
diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c index 4c818a738396..bd387e8f73b4 100644 --- a/arch/x86/kernel/process_64.c +++ b/arch/x86/kernel/process_64.c | |||
@@ -51,8 +51,6 @@ | |||
51 | #include <asm/syscalls.h> | 51 | #include <asm/syscalls.h> |
52 | #include <asm/debugreg.h> | 52 | #include <asm/debugreg.h> |
53 | 53 | ||
54 | #include <trace/events/power.h> | ||
55 | |||
56 | asmlinkage extern void ret_from_fork(void); | 54 | asmlinkage extern void ret_from_fork(void); |
57 | 55 | ||
58 | DEFINE_PER_CPU(unsigned long, old_rsp); | 56 | DEFINE_PER_CPU(unsigned long, old_rsp); |
@@ -141,10 +139,6 @@ void cpu_idle(void) | |||
141 | pm_idle(); | 139 | pm_idle(); |
142 | start_critical_timings(); | 140 | start_critical_timings(); |
143 | 141 | ||
144 | trace_power_end(smp_processor_id()); | ||
145 | trace_cpu_idle(PWR_EVENT_EXIT, | ||
146 | smp_processor_id()); | ||
147 | |||
148 | /* In many cases the interrupt that ended idle | 142 | /* In many cases the interrupt that ended idle |
149 | has already called exit_idle. But some idle | 143 | has already called exit_idle. But some idle |
150 | loops can be woken up without interrupt. */ | 144 | loops can be woken up without interrupt. */ |