Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1203127 > unrolled thread
| Started by | Andi Kleen <andi@firstfloor.org> |
|---|---|
| First post | 2015-08-08 03:10 +0200 |
| Last post | 2015-08-08 03:10 +0200 |
| Articles | 20 — 3 participants |
Back to article view | Back to linux.kernel
Add top down metrics to perf stat Andi Kleen <andi@firstfloor.org> - 2015-08-08 03:10 +0200
[PATCH 1/9] perf, tools: Dont stop PMU parsing on alias parse error Andi Kleen <andi@firstfloor.org> - 2015-08-08 03:10 +0200
Re: [PATCH 1/9] perf, tools: Dont stop PMU parsing on alias parse error Jiri Olsa <jolsa@redhat.com> - 2015-08-11 15:10 +0200
Re: [PATCH 1/9] perf, tools: Dont stop PMU parsing on alias parse error Andi Kleen <ak@linux.intel.com> - 2015-08-11 15:20 +0200
Re: [PATCH 1/9] perf, tools: Dont stop PMU parsing on alias parse error Jiri Olsa <jolsa@redhat.com> - 2015-08-11 15:30 +0200
Re: [PATCH 1/9] perf, tools: Dont stop PMU parsing on alias parse error Andi Kleen <ak@linux.intel.com> - 2015-08-11 15:50 +0200
Re: [PATCH 1/9] perf, tools: Dont stop PMU parsing on alias parse error Jiri Olsa <jolsa@redhat.com> - 2015-08-11 16:40 +0200
Re: [PATCH 1/9] perf, tools: Dont stop PMU parsing on alias parse error Andi Kleen <andi@firstfloor.org> - 2015-08-11 19:00 +0200
[PATCH 7/9] x86, perf: Add Top Down events to Intel Atom Andi Kleen <andi@firstfloor.org> - 2015-08-08 03:10 +0200
[PATCH 3/9] perf, tools, stat: Basic support for TopDown in perf stat Andi Kleen <andi@firstfloor.org> - 2015-08-08 03:10 +0200
[PATCH 2/9] perf, tools, stat: Support up-scaling of events Andi Kleen <andi@firstfloor.org> - 2015-08-08 03:10 +0200
Re: [PATCH 2/9] perf, tools, stat: Support up-scaling of events Jiri Olsa <jolsa@redhat.com> - 2015-08-11 15:30 +0200
Re: [PATCH 2/9] perf, tools, stat: Support up-scaling of events Andi Kleen <ak@linux.intel.com> - 2015-08-11 15:40 +0200
Re: [PATCH 2/9] perf, tools, stat: Support up-scaling of events Jiri Olsa <jolsa@redhat.com> - 2015-08-11 16:00 +0200
Re: [PATCH 2/9] perf, tools, stat: Support up-scaling of events Andi Kleen <andi@firstfloor.org> - 2015-08-11 19:10 +0200
Re: [PATCH 2/9] perf, tools, stat: Support up-scaling of events Jiri Olsa <jolsa@redhat.com> - 2015-08-11 19:20 +0200
Re: [PATCH 2/9] perf, tools, stat: Support up-scaling of events Andi Kleen <andi@firstfloor.org> - 2015-08-11 19:20 +0200
[PATCH 5/9] x86, perf: Support sysfs files depending on SMT status Andi Kleen <andi@firstfloor.org> - 2015-08-08 03:10 +0200
[PATCH 6/9] x86, perf: Add Top Down events to Intel Core Andi Kleen <andi@firstfloor.org> - 2015-08-08 03:10 +0200
[PATCH 8/9] perf, tools, stat: Add extra output of counter values with -v Andi Kleen <andi@firstfloor.org> - 2015-08-08 03:10 +0200
| From | Andi Kleen <andi@firstfloor.org> |
|---|---|
| Date | 2015-08-08 03:10 +0200 |
| Subject | Add top down metrics to perf stat |
| Message-ID | <pV0O5-fI-7@gated-at.bofh.it> |
This patchkit adds support for TopDown to perf stat
It applies on top of my earlier metrics patchkit, posted
separately.
TopDown is intended to replace the frontend cycles idle/
backend cycles idle metrics in standard perf stat output.
These metrics are not reliable in many workloads,
due to out of order effects.
This implements a new --topdown mode in perf stat
(similar to --transaction) that measures the pipe line
bottlenecks using standardized formulas. The measurement
can be all done with 5 counters (one fixed counter)
The result are four metrics:
FrontendBound, BackendBound, BadSpeculation, Retiring
that describe the CPU pipeline behavior on a high level.
FrontendBound and BackendBound
BadSpeculation is a higher
The full top down methology has many hierarchical metrics.
This implementation only supports level 1 which can be
collected without multiplexing. A full implementation
of top down on top of perf is available in pmu-tools toplev.
(http://github.com/andikleen/pmu-tools)
The current version works on Intel Core CPUs starting
with Sandy Bridge, and Atom CPUs starting with Silvermont.
In principle the generic metrics should be also implementable
on other out of order CPUs.
TopDown level 1 uses a set of abstracted metrics which
are generic to out of order CPU cores (although some
CPUs may not implement all of them):
topdown-total-slots Available slots in the pipeline
topdown-slots-issued Slots issued into the pipeline
topdown-slots-retired Slots successfully retired
topdown-fetch-bubbles Pipeline gaps in the frontend
topdown-recovery-bubbles Pipeline gaps during recovery
from misspeculation
These metrics then allow to compute four useful metrics:
FrontendBound, BackendBound, Retiring, BadSpeculation.
The formulas to compute the metrics are generic, they
only change based on the availability on the abstracted
input values.
The kernel declares the events supported by the current
CPU and perf stat then computes the formulas based on the
available metrics.
Example output:
$ ./perf stat --topdown -a ./BC1s
Performance counter stats for 'system wide':
S0-C0 2 19650790 topdown-total-slots (100.00%)
S0-C0 2 4445680.00 topdown-fetch-bubbles # 22.62% frontend bound (100.00%)
S0-C0 2 1743552.00 topdown-slots-retired (100.00%)
S0-C0 2 622954 topdown-recovery-bubbles (100.00%)
S0-C0 2 2025498.00 topdown-slots-issued # 63.90% backend bound
S0-C1 2 16685216540 topdown-total-slots (100.00%)
S0-C1 2 962557931.00 topdown-fetch-bubbles (100.00%)
S0-C1 2 4175583320.00 topdown-slots-retired (100.00%)
S0-C1 2 1743329246 topdown-recovery-bubbles # 22.22% bad speculation (100.00%)
S0-C1 2 6138901193.50 topdown-slots-issued # 46.99% backend bound
1.535832673 seconds time elapsed
On Hyper Threaded CPUs Top Down computes metrics per core instead of per logical CPU.
In this case perf stat automatically enables --per-core mode and also requires
global mode (-a) and avoiding other filters (no cgroup mode)
One side effect is that this may require root rights or a
kernel.perf_event_paranoid=-1 setting.
On systems without Hyper Threading it can be used per process.
Full tree available in
git://git.kernel.org/pub/scm/linux/kernel/git/ak/linux-misc perf/top-down-2
--
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 | Andi Kleen <andi@firstfloor.org> |
|---|---|
| Date | 2015-08-08 03:10 +0200 |
| Subject | [PATCH 1/9] perf, tools: Dont stop PMU parsing on alias parse error |
| Message-ID | <pV0O6-fI-19@gated-at.bofh.it> |
| In reply to | #1203127 |
From: Andi Kleen <ak@linux.intel.com>
When an error happens during alias parsing currently the complete
parsing of all attributes of the PMU is stopped. This is breaks
old perf on a newer kernel that may have not-yet-know
alias attributes (such as .scale or .per-pkg).
Continue when some attribute is unparseable.
This is IMHO a stable candidate and should be backported
to older versions to avoid problems with newer kernels.
Signed-off-by: Andi Kleen <ak@linux.intel.com>
---
tools/perf/util/pmu.c | 10 ++++------
1 file changed, 4 insertions(+), 6 deletions(-)
diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c
index d4b0e64..ce56354 100644
--- a/tools/perf/util/pmu.c
+++ b/tools/perf/util/pmu.c
@@ -283,13 +283,12 @@ static int pmu_aliases_parse(char *dir, struct list_head *head)
{
struct dirent *evt_ent;
DIR *event_dir;
- int ret = 0;
event_dir = opendir(dir);
if (!event_dir)
return -EINVAL;
- while (!ret && (evt_ent = readdir(event_dir))) {
+ while ((evt_ent = readdir(event_dir))) {
char path[PATH_MAX];
char *name = evt_ent->d_name;
FILE *file;
@@ -305,17 +304,16 @@ static int pmu_aliases_parse(char *dir, struct list_head *head)
snprintf(path, PATH_MAX, "%s/%s", dir, name);
- ret = -EINVAL;
file = fopen(path, "r");
if (!file)
- break;
+ continue;
- ret = perf_pmu__new_alias(head, dir, name, file);
+ perf_pmu__new_alias(head, dir, name, file);
fclose(file);
}
closedir(event_dir);
- return ret;
+ return 0;
}
/*
--
2.4.3
--
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 | Jiri Olsa <jolsa@redhat.com> |
|---|---|
| Date | 2015-08-11 15:10 +0200 |
| Subject | Re: [PATCH 1/9] perf, tools: Dont stop PMU parsing on alias parse error |
| Message-ID | <pWhtw-5ZS-35@gated-at.bofh.it> |
| In reply to | #1203128 |
On Fri, Aug 07, 2015 at 06:06:17PM -0700, Andi Kleen wrote:
> From: Andi Kleen <ak@linux.intel.com>
>
> When an error happens during alias parsing currently the complete
> parsing of all attributes of the PMU is stopped. This is breaks
> old perf on a newer kernel that may have not-yet-know
> alias attributes (such as .scale or .per-pkg).
hum, both .scale and .per-pgk are skip from term parsing via:
/*
* skip info files parsed in perf_pmu__new_alias()
*/
if (pmu_alias_info_file(name))
continue;
and loaded without any error report:
static int __perf_pmu__new_alias(struct list_head *list, char *dir, char *name,
char *desc __maybe_unused, char *val)
SNIP
if (dir) {
/*
* load unit name and scale if available
*/
perf_pmu__parse_unit(alias, dir, name);
perf_pmu__parse_scale(alias, dir, name);
perf_pmu__parse_per_pkg(alias, dir, name);
perf_pmu__parse_snapshot(alias, dir, name);
}
list_add_tail(&alias->list, list);
return 0;
}
Which attribute parsing is failing for you?
thanks,
jirka
--
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 | Andi Kleen <ak@linux.intel.com> |
|---|---|
| Date | 2015-08-11 15:20 +0200 |
| Subject | Re: [PATCH 1/9] perf, tools: Dont stop PMU parsing on alias parse error |
| Message-ID | <pWhDc-6bn-1@gated-at.bofh.it> |
| In reply to | #1205125 |
> Which attribute parsing is failing for you? The new .agg-per-core attribute I added later in the series. I think it will happen to any not-yet-known attribute. -Andi -- 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 | Jiri Olsa <jolsa@redhat.com> |
|---|---|
| Date | 2015-08-11 15:30 +0200 |
| Subject | Re: [PATCH 1/9] perf, tools: Dont stop PMU parsing on alias parse error |
| Message-ID | <pWhMS-6mR-15@gated-at.bofh.it> |
| In reply to | #1205128 |
On Tue, Aug 11, 2015 at 06:14:57AM -0700, Andi Kleen wrote: > > Which attribute parsing is failing for you? > > The new .agg-per-core attribute I added later in the series. > I think it will happen to any not-yet-known attribute. alias can contain only terms defined in formats directory, and the *.XXX attributes parsing does not return error code can't see the failure, please get some example jirka -- 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 | Andi Kleen <ak@linux.intel.com> |
|---|---|
| Date | 2015-08-11 15:50 +0200 |
| Subject | Re: [PATCH 1/9] perf, tools: Dont stop PMU parsing on alias parse error |
| Message-ID | <pWi6d-6Jq-3@gated-at.bofh.it> |
| In reply to | #1205135 |
On Tue, Aug 11, 2015 at 03:24:27PM +0200, Jiri Olsa wrote: > On Tue, Aug 11, 2015 at 06:14:57AM -0700, Andi Kleen wrote: > > > Which attribute parsing is failing for you? > > > > The new .agg-per-core attribute I added later in the series. > > I think it will happen to any not-yet-known attribute. > > alias can contain only terms defined in formats directory, > and the *.XXX attributes parsing does not return error code > > can't see the failure, please get some example Apply the kernel patch that adds several .agg-per-core attributes Then try to use any cpu/.../ event % perf stat -e cpu/event=0x3c/ true invalid or unsupported event: 'cpu/event=0x3c/' because the PMU parsing bailed out. With patched perf (either this patch or the patch that adds the .agg-per-core parsing) it works. -Andi -- 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 | Jiri Olsa <jolsa@redhat.com> |
|---|---|
| Date | 2015-08-11 16:40 +0200 |
| Subject | Re: [PATCH 1/9] perf, tools: Dont stop PMU parsing on alias parse error |
| Message-ID | <pWiSB-7UI-15@gated-at.bofh.it> |
| In reply to | #1205147 |
On Tue, Aug 11, 2015 at 06:40:27AM -0700, Andi Kleen wrote:
> On Tue, Aug 11, 2015 at 03:24:27PM +0200, Jiri Olsa wrote:
> > On Tue, Aug 11, 2015 at 06:14:57AM -0700, Andi Kleen wrote:
> > > > Which attribute parsing is failing for you?
> > >
> > > The new .agg-per-core attribute I added later in the series.
> > > I think it will happen to any not-yet-known attribute.
> >
> > alias can contain only terms defined in formats directory,
> > and the *.XXX attributes parsing does not return error code
> >
> > can't see the failure, please get some example
>
> Apply the kernel patch that adds several .agg-per-core attributes
> Then try to use any cpu/.../ event
>
> % perf stat -e cpu/event=0x3c/ true
> invalid or unsupported event: 'cpu/event=0x3c/'
>
> because the PMU parsing bailed out.
ugh right, the new attribute wont be recognized..
how about recognizing attribute based on the '.' prefix being
existing file rather than the suffix like in the attached patch
jirka
---
diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c
index d4b0e6454bc6..937ecc35a60e 100644
--- a/tools/perf/util/pmu.c
+++ b/tools/perf/util/pmu.c
@@ -258,21 +258,23 @@ static int perf_pmu__new_alias(struct list_head *list, char *dir, char *name, FI
return __perf_pmu__new_alias(list, dir, name, NULL, buf);
}
-static inline bool pmu_alias_info_file(char *name)
+static inline bool pmu_alias_attr_file(char *dir, char *name)
{
- size_t len;
-
- len = strlen(name);
- if (len > 5 && !strcmp(name + len - 5, ".unit"))
- return true;
- if (len > 6 && !strcmp(name + len - 6, ".scale"))
- return true;
- if (len > 8 && !strcmp(name + len - 8, ".per-pkg"))
- return true;
- if (len > 9 && !strcmp(name + len - 9, ".snapshot"))
- return true;
+ bool ret = false;
+ struct stat st;
+ char *path, *s;
- return false;
+ if (asprintf(&path, "%s/%s", dir, name) == -1)
+ return false;
+
+ s = strrchr(path, '.');
+ if (s) {
+ *s = 0;
+ ret = !stat(path, &st);
+ }
+
+ free(path);
+ return ret;
}
/*
@@ -300,7 +302,7 @@ static int pmu_aliases_parse(char *dir, struct list_head *head)
/*
* skip info files parsed in perf_pmu__new_alias()
*/
- if (pmu_alias_info_file(name))
+ if (pmu_alias_attr_file(dir, name))
continue;
snprintf(path, PATH_MAX, "%s/%s", dir, name);
--
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 | Andi Kleen <andi@firstfloor.org> |
|---|---|
| Date | 2015-08-11 19:00 +0200 |
| Subject | Re: [PATCH 1/9] perf, tools: Dont stop PMU parsing on alias parse error |
| Message-ID | <pWl46-2zU-7@gated-at.bofh.it> |
| In reply to | #1205183 |
> how about recognizing attribute based on the '.' prefix being > existing file rather than the suffix like in the attached patch Fine too. My patch is simpler and works well enough though, and also handles other cases. -Andi -- 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 | Andi Kleen <andi@firstfloor.org> |
|---|---|
| Date | 2015-08-08 03:10 +0200 |
| Subject | [PATCH 7/9] x86, perf: Add Top Down events to Intel Atom |
| Message-ID | <pV0O6-fI-23@gated-at.bofh.it> |
| In reply to | #1203127 |
From: Andi Kleen <ak@linux.intel.com>
Add topdown event declarations to Silvermont / Airmont.
These cores do not support the full Top Down metrics, but an useful
subset (FrontendBound, Retiring, Backend Bound/Bad Speculation).
The perf stat tool automatically handles the missing events
and combines the available metrics.
Signed-off-by: Andi Kleen <ak@linux.intel.com>
---
arch/x86/kernel/cpu/perf_event_intel.c | 24 ++++++++++++++++++++++++
1 file changed, 24 insertions(+)
diff --git a/arch/x86/kernel/cpu/perf_event_intel.c b/arch/x86/kernel/cpu/perf_event_intel.c
index 65b58cb..1f08603 100644
--- a/arch/x86/kernel/cpu/perf_event_intel.c
+++ b/arch/x86/kernel/cpu/perf_event_intel.c
@@ -1380,6 +1380,29 @@ static __initconst const u64 atom_hw_cache_event_ids
},
};
+EVENT_ATTR_STR(topdown-total-slots, td_total_slots_slm, "event=0x3c");
+EVENT_ATTR_STR(topdown-total-slots.scale, td_total_slots_scale_slm, "-2");
+/* no_alloc_cycles.not_delivered */
+EVENT_ATTR_STR(topdown-fetch-bubbles, td_fetch_bubbles_slm,
+ "event=0xca,umask=0x50");
+EVENT_ATTR_STR(topdown-fetch-bubbles.scale, td_fetch_bubbles_scale_slm, "-2");
+/* uops_retired.all */
+EVENT_ATTR_STR(topdown-slots-issued, td_slots_issued_slm,
+ "event=0xc2,umask=0x10");
+/* uops_retired.all */
+EVENT_ATTR_STR(topdown-slots-retired, td_slots_retired_slm,
+ "event=0xc2,umask=0x10");
+
+struct attribute *slm_events_attrs[] = {
+ EVENT_PTR(td_total_slots_slm),
+ EVENT_PTR(td_total_slots_scale_slm),
+ EVENT_PTR(td_fetch_bubbles_slm),
+ EVENT_PTR(td_fetch_bubbles_scale_slm),
+ EVENT_PTR(td_slots_issued_slm),
+ EVENT_PTR(td_slots_retired_slm),
+ NULL
+};
+
static struct extra_reg intel_slm_extra_regs[] __read_mostly =
{
/* must define OFFCORE_RSP_X first, see intel_fixup_er() */
@@ -3401,6 +3424,7 @@ __init int intel_pmu_init(void)
x86_pmu.pebs_constraints = intel_slm_pebs_event_constraints;
x86_pmu.extra_regs = intel_slm_extra_regs;
x86_pmu.flags |= PMU_FL_HAS_RSP_1;
+ x86_pmu.cpu_events = slm_events_attrs;
pr_cont("Silvermont events, ");
break;
--
2.4.3
--
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 | Andi Kleen <andi@firstfloor.org> |
|---|---|
| Date | 2015-08-08 03:10 +0200 |
| Subject | [PATCH 3/9] perf, tools, stat: Basic support for TopDown in perf stat |
| Message-ID | <pV0O6-fI-13@gated-at.bofh.it> |
| In reply to | #1203127 |
From: Andi Kleen <ak@linux.intel.com>
Add basic plumbing for TopDown in perf stat
Add a new --topdown options to enable events.
When --topdown is specified set up events for all topdown
events supported by the kernel.
Add topdown-* as a special case to the event parser, as is
needed for all events containing -.
The actual code to compute the metrics is in follow-on patches.
Signed-off-by: Andi Kleen <ak@linux.intel.com>
---
tools/perf/Documentation/perf-stat.txt | 8 +++
tools/perf/builtin-stat.c | 124 ++++++++++++++++++++++++++++++++-
tools/perf/util/parse-events.l | 1 +
3 files changed, 131 insertions(+), 2 deletions(-)
diff --git a/tools/perf/Documentation/perf-stat.txt b/tools/perf/Documentation/perf-stat.txt
index 47469ab..86c03e9 100644
--- a/tools/perf/Documentation/perf-stat.txt
+++ b/tools/perf/Documentation/perf-stat.txt
@@ -158,6 +158,14 @@ filter out the startup phase of the program, which is often very different.
Print statistics of transactional execution if supported.
+--topdown::
+
+Print top down level 1 metrics if supported by the CPU. This allows to
+determine bottle necks in the CPU pipeline for CPU bound workloads,
+by breaking it down into frontend bound, backend bound, bad speculation
+and retiring. Specifying the option multiple times shows metrics even
+if the don't cross a threshold.
+
EXAMPLES
--------
diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
index 2590c75..a83f26f 100644
--- a/tools/perf/builtin-stat.c
+++ b/tools/perf/builtin-stat.c
@@ -93,6 +93,15 @@ static const char * transaction_limited_attrs = {
"}"
};
+static const char * topdown_attrs[] = {
+ "topdown-total-slots",
+ "topdown-fetch-bubbles",
+ "topdown-slots-retired",
+ "topdown-recovery-bubbles",
+ "topdown-slots-issued",
+ NULL,
+};
+
static struct perf_evlist *evsel_list;
static struct target target = {
@@ -105,6 +114,7 @@ static volatile pid_t child_pid = -1;
static bool null_run = false;
static int detailed_run = 0;
static bool transaction_run;
+static int topdown_run = 0;
static bool big_num = true;
static int big_num_opt = -1;
static const char *csv_sep = NULL;
@@ -735,7 +745,8 @@ static void printout(int id, int nr, struct perf_evsel *counter, double uval,
first_shadow_cpu(counter, id),
pm,
nl,
- &os);
+ &os,
+ topdown_run);
if (!csv_output) {
print_noise(counter, noise);
@@ -1093,12 +1104,90 @@ static int perf_stat_init_aggr_mode(void)
return 0;
}
+static void filter_events(const char **attr, char **str, bool use_group)
+{
+ int off = 0;
+ int i;
+ int len = 0;
+ char *s;
+
+ for (i = 0; attr[i]; i++) {
+ if (pmu_have_event("cpu", attr[i])) {
+ len += strlen(attr[i]) + 1;
+ attr[i - off] = attr[i];
+ } else
+ off++;
+ }
+ attr[i - off] = NULL;
+
+ *str = malloc(len + 1 + 2);
+ if (!*str)
+ return;
+ s = *str;
+ if (i - off == 0) {
+ *s = 0;
+ return;
+ }
+ if (use_group)
+ *s++ = '{';
+ for (i = 0; attr[i]; i++) {
+ strcpy(s, attr[i]);
+ s += strlen(s);
+ *s++ = ',';
+ }
+ if (use_group) {
+ s[-1] = '}';
+ *s = 0;
+ } else
+ s[-1] = 0;
+}
+
+/* Caller must free result */
+static char *sysctl_read(const char *fn)
+{
+ int n;
+ char *line = NULL;
+ size_t linelen = 0;
+ FILE *f = fopen(fn, "r");
+ if (!f)
+ return NULL;
+ n = getline(&line, &linelen, f);
+ fclose(f);
+ if (n > 0)
+ return line;
+ free(line);
+ return NULL;
+}
+
+/*
+ * Check whether we can use a group for top down.
+ * Without a group may get bad results.
+ */
+static bool check_group(bool *warn)
+{
+ char *v = sysctl_read("/proc/sys/kernel/nmi_watchdog");
+ int n;
+
+ *warn = false;
+ if (v) {
+ bool res = sscanf(v, "%d", &n) == 1 && n != 0;
+ free(v);
+ if (res) {
+ *warn = true;
+ return false;
+ }
+ return true;
+ }
+ return false; /* Don't know, so don't use group */
+}
+
/*
* Add default attributes, if there were no attributes specified or
* if -d/--detailed, -d -d or -d -d -d is used:
*/
static int add_default_attributes(void)
{
+ int err;
struct perf_event_attr default_attrs[] = {
{ .type = PERF_TYPE_SOFTWARE, .config = PERF_COUNT_SW_TASK_CLOCK },
@@ -1211,7 +1300,6 @@ static int add_default_attributes(void)
return 0;
if (transaction_run) {
- int err;
if (pmu_have_event("cpu", "cycles-ct") &&
pmu_have_event("cpu", "el-start"))
err = parse_events(evsel_list, transaction_attrs, NULL);
@@ -1224,6 +1312,36 @@ static int add_default_attributes(void)
return 0;
}
+ if (topdown_run) {
+ char *str = NULL;
+ bool warn;
+
+ filter_events(topdown_attrs, &str, check_group(&warn));
+ if (topdown_attrs[0] && str) {
+ if (warn)
+ fprintf(stderr,
+ "nmi_watchdog enabled with topdown. May give wrong results.\n"
+ "Disable with echo 0 > /proc/sys/kernel/nmi_watchdog\n");
+ err = parse_events(evsel_list, str, NULL);
+ if (err) {
+ fprintf(stderr,
+ "Cannot set up top down events %s: %d\n",
+ str, err);
+ free(str);
+ return -1;
+ }
+ } else {
+ fprintf(stderr, "System does not support topdown\n");
+ return -1;
+ }
+ free(str);
+ /*
+ * Right now combining with the other attributes breaks group
+ * semantics.
+ */
+ return 0;
+ }
+
if (!evsel_list->nr_entries) {
if (perf_evlist__add_default_attrs(evsel_list, default_attrs) < 0)
return -1;
@@ -1260,6 +1378,8 @@ int cmd_stat(int argc, const char **argv, const char *prefix __maybe_unused)
const struct option options[] = {
OPT_BOOLEAN('T', "transaction", &transaction_run,
"hardware transaction statistics"),
+ OPT_INCR(0, "topdown", &topdown_run,
+ "measure topdown level 1 statistics"),
OPT_CALLBACK('e', "event", &evsel_list, "event",
"event selector. use 'perf list' to list available events",
parse_events_option),
diff --git a/tools/perf/util/parse-events.l b/tools/perf/util/parse-events.l
index f542750..a3b9903 100644
--- a/tools/perf/util/parse-events.l
+++ b/tools/perf/util/parse-events.l
@@ -239,6 +239,7 @@ cycles-ct { return str(yyscanner, PE_KERNEL_PMU_EVENT); }
cycles-t { return str(yyscanner, PE_KERNEL_PMU_EVENT); }
mem-loads { return str(yyscanner, PE_KERNEL_PMU_EVENT); }
mem-stores { return str(yyscanner, PE_KERNEL_PMU_EVENT); }
+topdown-[a-z-]+ { return str(yyscanner, PE_KERNEL_PMU_EVENT); }
L1-dcache|l1-d|l1d|L1-data |
L1-icache|l1-i|l1i|L1-instruction |
--
2.4.3
--
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 | Andi Kleen <andi@firstfloor.org> |
|---|---|
| Date | 2015-08-08 03:10 +0200 |
| Subject | [PATCH 2/9] perf, tools, stat: Support up-scaling of events |
| Message-ID | <pV0O7-fI-29@gated-at.bofh.it> |
| In reply to | #1203127 |
From: Andi Kleen <ak@linux.intel.com>
TopDown needs to multiply events by constants (for example
the CPU Pipeline Width) to get the correct results.
The kernel needs to export this factor.
Today *.scale is only used to scale down metrics (divide), for example
to scale bytes to MB.
Repurpose negative scale to mean scaling up, that is multiplying.
Implement the code for this in perf stat.
Signed-off-by: Andi Kleen <ak@linux.intel.com>
---
tools/perf/builtin-stat.c | 27 +++++++++++++++++++--------
1 file changed, 19 insertions(+), 8 deletions(-)
diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
index ea5298a..2590c75 100644
--- a/tools/perf/builtin-stat.c
+++ b/tools/perf/builtin-stat.c
@@ -179,6 +179,17 @@ static inline int nsec_counter(struct perf_evsel *evsel)
return 0;
}
+static double scale_val(struct perf_evsel *counter, u64 val)
+{
+ double uval = val;
+
+ if (counter->scale < 0)
+ uval = val * (-counter->scale);
+ else if (counter->scale)
+ uval = val / counter->scale;
+ return uval;
+}
+
/*
* Read out the results of a single counter:
* do not aggregate counts across CPUs in system-wide mode
@@ -630,12 +641,12 @@ static void abs_printout(int id, int nr, struct perf_evsel *evsel, double avg)
const char *fmt;
if (csv_output) {
- fmt = sc != 1.0 ? "%.2f%s" : "%.0f%s";
+ fmt = (sc != 1.0 && sc > 0) ? "%.2f%s" : "%.0f%s";
} else {
if (big_num)
- fmt = sc != 1.0 ? "%'18.2f%s" : "%'18.0f%s";
+ fmt = (sc != 1.0 && sc > 0) ? "%'18.2f%s" : "%'18.0f%s";
else
- fmt = sc != 1.0 ? "%18.2f%s" : "%18.0f%s";
+ fmt = (sc != 1.0 && sc > 0) ? "%18.2f%s" : "%18.0f%s";
}
aggr_printout(evsel, id, nr);
@@ -750,7 +761,7 @@ static void aggr_update_shadow(void)
continue;
val += perf_counts(counter->counts, cpu, 0)->val;
}
- val = val * counter->scale;
+ val = scale_val(counter, val);
perf_stat__update_shadow_stats(counter, &val,
first_shadow_cpu(counter, id));
}
@@ -788,7 +799,7 @@ static void print_aggr(char *prefix)
if (prefix)
fprintf(output, "%s", prefix);
- uval = val * counter->scale;
+ uval = scale_val(counter, val);
printout(id, nr, counter, uval, prefix, run, ena, 1.0);
fputc('\n', output);
}
@@ -815,7 +826,7 @@ static void print_aggr_thread(struct perf_evsel *counter, char *prefix)
if (prefix)
fprintf(output, "%s", prefix);
- uval = val * counter->scale;
+ uval = scale_val(counter, val);
printout(thread, 0, counter, uval, prefix, run, ena, 1.0);
fputc('\n', output);
}
@@ -860,7 +871,7 @@ static void print_counter_aggr(struct perf_evsel *counter, char *prefix)
return;
}
- uval = avg * counter->scale;
+ uval = scale_val(counter, avg);
printout(-1, 0, counter, uval, prefix, avg_running, avg_enabled, avg);
fprintf(output, "\n");
}
@@ -884,7 +895,7 @@ static void print_counter(struct perf_evsel *counter, char *prefix)
if (prefix)
fprintf(output, "%s", prefix);
- uval = val * counter->scale;
+ uval = scale_val(counter, val);
printout(cpu, 0, counter, uval, prefix, run, ena, 1.0);
fputc('\n', output);
--
2.4.3
--
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 | Jiri Olsa <jolsa@redhat.com> |
|---|---|
| Date | 2015-08-11 15:30 +0200 |
| Subject | Re: [PATCH 2/9] perf, tools, stat: Support up-scaling of events |
| Message-ID | <pWhMR-6mR-1@gated-at.bofh.it> |
| In reply to | #1203132 |
On Fri, Aug 07, 2015 at 06:06:18PM -0700, Andi Kleen wrote:
> From: Andi Kleen <ak@linux.intel.com>
>
> TopDown needs to multiply events by constants (for example
> the CPU Pipeline Width) to get the correct results.
> The kernel needs to export this factor.
>
> Today *.scale is only used to scale down metrics (divide), for example
> to scale bytes to MB.
>
> Repurpose negative scale to mean scaling up, that is multiplying.
> Implement the code for this in perf stat.
>
> Signed-off-by: Andi Kleen <ak@linux.intel.com>
> ---
> tools/perf/builtin-stat.c | 27 +++++++++++++++++++--------
> 1 file changed, 19 insertions(+), 8 deletions(-)
>
> diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
> index ea5298a..2590c75 100644
> --- a/tools/perf/builtin-stat.c
> +++ b/tools/perf/builtin-stat.c
> @@ -179,6 +179,17 @@ static inline int nsec_counter(struct perf_evsel *evsel)
> return 0;
> }
>
> +static double scale_val(struct perf_evsel *counter, u64 val)
> +{
> + double uval = val;
> +
> + if (counter->scale < 0)
> + uval = val * (-counter->scale);
> + else if (counter->scale)
> + uval = val / counter->scale;
hum, do you change the scale logic? the current scale > 0 works like:
uval = val * counter->scale;
jirka
--
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 | Andi Kleen <ak@linux.intel.com> |
|---|---|
| Date | 2015-08-11 15:40 +0200 |
| Subject | Re: [PATCH 2/9] perf, tools, stat: Support up-scaling of events |
| Message-ID | <pWhWy-6y2-13@gated-at.bofh.it> |
| In reply to | #1205131 |
On Tue, Aug 11, 2015 at 03:25:32PM +0200, Jiri Olsa wrote:
> On Fri, Aug 07, 2015 at 06:06:18PM -0700, Andi Kleen wrote:
> > From: Andi Kleen <ak@linux.intel.com>
> >
> > TopDown needs to multiply events by constants (for example
> > the CPU Pipeline Width) to get the correct results.
> > The kernel needs to export this factor.
> >
> > Today *.scale is only used to scale down metrics (divide), for example
> > to scale bytes to MB.
> >
> > Repurpose negative scale to mean scaling up, that is multiplying.
> > Implement the code for this in perf stat.
> >
> > Signed-off-by: Andi Kleen <ak@linux.intel.com>
> > ---
> > tools/perf/builtin-stat.c | 27 +++++++++++++++++++--------
> > 1 file changed, 19 insertions(+), 8 deletions(-)
> >
> > diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
> > index ea5298a..2590c75 100644
> > --- a/tools/perf/builtin-stat.c
> > +++ b/tools/perf/builtin-stat.c
> > @@ -179,6 +179,17 @@ static inline int nsec_counter(struct perf_evsel *evsel)
> > return 0;
> > }
> >
> > +static double scale_val(struct perf_evsel *counter, u64 val)
> > +{
> > + double uval = val;
> > +
> > + if (counter->scale < 0)
> > + uval = val * (-counter->scale);
> > + else if (counter->scale)
> > + uval = val / counter->scale;
>
> hum, do you change the scale logic? the current scale > 0 works like:
>
> uval = val * counter->scale;
Yes I define negative scales to mean "multiply by" See the description of the kernel
patch for more details.
-Andi
--
ak@linux.intel.com -- Speaking for myself only
--
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 | Jiri Olsa <jolsa@redhat.com> |
|---|---|
| Date | 2015-08-11 16:00 +0200 |
| Subject | Re: [PATCH 2/9] perf, tools, stat: Support up-scaling of events |
| Message-ID | <pWifT-6UA-7@gated-at.bofh.it> |
| In reply to | #1205139 |
On Tue, Aug 11, 2015 at 06:38:05AM -0700, Andi Kleen wrote:
> On Tue, Aug 11, 2015 at 03:25:32PM +0200, Jiri Olsa wrote:
> > On Fri, Aug 07, 2015 at 06:06:18PM -0700, Andi Kleen wrote:
> > > From: Andi Kleen <ak@linux.intel.com>
> > >
> > > TopDown needs to multiply events by constants (for example
> > > the CPU Pipeline Width) to get the correct results.
> > > The kernel needs to export this factor.
> > >
> > > Today *.scale is only used to scale down metrics (divide), for example
> > > to scale bytes to MB.
> > >
> > > Repurpose negative scale to mean scaling up, that is multiplying.
> > > Implement the code for this in perf stat.
> > >
> > > Signed-off-by: Andi Kleen <ak@linux.intel.com>
> > > ---
> > > tools/perf/builtin-stat.c | 27 +++++++++++++++++++--------
> > > 1 file changed, 19 insertions(+), 8 deletions(-)
> > >
> > > diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
> > > index ea5298a..2590c75 100644
> > > --- a/tools/perf/builtin-stat.c
> > > +++ b/tools/perf/builtin-stat.c
> > > @@ -179,6 +179,17 @@ static inline int nsec_counter(struct perf_evsel *evsel)
> > > return 0;
> > > }
> > >
> > > +static double scale_val(struct perf_evsel *counter, u64 val)
> > > +{
> > > + double uval = val;
> > > +
> > > + if (counter->scale < 0)
> > > + uval = val * (-counter->scale);
> > > + else if (counter->scale)
> > > + uval = val / counter->scale;
> >
> > hum, do you change the scale logic? the current scale > 0 works like:
> >
> > uval = val * counter->scale;
>
> Yes I define negative scales to mean "multiply by" See the description of the kernel
> patch for more details.
how about existing scale attributes, like in rapl code
jirka
--
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 | Andi Kleen <andi@firstfloor.org> |
|---|---|
| Date | 2015-08-11 19:10 +0200 |
| Subject | Re: [PATCH 2/9] perf, tools, stat: Support up-scaling of events |
| Message-ID | <pWldN-30G-45@gated-at.bofh.it> |
| In reply to | #1205157 |
> how about existing scale attributes, like in rapl code I'm using the existing scale attribute, but I need a multiplication, not a division. That is why negative scale was redefined to mean multiplication. -Andi -- ak@linux.intel.com -- Speaking for myself only. -- 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 | Jiri Olsa <jolsa@redhat.com> |
|---|---|
| Date | 2015-08-11 19:20 +0200 |
| Subject | Re: [PATCH 2/9] perf, tools, stat: Support up-scaling of events |
| Message-ID | <pWlns-3c7-9@gated-at.bofh.it> |
| In reply to | #1205287 |
On Tue, Aug 11, 2015 at 07:00:37PM +0200, Andi Kleen wrote:
> > how about existing scale attributes, like in rapl code
>
> I'm using the existing scale attribute, but I need a multiplication,
> not a division. That is why negative scale was redefined to mean
> multiplication.
your new perf tool code (perf/top-down-2 branch) over the rapl counter:
[root@krava perf]# ./perf stat -e 'power/energy-cores/' -I 1000 -a
# time counts unit events
1.000096151 21606019212309954560.00 Joules power/energy-cores/
2.000284710 3411476717733150720.00 Joules power/energy-cores/
3.000455216 12621337955705815040.00 Joules power/energy-cores/
4.000543075 6444651066767179776.00 Joules power/energy-cores/
^C 4.144246923 1705738358866575360.00 Joules power/energy-cores/
jirka
--
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 | Andi Kleen <andi@firstfloor.org> |
|---|---|
| Date | 2015-08-11 19:20 +0200 |
| Subject | Re: [PATCH 2/9] perf, tools, stat: Support up-scaling of events |
| Message-ID | <pWlns-3c7-17@gated-at.bofh.it> |
| In reply to | #1205298 |
On Tue, Aug 11, 2015 at 07:13:41PM +0200, Jiri Olsa wrote: > On Tue, Aug 11, 2015 at 07:00:37PM +0200, Andi Kleen wrote: > > > how about existing scale attributes, like in rapl code > > > > I'm using the existing scale attribute, but I need a multiplication, > > not a division. That is why negative scale was redefined to mean > > multiplication. > > your new perf tool code (perf/top-down-2 branch) over the rapl counter: Thanks I'll look at it. Perhaps can also use a fraction scale instead of the negative scale. -Andi -- 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 | Andi Kleen <andi@firstfloor.org> |
|---|---|
| Date | 2015-08-08 03:10 +0200 |
| Subject | [PATCH 5/9] x86, perf: Support sysfs files depending on SMT status |
| Message-ID | <pV0O7-fI-27@gated-at.bofh.it> |
| In reply to | #1203127 |
From: Andi Kleen <ak@linux.intel.com>
Add a way to show different sysfs events attributes depending on
HyperThreading is on or off. This is difficult to determine
early at boot, so we just do it dynamically when the sysfs
attribute is read.
Signed-off-by: Andi Kleen <ak@linux.intel.com>
---
arch/x86/kernel/cpu/perf_event.c | 34 ++++++++++++++++++++++++++++++++++
arch/x86/kernel/cpu/perf_event.h | 10 ++++++++++
include/linux/perf_event.h | 7 +++++++
3 files changed, 51 insertions(+)
diff --git a/arch/x86/kernel/cpu/perf_event.c b/arch/x86/kernel/cpu/perf_event.c
index 8bac4bb..a1313ed 100644
--- a/arch/x86/kernel/cpu/perf_event.c
+++ b/arch/x86/kernel/cpu/perf_event.c
@@ -1590,6 +1590,40 @@ ssize_t events_sysfs_show(struct device *dev, struct device_attribute *attr,
return x86_pmu.events_sysfs_show(page, config);
}
+ssize_t events_ht_sysfs_show(struct device *dev, struct device_attribute *attr,
+ char *page)
+{
+ struct perf_pmu_events_ht_attr *pmu_attr =
+ container_of(attr, struct perf_pmu_events_ht_attr, attr);
+ bool ht_on = false;
+ int cpu;
+
+ /*
+ * Report conditional events depending on Hyper-Threading.
+ *
+ * Check all online CPUs if any have a thread sibling,
+ * as perf may measure any of them.
+ *
+ * This is overly conservative as usually the HT special
+ * handling is not needed if the other CPU thread is idle.
+ *
+ * Note this does not (cannot) handle the case when thread
+ * siblings are invisible, for example with virtualization
+ * if they are owned by some other guest. The user tool
+ * has to re-read when a thread sibling gets onlined later.
+ */
+ for_each_online_cpu (cpu) {
+ ht_on = cpumask_weight(topology_sibling_cpumask(cpu)) > 1;
+ if (ht_on)
+ break;
+ }
+
+ return sprintf(page, "%s",
+ ht_on ?
+ pmu_attr->event_str_ht :
+ pmu_attr->event_str_noht);
+}
+
EVENT_ATTR(cpu-cycles, CPU_CYCLES );
EVENT_ATTR(instructions, INSTRUCTIONS );
EVENT_ATTR(cache-references, CACHE_REFERENCES );
diff --git a/arch/x86/kernel/cpu/perf_event.h b/arch/x86/kernel/cpu/perf_event.h
index 5edf6d8..3df86d9 100644
--- a/arch/x86/kernel/cpu/perf_event.h
+++ b/arch/x86/kernel/cpu/perf_event.h
@@ -664,6 +664,14 @@ static struct perf_pmu_events_attr event_attr_##v = { \
.event_str = str, \
};
+#define EVENT_ATTR_STR_HT(_name, v, noht, ht) \
+static struct perf_pmu_events_ht_attr event_attr_##v = { \
+ .attr = __ATTR(_name, 0444, events_ht_sysfs_show, NULL),\
+ .id = 0, \
+ .event_str_noht = noht, \
+ .event_str_ht = ht, \
+};
+
extern struct x86_pmu x86_pmu __read_mostly;
static inline bool x86_pmu_has_lbr_callstack(void)
@@ -923,6 +931,8 @@ int knc_pmu_init(void);
ssize_t events_sysfs_show(struct device *dev, struct device_attribute *attr,
char *page);
+ssize_t events_ht_sysfs_show(struct device *dev, struct device_attribute *attr,
+ char *page);
static inline int is_ht_workaround_enabled(void)
{
diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h
index 2027809..5e9ee24 100644
--- a/include/linux/perf_event.h
+++ b/include/linux/perf_event.h
@@ -1068,6 +1068,13 @@ struct perf_pmu_events_attr {
const char *event_str;
};
+struct perf_pmu_events_ht_attr {
+ struct device_attribute attr;
+ u64 id;
+ const char *event_str_ht;
+ const char *event_str_noht;
+};
+
ssize_t perf_event_sysfs_show(struct device *dev, struct device_attribute *attr,
char *page);
--
2.4.3
--
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 | Andi Kleen <andi@firstfloor.org> |
|---|---|
| Date | 2015-08-08 03:10 +0200 |
| Subject | [PATCH 6/9] x86, perf: Add Top Down events to Intel Core |
| Message-ID | <pV0O6-fI-15@gated-at.bofh.it> |
| In reply to | #1203127 |
From: Andi Kleen <ak@linux.intel.com>
Add declarations for the events needed for TopDown to the
Intel big core CPUs starting with Sandy Bridge. We need
to report different values if HyperThreading is on or off.
The only thing this patch does is to export some events
in sysfs.
TopDown level 1 uses a set of abstracted metrics which
are generic to out of order CPU cores (although some
CPUs may not implement all of them):
topdown-total-slots Available slots in the pipeline
topdown-slots-issued Slots issued into the pipeline
topdown-slots-retired Slots successfully retired
topdown-fetch-bubbles Pipeline gaps in the frontend
topdown-recovery-bubbles Pipeline gaps during recovery
from misspeculation
These metrics then allow to compute four useful metrics:
FrontendBound, BackendBound, Retiring, BadSpeculation.
The formulas to compute the metrics are generic, they
only change based on the availability on the abstracted
input values.
The kernel declares the events supported by the current
CPU and perf stat then computes the formulas based on the
available metrics.
Some events need a divisor. To handle this I redefined
".scale" slightly to let a negative value mean divide by.
For HyperThreading the any bit is needed to get accurate
values when both threads are executing. This implies that
the events can only be collected as root or with
perf_event_paranoid=-1 for now.
Hyper Threading also requires averaging events from both
threads together (the CPU cannot measure them independently).
In perf stat this is done by using per core mode, and then
forcing a divisor of two to get the average. The
new .agg-per-core attribute is added to the events, which
then forces perf stat to enable --per-core.
When hyperthreading is disabled the attribute has the value 0.
The basic scheme is based on the following paper:
Yasin,
A Top Down Method for Performance analysis and Counter architecture
ISPASS14
(pdf available via google)
with some extensions to handle HyperThreading.
Signed-off-by: Andi Kleen <ak@linux.intel.com>
---
arch/x86/kernel/cpu/perf_event_intel.c | 82 ++++++++++++++++++++++++++++++++++
1 file changed, 82 insertions(+)
diff --git a/arch/x86/kernel/cpu/perf_event_intel.c b/arch/x86/kernel/cpu/perf_event_intel.c
index a478e3c..65b58cb 100644
--- a/arch/x86/kernel/cpu/perf_event_intel.c
+++ b/arch/x86/kernel/cpu/perf_event_intel.c
@@ -217,9 +217,70 @@ struct attribute *nhm_events_attrs[] = {
NULL,
};
+/*
+ * TopDown events for Core.
+ *
+ * With Hyper Threading on, TopDown metrics are averaged between the
+ * threads of a core: (count_core0 + count_core1) / 2. The 2 is expressed
+ * as a scale parameter. We also tell perf to aggregate per core
+ * by setting the .agg-per-core attribute for the alias to 1.
+ *
+ * Some events need to be multiplied by the pipeline width (4), which
+ * is expressed as a negative scale. In HT we cancel the factor 4
+ * with the 2 dividend for the core average, so we use -2.
+ */
+
+EVENT_ATTR_STR_HT(topdown-total-slots, td_total_slots,
+ "event=0x3c,umask=0x0", /* cpu_clk_unhalted.thread */
+ "event=0x3c,umask=0x0,any=1"); /* cpu_clk_unhalted.thread_any */
+EVENT_ATTR_STR_HT(topdown-total-slots.scale, td_total_slots_scale,
+ "-4", "-2");
+EVENT_ATTR_STR_HT(topdown-total-slots.agg-per-core, td_total_slots_pc,
+ "0", "1");
+EVENT_ATTR_STR(topdown-slots-issued, td_slots_issued,
+ "event=0xe,umask=0x1"); /* uops_issued.any */
+EVENT_ATTR_STR_HT(topdown-slots-issued.agg-per-core, td_slots_issued_pc,
+ "0", "1");
+EVENT_ATTR_STR_HT(topdown-slots-issued.scale, td_slots_issued_scale,
+ "0", "2");
+EVENT_ATTR_STR(topdown-slots-retired, td_slots_retired,
+ "event=0xc2,umask=0x2"); /* uops_retired.retire_slots */
+EVENT_ATTR_STR_HT(topdown-slots-retired.agg-per-core, td_slots_retired_pc,
+ "0", "1");
+EVENT_ATTR_STR_HT(topdown-slots-retired.scale, td_slots_retired_scale,
+ "0", "2");
+EVENT_ATTR_STR(topdown-fetch-bubbles, td_fetch_bubbles,
+ "event=0x9c,umask=0x1"); /* idq_uops_not_delivered_core */
+EVENT_ATTR_STR_HT(topdown-fetch-bubbles.agg-per-core, td_fetch_bubbles_pc,
+ "0", "1");
+EVENT_ATTR_STR_HT(topdown-fetch-bubbles.scale, td_fetch_bubbles_scale,
+ "0", "2");
+EVENT_ATTR_STR_HT(topdown-recovery-bubbles, td_recovery_bubbles,
+ "event=0xd,umask=0x3,cmask=1", /* int_misc.recovery_cycles */
+ "event=0xd,umask=0x3,cmask=1,any=1"); /* int_misc.recovery_cycles_any */
+EVENT_ATTR_STR_HT(topdown-recovery-bubbles.scale, td_recovery_bubbles_scale,
+ "-4", "-2");
+EVENT_ATTR_STR_HT(topdown-recovery-bubbles.agg-per-core, td_recovery_bubbles_pc,
+ "0", "1");
+
struct attribute *snb_events_attrs[] = {
EVENT_PTR(mem_ld_snb),
EVENT_PTR(mem_st_snb),
+ EVENT_PTR(td_slots_issued),
+ EVENT_PTR(td_slots_issued_scale),
+ EVENT_PTR(td_slots_issued_pc),
+ EVENT_PTR(td_slots_retired),
+ EVENT_PTR(td_slots_retired_scale),
+ EVENT_PTR(td_slots_retired_pc),
+ EVENT_PTR(td_fetch_bubbles),
+ EVENT_PTR(td_fetch_bubbles_scale),
+ EVENT_PTR(td_fetch_bubbles_pc),
+ EVENT_PTR(td_total_slots),
+ EVENT_PTR(td_total_slots_scale),
+ EVENT_PTR(td_total_slots_pc),
+ EVENT_PTR(td_recovery_bubbles),
+ EVENT_PTR(td_recovery_bubbles_scale),
+ EVENT_PTR(td_recovery_bubbles_pc),
NULL,
};
@@ -3177,6 +3238,21 @@ static struct attribute *hsw_events_attrs[] = {
EVENT_PTR(cycles_ct),
EVENT_PTR(mem_ld_hsw),
EVENT_PTR(mem_st_hsw),
+ EVENT_PTR(td_slots_issued),
+ EVENT_PTR(td_slots_issued_scale),
+ EVENT_PTR(td_slots_issued_pc),
+ EVENT_PTR(td_slots_retired),
+ EVENT_PTR(td_slots_retired_scale),
+ EVENT_PTR(td_slots_retired_pc),
+ EVENT_PTR(td_fetch_bubbles),
+ EVENT_PTR(td_fetch_bubbles_scale),
+ EVENT_PTR(td_fetch_bubbles_pc),
+ EVENT_PTR(td_total_slots),
+ EVENT_PTR(td_total_slots_scale),
+ EVENT_PTR(td_total_slots_pc),
+ EVENT_PTR(td_recovery_bubbles),
+ EVENT_PTR(td_recovery_bubbles_scale),
+ EVENT_PTR(td_recovery_bubbles_pc),
NULL
};
@@ -3494,6 +3570,12 @@ __init int intel_pmu_init(void)
memcpy(hw_cache_extra_regs, skl_hw_cache_extra_regs, sizeof(hw_cache_extra_regs));
intel_pmu_lbr_init_skl();
+ /* INT_MISC.RECOVERY_CYCLES has umask 1 in Skylake */
+ event_attr_td_recovery_bubbles.event_str_noht =
+ "event=0xd,umask=0x1,cmask=1";
+ event_attr_td_recovery_bubbles.event_str_ht =
+ "event=0xd,umask=0x1,cmask=1,any=1";
+
x86_pmu.event_constraints = intel_skl_event_constraints;
x86_pmu.pebs_constraints = intel_skl_pebs_event_constraints;
x86_pmu.extra_regs = intel_skl_extra_regs;
--
2.4.3
--
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 | Andi Kleen <andi@firstfloor.org> |
|---|---|
| Date | 2015-08-08 03:10 +0200 |
| Subject | [PATCH 8/9] perf, tools, stat: Add extra output of counter values with -v |
| Message-ID | <pV0O6-fI-17@gated-at.bofh.it> |
| In reply to | #1203127 |
From: Andi Kleen <ak@linux.intel.com>
Add debug output of raw counter values per CPU when
perf stat -v is specified, together with their cpu numbers.
This is very useful to debug problems with per core counters,
where we can normally only see aggregated values.
Signed-off-by: Andi Kleen <ak@linux.intel.com>
---
tools/perf/builtin-stat.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
index a83f26f..eec6c16 100644
--- a/tools/perf/builtin-stat.c
+++ b/tools/perf/builtin-stat.c
@@ -223,6 +223,13 @@ static int read_counter(struct perf_evsel *counter)
count = perf_counts(counter->counts, cpu, thread);
if (perf_evsel__read(counter, cpu, thread, count))
return -1;
+ if (verbose) {
+ fprintf(stat_config.output,
+ "%s: %d: %" PRIu64 " %" PRIu64 " %" PRIu64 "\n",
+ perf_evsel__name(counter),
+ cpu,
+ count->val, count->ena, count->run);
+ }
}
}
--
2.4.3
--
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