>From kernel version 2.6.41 the power_start, power_end
and power_frequency power traces will be replaced with
cpu_idle and cpu_frequency power traces. Refer kernel
documentation events-power.txt for details.

Inorder to allow backward compatiblity the functionality
of this patch has been done under a macro NEW_POWER_TRACE_APIS.
When using a kernel version greater than 2.6.41 uncomment
the macro in main.cpp

Signed-off-by: John Mathew <john.mat...@intel.com>
---
 cpu/cpu.cpp            |   20 ++++++++++++++++++++
 cpu/cpu.h              |    6 ++++++
 main.cpp               |    2 ++
 process/do_process.cpp |   16 ++++++++++++++++
 4 files changed, 44 insertions(+), 0 deletions(-)

diff --git a/cpu/cpu.cpp b/cpu/cpu.cpp
index 563aa30..092422c 100644
--- a/cpu/cpu.cpp
+++ b/cpu/cpu.cpp
@@ -277,9 +277,14 @@ void enumerate_cpus(void)
 
        perf_events = new perf_power_bundle();
 
+#ifdef NEW_POWER_TRACE_APIS
+       perf_events->add_event("power:cpu_idle");
+       perf_events->add_event("power:cpu_frequency");
+#else
        perf_events->add_event("power:power_frequency");
        perf_events->add_event("power:power_start");
        perf_events->add_event("power:power_end");
+#endif
 
 }
 
@@ -955,6 +960,20 @@ void perf_power_bundle::handle_trace_point(int type, void 
*trace, int cpunr, uin
                        system_level.children[i]->validate();
 #endif
 
+
+#ifdef NEW_POWER_TRACE_APIS
+       if (strcmp(event_name, "power:cpu_frequency")==0) {
+               struct cpuidle_entry *pe = (struct cpuidle_entry *)trace;
+               cpu->change_freq(time, pe->state);
+       }
+       if (strcmp(event_name, "power:cpu_idle")==0) {
+               struct cpuidle_entry *ce = (struct cpuidle_entry *)trace;
+               if (ce->state == 4294967295)
+                       cpu->go_unidle(time);
+               else
+                       cpu->go_idle(time);
+       }
+#else
        if (strcmp(event_name, "power:power_frequency")==0) {
                struct power_entry *pe = (struct power_entry *)trace;
                cpu->change_freq(time, pe->value);
@@ -963,6 +982,7 @@ void perf_power_bundle::handle_trace_point(int type, void 
*trace, int cpunr, uin
                cpu->go_idle(time);
        if (strcmp(event_name, "power:power_end")==0)
                cpu->go_unidle(time);
+#endif
 
 #if 0
        unsigned int i;
diff --git a/cpu/cpu.h b/cpu/cpu.h
index d59dbb3..5c36c95 100644
--- a/cpu/cpu.h
+++ b/cpu/cpu.h
@@ -39,6 +39,12 @@ class abstract_cpu;
 #define LEVEL_C0 -1
 #define LEVEL_HEADER -2
 
+struct cpuidle_entry {
+       uint32_t  state;
+       uint32_t  cpu_id;
+} __attribute__((packed));
+
+
 struct idle_state {
        char linux_name[16]; /* state0 etc.. cpuidle name */
        char human_name[32];
diff --git a/main.cpp b/main.cpp
index cc1c7d3..608b726 100644
--- a/main.cpp
+++ b/main.cpp
@@ -56,6 +56,8 @@
 #include "devlist.h"
 #include "report.h"
 
+//#define NEW_POWER_TRACE_APIS
+
 int debug_learning = 0;
 
 int leave_powertop = 0;
diff --git a/process/do_process.cpp b/process/do_process.cpp
index f97b7e7..4b69fea 100644
--- a/process/do_process.cpp
+++ b/process/do_process.cpp
@@ -447,12 +447,22 @@ void perf_process_bundle::handle_trace_point(int type, 
void *trace, int cpu, uin
                t = work->done(time, (uint64_t)wq->work);
                consumer_child_time(cpu, t);
        }
+#ifdef NEW_POWER_TRACE_APIS
+       if (strcmp(event_name, "power:cpu_idle")==0) {
+               struct cpuidle_entry *ce = (struct cpuidle_entry *)trace;
+               if (ce->state == 4294967295)
+                       consume_blame(cpu);
+               else
+                       set_wakeup_pending(cpu);
+       }
+#else
        if (strcmp(event_name, "power:power_start") == 0) {
                set_wakeup_pending(cpu);
        }
        if (strcmp(event_name, "power:power_end") == 0) {
                consume_blame(cpu);
        }
+#endif
        if (strcmp(event_name, "i915:i915_gem_ring_dispatch") == 0
         || strcmp(event_name, "i915:i915_gem_request_submit") == 0) {
                /* any kernel contains only one of the these tracepoints,
@@ -515,8 +525,14 @@ void start_process_measurement(void)
                perf_events->add_event("timer:timer_expire_exit");
                perf_events->add_event("timer:hrtimer_expire_entry");
                perf_events->add_event("timer:hrtimer_expire_exit");
+
+#ifdef NEW_POWER_TRACE_APIS
+               perf_events->add_event("power:cpu_idle");
+#else
                perf_events->add_event("power:power_start");
                perf_events->add_event("power:power_end");
+#endif
+
                perf_events->add_event("workqueue:workqueue_execute_start");
                perf_events->add_event("workqueue:workqueue_execute_end");
                perf_events->add_event("i915:i915_gem_ring_dispatch");
-- 
1.7.4.1

---------------------------------------------------------------------
Intel Finland Oy
Registered Address: PL 281, 00181 Helsinki 
Business Identity Code: 0357606 - 4 
Domiciled in Helsinki 

This e-mail and any attachments may contain confidential material for
the sole use of the intended recipient(s). Any review or distribution
by others is strictly prohibited. If you are not the intended
recipient, please contact the sender and delete all copies.

_______________________________________________
Power mailing list
Power@bughost.org
https://bughost.org/mailman/listinfo/power

Reply via email to