Hello,
Patch introduces support for new trace API. Below is part 1 --
support new trace API. I suspect, that in part 2 we'll have to change
add_event signature to return status code, since that compiled with both
CONFIG_EVENT_POWER_TRACING_DEPRECATED and new API kernel will produce
double events (didn't test it, just a guess).
----8<-----8<------
Introduce support for new trace API : cpu_frequency, cpu_idle events.
For event_type 71 -- cpu_frequency -- header is as follows:
header:
type is 71 / 47
09 00 00 00 01 00 30 00 e7 bb f1 76 78 6e 00 00 01 00 00 00 00 00 00 00
14 00 00 00 47 00 00 01 67 1e 00 00 ff ff ff ff 98 4b 12 00 01 00 00 00
where according to include/trace/events/power.h
DEFINE_EVENT(cpu, cpu_frequency,
TP_PROTO(unsigned int frequency, unsigned int cpu_id),
TP_ARGS(frequency, cpu_id)
);
To address freq and cpu_id, struct power_cpu_idle_entry was introduced:
struct power_cpu_idle_entry {
int state;
int cpu_id;
};
For event_type 72 -- cpu_idle -- header is:
header:
type is 72 / 48
09 00 00 00 01 00 30 00 ba 5b 68 52 78 6e 00 00 03 00 00 00 00 00 00 00
14 00 00 00 48 00 04 02 00 00 00 00 ff ff ff ff ff ff ff ff 03 00 00 00
where
DEFINE_EVENT(cpu, cpu_idle,
TP_PROTO(unsigned int state, unsigned int cpu_id),
TP_ARGS(state, cpu_id)
);
To address frequency and cpu_id, struct power_cpu_freqency_entry was
introduced:
struct power_cpu_freqency_entry {
unsigned int frequency;
unsigned int cpu_id;
};
---
cpu/cpu.cpp | 18 +++++++++++++++++-
perf/perf.cpp | 4 +++-
perf/perf.h | 23 ++++++++++++++++++++++-
process/do_process.cpp | 11 +++++++++++
4 files changed, 53 insertions(+), 3 deletions(-)
diff --git a/cpu/cpu.cpp b/cpu/cpu.cpp
index 39f00e7..6afedf3 100644
--- a/cpu/cpu.cpp
+++ b/cpu/cpu.cpp
@@ -271,6 +271,8 @@ void enumerate_cpus(void)
perf_events = new perf_power_bundle();
perf_events->add_event("power:power_frequency");
+ perf_events->add_event("power:cpu_frequency");
+ perf_events->add_event("power:cpu_idle");
perf_events->add_event("power:power_start");
perf_events->add_event("power:power_end");
@@ -773,10 +775,24 @@ void perf_power_bundle::handle_trace_point(int type, void
*trace, int cpunr, uin
system_level.children[i]->validate();
#endif
- if (strcmp(event_name, "power:power_frequency")==0) {
+ if (strcmp(event_name, "power:power_frequency") == 0) {
struct power_entry *pe = (struct power_entry *)trace;
cpu->change_freq(time, pe->value);
}
+
+ if (strcmp(event_name, "power:cpu_frequency") == 0) {
+ struct power_cpu_freqency_entry *pfe = (struct
power_cpu_freqency_entry *)trace;
+ cpu->change_freq(time, pfe->frequency);
+ }
+
+ if (strcmp(event_name, "power:cpu_idle") == 0) {
+ struct power_cpu_idle_entry *ppe = (struct power_cpu_idle_entry
*)trace;
+ if (ppe->state != PWR_EVENT_EXIT)
+ cpu->go_idle(time);
+ else
+ cpu->go_unidle(time);
+ }
+
if (strcmp(event_name, "power:power_start")==0)
cpu->go_idle(time);
if (strcmp(event_name, "power:power_end")==0)
diff --git a/perf/perf.cpp b/perf/perf.cpp
index 73682aa..7354391 100644
--- a/perf/perf.cpp
+++ b/perf/perf.cpp
@@ -53,8 +53,10 @@ static int get_trace_type(const char *eventname)
str = read_sysfs_string("/sys/kernel/debug/tracing/events/%s/id",
eventname);
- if (str.length() < 1)
+ if (str.length() < 1) {
+ fprintf(stderr, "Error: can't find event: %s\n", eventname);
return -1;
+ }
this_trace = strtoull(str.c_str(), NULL, 10);
return this_trace;
}
diff --git a/perf/perf.h b/perf/perf.h
index faeb6b3..569c5ed 100644
--- a/perf/perf.h
+++ b/perf/perf.h
@@ -26,9 +26,30 @@
#define _INCLUDE_GUARD_PERF_H_
#include <iostream>
+#include <stdint.h>
using namespace std;
+#define __u32 uint32_t
+#define PWR_EVENT_EXIT -1
+
+/*
+ * DEFINE_EVENT cpu_idle
+ * TP_ARGS(state, cpu_id)
+ */
+struct power_cpu_idle_entry {
+ int state;
+ int cpu_id;
+};
+
+/* DEFINE_EVENT cpu_frequency
+ * TP_ARGS(frequency, cpu_id)
+ */
+struct power_cpu_freqency_entry {
+ unsigned int frequency;
+ unsigned int cpu_id;
+};
+
class perf_event {
protected:
int perf_fd;
@@ -65,4 +86,4 @@ public:
};
-#endif
\ No newline at end of file
+#endif
diff --git a/process/do_process.cpp b/process/do_process.cpp
index 2ca4b10..f87a873 100644
--- a/process/do_process.cpp
+++ b/process/do_process.cpp
@@ -39,6 +39,7 @@
#include <string.h>
#include <ncurses.h>
+#include "../perf/perf.h"
#include "../perf/perf_bundle.h"
#include "../perf/perf_event.h"
#include "../parameters/parameters.h"
@@ -438,6 +439,15 @@ 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);
}
+
+ if (strcmp(event_name, "power:cpu_idle") == 0) {
+ struct power_cpu_idle_entry *ppe = (struct
power_cpu_idle_entry *)trace;
+ if (ppe->state != PWR_EVENT_EXIT)
+ set_wakeup_pending(cpu);
+ else
+ consume_blame(cpu);
+ }
+
if (strcmp(event_name, "power:power_start") == 0) {
set_wakeup_pending(cpu);
}
@@ -503,6 +513,7 @@ 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");
+ perf_events->add_event("power:cpu_idle");
perf_events->add_event("power:power_start");
perf_events->add_event("power:power_end");
perf_events->add_event("workqueue:workqueue_execute_start");
_______________________________________________
Discuss mailing list
[email protected]
http://lists.lesswatts.org/listinfo/discuss