From: Kan Liang <[email protected]>

This patch store the vaule for calculating frequency, CPU Utilization
and percent performance in struct perf_sample, when sample group read
is detected and dump_trace is enabled.

Signed-off-by: Kan Liang <[email protected]>
---
 tools/perf/util/event.h   |  3 +++
 tools/perf/util/session.c | 26 +++++++++++++++++++++++++-
 tools/perf/util/session.h | 25 +++++++++++++++++++++++++
 3 files changed, 53 insertions(+), 1 deletion(-)

diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h
index 3439462..edffeca 100644
--- a/tools/perf/util/event.h
+++ b/tools/perf/util/event.h
@@ -187,6 +187,8 @@ enum perf_freqs {
        PERF_FREQ_MAX
 };
 
+typedef u64 perf_freq_t[PERF_FREQ_MAX];
+
 struct perf_sample {
        u64 ip;
        u32 pid, tid;
@@ -202,6 +204,7 @@ struct perf_sample {
        u64 data_src;
        u32 flags;
        u16 insn_len;
+       perf_freq_t freq;
        void *raw_data;
        struct ip_callchain *callchain;
        struct branch_stack *branch_stack;
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
index d1a43a3..e8cb98d 100644
--- a/tools/perf/util/session.c
+++ b/tools/perf/util/session.c
@@ -7,7 +7,6 @@
 #include <sys/mman.h>
 
 #include "evlist.h"
-#include "evsel.h"
 #include "session.h"
 #include "tool.h"
 #include "sort.h"
@@ -1047,6 +1046,26 @@ static int
                                            &sample->read.one, machine);
 }
 
+static void perf_caculate_freq(struct perf_sample *sample,
+                              struct perf_evsel *evsel)
+{
+       u64 i;
+       struct perf_evlist *evlist = evsel->evlist;
+       struct sample_read_value *value;
+       struct perf_sample_id *sid;
+       struct perf_evsel *event;
+
+       for (i = 0; i < sample->read.group.nr; i++) {
+
+               value = &sample->read.group.values[i];
+               sid = perf_evlist__id2sid(evlist, value->id);
+               event = sid->evsel;
+               if (event != NULL)
+                       perf_freq__init(evlist->env->msr_pmu_type,
+                                       event, sample->freq, value->value);
+       }
+}
+
 static int machines__deliver_event(struct machines *machines,
                                   struct perf_evlist *evlist,
                                   union perf_event *event,
@@ -1068,6 +1087,11 @@ static int machines__deliver_event(struct machines 
*machines,
                        ++evlist->stats.nr_unknown_id;
                        return 0;
                }
+               if (dump_trace &&
+                   (evsel->attr.sample_type & PERF_SAMPLE_READ) &&
+                   (evsel->attr.read_format & PERF_FORMAT_GROUP))
+                       perf_caculate_freq(sample, evsel);
+
                dump_sample(evsel, event, sample);
                if (machine == NULL) {
                        ++evlist->stats.nr_unprocessable_samples;
diff --git a/tools/perf/util/session.h b/tools/perf/util/session.h
index b44afc7..f70d3a1 100644
--- a/tools/perf/util/session.h
+++ b/tools/perf/util/session.h
@@ -9,6 +9,7 @@
 #include "thread.h"
 #include "data.h"
 #include "ordered-events.h"
+#include "evsel.h"
 #include <linux/rbtree.h>
 #include <linux/perf_event.h>
 
@@ -42,6 +43,30 @@ struct perf_session {
 #define PRINT_IP_OPT_ONELINE   (1<<4)
 #define PRINT_IP_OPT_SRCLINE   (1<<5)
 
+#define PERF_MSR_TSC           0
+#define PERF_MSR_APERF         1
+#define PERF_MSR_MPERF         2
+
+static inline void perf_freq__init(unsigned int msr_pmu_type,
+                                  struct perf_evsel *evsel,
+                                  perf_freq_t array,
+                                  u64 value)
+{
+       if (evsel->attr.type == msr_pmu_type) {
+               if (evsel->attr.config == PERF_MSR_TSC)
+                       array[PERF_FREQ_TSC] = value;
+               if (evsel->attr.config == PERF_MSR_APERF)
+                       array[PERF_FREQ_APERF] = value;
+               if (evsel->attr.config == PERF_MSR_MPERF)
+                       array[PERF_FREQ_MPERF] = value;
+       }
+       if (evsel->attr.type == PERF_TYPE_HARDWARE) {
+               if (evsel->attr.config == PERF_COUNT_HW_CPU_CYCLES)
+                       array[PERF_FREQ_CYCLES] = value;
+               if (evsel->attr.config == PERF_COUNT_HW_REF_CPU_CYCLES)
+                       array[PERF_FREQ_REF_CYCLES] = value;
+       }
+}
 struct perf_tool;
 
 struct perf_session *perf_session__new(struct perf_data_file *file,
-- 
1.8.3.1

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to