Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1226482 > unrolled thread
| Started by | kan.liang@intel.com |
|---|---|
| First post | 2015-09-16 23:40 +0200 |
| Last post | 2015-09-16 23:50 +0200 |
| Articles | 3 — 1 participant |
Back to article view | Back to linux.kernel
[PATCH V10 0/8] Freq/CPU%/CORE_BUSY% support kan.liang@intel.com - 2015-09-16 23:40 +0200
[PATCH V10 3/8] perf,tools: caculate freq per sample kan.liang@intel.com - 2015-09-16 23:50 +0200
[PATCH V10 7/8] perf,tools: Introduce HPP__SINGLE_PRINT_FNS support kan.liang@intel.com - 2015-09-16 23:50 +0200
| From | kan.liang@intel.com |
|---|---|
| Date | 2015-09-16 23:40 +0200 |
| Subject | [PATCH V10 0/8] Freq/CPU%/CORE_BUSY% support |
| Message-ID | <q9sAN-8dL-3@gated-at.bofh.it> |
From: Kan Liang <kan.liang@intel.com>
This patch set supports per-sample freq/CPU%/CORE_BUSY% print in perf
report.
For printing these information, the perf.data file must have been obtained
by group read and using special events cycles, ref-cycles, msr/tsc/,
msr/aperf/ or msr/mperf/.
- Freq (MHz): The frequency during the sample interval. Needs cycles
ref-cycles event.
- CPU%: CPU utilization during the sample interval. Needs ref-cycles and
msr/tsc/ events.
- CORE_BUSY%: actual percent performance (APERF/MPERF%) during the
sample interval. Needs msr/aperf/ and msr/mperf/ events.
Here is an example:
$ perf record --perf-freq ~/tchain_edit
$ perf report --stdio --perf-freq
Overhead FREQ MHz CPU% CORE_BUSY%
Command Shared Object Symbol
........................................ ......... ..... ..........
........... ................ ......................
99.54% 99.54% 99.53% 99.53% 99.53% 2301 96 99
tchain_edit tchain_edit [.] f3
0.20% 0.20% 0.20% 0.20% 0.20% 2301 98 99
tchain_edit tchain_edit [.] f2
0.05% 0.05% 0.05% 0.05% 0.05% 2300 98 99
tchain_edit [kernel.vmlinux] [k] read_tsc
Changes since V1:
- Save cpu max freq to header when recording
- Read cpu max freq and msr type from header when reporting
Changes since V2:
- Introduce generic FEAT for CPU related data stored
- Make cpu max freq and msr type part of perf_session_env
- rename cpu_u to cpu_util
- Don't save sample value in perf_sample and discards new iterator.
Calculating the freq_perf_info in add_entry_cb callback
- Introduce symbol_conf.freq_perf_type for related hpp column visibility
Changes since V3:
- add a identifier 'tag' for CPU attributes, max frequency.
- add backpointers to evlist for env, and evsel for evlist.
- Use bitmask for freq_perf_type
- Replace macros by functions to caculate freq, cpu_util and core_busy
- Move all caculation codes under symbol_conf.show_freq_perf condition.
Changes since V4:
- Store cpu attributes id as tag and more readable cpu_attr
Changes since V5:
- Rename freq to max_freq and use it
- Add a loop in process_cpu_attributes to facility future extension
Changes since V6:
- Split rename perf_session_env and add backpointer to evlist patches
Changes since V7:
- Introduce --freq-perf option for perf record
- Factor out fix for dump_sample
Changes since V8:
- Rename --show-freq-perf to --freq-perf
- --freq-perf option imply --group
Changes since V9:
- Rebase on commit d71b0ad8d309
- Error handling for CPU attributes header write and process
- Rewrite the description for --perf-freq in perf record
- Add perf_freq_t in perf_sample to store frequency and performance data.
- rename --freq-perf to --perf-freq
- The last patch is split into three patches (6/8 only show leader value in hpp__fmt,
7/8 HPP__SINGLE_PRINT_FNS support and 8/8 perf report --perf-freq support)
Kan Liang (8):
perf,tools: introduce generic FEAT for CPU attributes
perf,record: introduce --perf-freq option
perf,tools: caculate freq per sample
perf,tools: Dump per-sample freq/CPU%/CORE_BUSY% in report -D
perf,tools: caculate and save freq/CPU%/CORE_BUSY% in he_stat
perf,tools: only show leader's value in hpp__fmt
perf,tools: Introduce HPP__SINGLE_PRINT_FNS support
perf,tools: Show freq/CPU%/CORE_BUSY% in perf report by --perf-freq
tools/perf/Documentation/perf-record.txt | 8 ++++
tools/perf/Documentation/perf-report.txt | 12 ++++++
tools/perf/builtin-record.c | 39 ++++++++++++++++++-
tools/perf/builtin-report.c | 41 ++++++++++++++++++++
tools/perf/ui/hist.c | 66 +++++++++++++++++++++++++++++---
tools/perf/util/env.h | 11 ++++++
tools/perf/util/event.h | 13 +++++++
tools/perf/util/header.c | 62 ++++++++++++++++++++++++++++++
tools/perf/util/header.h | 1 +
tools/perf/util/hist.h | 3 ++
tools/perf/util/session.c | 44 +++++++++++++++++++--
tools/perf/util/session.h | 52 +++++++++++++++++++++++++
tools/perf/util/sort.c | 3 ++
tools/perf/util/sort.h | 3 ++
tools/perf/util/symbol.h | 12 +++++-
15 files changed, 360 insertions(+), 10 deletions(-)
--
1.8.3.1
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[toc] | [next] | [standalone]
| From | kan.liang@intel.com |
|---|---|
| Date | 2015-09-16 23:50 +0200 |
| Subject | [PATCH V10 3/8] perf,tools: caculate freq per sample |
| Message-ID | <q9sKu-8q3-1@gated-at.bofh.it> |
| In reply to | #1226482 |
From: Kan Liang <kan.liang@intel.com>
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 <kan.liang@intel.com>
---
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 majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | kan.liang@intel.com |
|---|---|
| Date | 2015-09-16 23:50 +0200 |
| Subject | [PATCH V10 7/8] perf,tools: Introduce HPP__SINGLE_PRINT_FNS support |
| Message-ID | <q9sKu-8q3-17@gated-at.bofh.it> |
| In reply to | #1226482 |
From: Kan Liang <kan.liang@intel.com>
Normally, with group option set, all the events in the same group will
be print one by one. So the group header width is the sum of all events
width. However, for freqi/cpu%/CORE_BUSY% print, group events share the
same value. So only single event width is enough.
Signed-off-by: Kan Liang <kan.liang@intel.com>
---
tools/perf/ui/hist.c | 43 ++++++++++++++++++++++++++++++++++++++++++-
tools/perf/util/hist.h | 3 +++
tools/perf/util/sort.c | 3 +++
3 files changed, 48 insertions(+), 1 deletion(-)
diff --git a/tools/perf/ui/hist.c b/tools/perf/ui/hist.c
index c37aa6f..ba95ee2 100644
--- a/tools/perf/ui/hist.c
+++ b/tools/perf/ui/hist.c
@@ -235,6 +235,25 @@ static int hpp__header_fn(struct perf_hpp_fmt *fmt, struct perf_hpp *hpp,
return scnprintf(hpp->buf, hpp->size, "%*s", len, fmt->name);
}
+static int hpp__single_width_fn(struct perf_hpp_fmt *fmt,
+ struct perf_hpp *hpp __maybe_unused,
+ struct perf_evsel *evsel __maybe_unused)
+{
+ int len = fmt->user_len ?: fmt->len;
+
+ if (len < (int)strlen(fmt->name))
+ len = strlen(fmt->name);
+
+ return len;
+}
+
+static int hpp__single_header_fn(struct perf_hpp_fmt *fmt, struct perf_hpp *hpp,
+ struct perf_evsel *evsel)
+{
+ int len = hpp__single_width_fn(fmt, hpp, evsel);
+ return scnprintf(hpp->buf, hpp->size, "%*s", len, fmt->name);
+}
+
static int hpp_color_scnprintf(struct perf_hpp *hpp, const char *fmt, ...)
{
va_list args;
@@ -364,6 +383,9 @@ HPP_PERCENT_ACC_FNS(overhead_acc, period)
HPP_RAW_FNS(samples, nr_events)
HPP_RAW_FNS(period, period)
+HPP_RAW_FNS(freq, freq)
+HPP_RAW_FNS(cpu_util, cpu_util)
+HPP_RAW_FNS(core_busy, core_busy)
static int64_t hpp__nop_cmp(struct perf_hpp_fmt *fmt __maybe_unused,
struct hist_entry *a __maybe_unused,
@@ -407,6 +429,17 @@ static int64_t hpp__nop_cmp(struct perf_hpp_fmt *fmt __maybe_unused,
.sort = hpp__sort_ ## _fn, \
}
+#define HPP__SINGLE_PRINT_FNS(_name, _fn) \
+ { \
+ .name = _name, \
+ .header = hpp__single_header_fn, \
+ .width = hpp__single_width_fn, \
+ .entry = hpp__entry_ ## _fn, \
+ .cmp = hpp__nop_cmp, \
+ .collapse = hpp__nop_cmp, \
+ .sort = hpp__sort_ ## _fn, \
+ }
+
struct perf_hpp_fmt perf_hpp__format[] = {
HPP__COLOR_PRINT_FNS("Overhead", overhead),
HPP__COLOR_PRINT_FNS("sys", overhead_sys),
@@ -415,7 +448,10 @@ struct perf_hpp_fmt perf_hpp__format[] = {
HPP__COLOR_PRINT_FNS("guest usr", overhead_guest_us),
HPP__COLOR_ACC_PRINT_FNS("Children", overhead_acc),
HPP__PRINT_FNS("Samples", samples),
- HPP__PRINT_FNS("Period", period)
+ HPP__PRINT_FNS("Period", period),
+ HPP__SINGLE_PRINT_FNS("FREQ MHz", freq),
+ HPP__SINGLE_PRINT_FNS("CPU%", cpu_util),
+ HPP__SINGLE_PRINT_FNS("CORE_BUSY%", core_busy)
};
LIST_HEAD(perf_hpp__list);
@@ -653,6 +689,9 @@ void perf_hpp__reset_width(struct perf_hpp_fmt *fmt, struct hists *hists)
return;
switch (idx) {
+ case PERF_HPP__CPU_UTIL:
+ fmt->len = 5;
+ break;
case PERF_HPP__OVERHEAD:
case PERF_HPP__OVERHEAD_SYS:
case PERF_HPP__OVERHEAD_US:
@@ -662,6 +701,8 @@ void perf_hpp__reset_width(struct perf_hpp_fmt *fmt, struct hists *hists)
case PERF_HPP__OVERHEAD_GUEST_SYS:
case PERF_HPP__OVERHEAD_GUEST_US:
+ case PERF_HPP__FREQ:
+ case PERF_HPP__CORE_BUSY:
fmt->len = 9;
break;
diff --git a/tools/perf/util/hist.h b/tools/perf/util/hist.h
index 4d6aa1d..664b34d 100644
--- a/tools/perf/util/hist.h
+++ b/tools/perf/util/hist.h
@@ -241,6 +241,9 @@ enum {
PERF_HPP__OVERHEAD_ACC,
PERF_HPP__SAMPLES,
PERF_HPP__PERIOD,
+ PERF_HPP__FREQ,
+ PERF_HPP__CPU_UTIL,
+ PERF_HPP__CORE_BUSY,
PERF_HPP__MAX_INDEX
};
diff --git a/tools/perf/util/sort.c b/tools/perf/util/sort.c
index 6b9556d..1647802 100644
--- a/tools/perf/util/sort.c
+++ b/tools/perf/util/sort.c
@@ -1326,6 +1326,9 @@ static struct hpp_dimension hpp_sort_dimensions[] = {
DIM(PERF_HPP__OVERHEAD_ACC, "overhead_children"),
DIM(PERF_HPP__SAMPLES, "sample"),
DIM(PERF_HPP__PERIOD, "period"),
+ DIM(PERF_HPP__FREQ, "freq"),
+ DIM(PERF_HPP__CPU_UTIL, "cpu_u"),
+ DIM(PERF_HPP__CORE_BUSY, "core_busy"),
};
#undef DIM
--
1.8.3.1
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [standalone]
Back to top | Article view | linux.kernel
csiph-web