Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1395460 > unrolled thread
| Started by | Andi Kleen <andi@firstfloor.org> |
|---|---|
| First post | 2016-05-06 01:10 +0200 |
| Last post | 2016-05-12 09:50 +0200 |
| Articles | 7 on this page of 27 — 7 participants |
Back to article view | Back to linux.kernel
Add top down metrics to perf stat Andi Kleen <andi@firstfloor.org> - 2016-05-06 01:10 +0200
[PATCH 05/10] x86, perf: Use new topology_max_smt_threads() in HT leak workaround Andi Kleen <andi@firstfloor.org> - 2016-05-06 01:10 +0200
[PATCH 10/10] perf, tools, stat: Add extra output of counter values with -vv Andi Kleen <andi@firstfloor.org> - 2016-05-06 01:10 +0200
Re: [PATCH 10/10] perf, tools, stat: Add extra output of counter values with -vv Jiri Olsa <jolsa@redhat.com> - 2016-05-12 10:10 +0200
Re: [PATCH 10/10] perf, tools, stat: Add extra output of counter values with -vv Andi Kleen <andi@firstfloor.org> - 2016-05-20 02:10 +0200
[PATCH 07/10] perf, tools, stat: Scale values by unit before metrics Andi Kleen <andi@firstfloor.org> - 2016-05-06 01:10 +0200
Re: [PATCH 07/10] perf, tools, stat: Scale values by unit before metrics Jiri Olsa <jolsa@redhat.com> - 2016-05-07 21:20 +0200
[tip:perf/core] perf stat: Scale values by unit before metrics tip-bot for Andi Kleen <tipbot@zytor.com> - 2016-05-10 22:40 +0200
[PATCH 09/10] perf, tools, stat: Add computation of TopDown formulas Andi Kleen <andi@firstfloor.org> - 2016-05-06 01:10 +0200
[PATCH 04/10] x86, perf: Add Top Down events to Intel Atom Andi Kleen <andi@firstfloor.org> - 2016-05-06 01:10 +0200
[PATCH 06/10] perf, tools, stat: Avoid fractional digits for integer scales Andi Kleen <andi@firstfloor.org> - 2016-05-06 01:10 +0200
Re: [PATCH 06/10] perf, tools, stat: Avoid fractional digits for integer scales Jiri Olsa <jolsa@redhat.com> - 2016-05-07 21:20 +0200
Re: [PATCH 06/10] perf, tools, stat: Avoid fractional digits for integer scales Andi Kleen <andi@firstfloor.org> - 2016-05-07 21:30 +0200
Re: [PATCH 06/10] perf, tools, stat: Avoid fractional digits for integer scales Jiri Olsa <jolsa@redhat.com> - 2016-05-11 15:10 +0200
Re: [PATCH 06/10] perf, tools, stat: Avoid fractional digits for integer scales Arnaldo Carvalho de Melo <acme@kernel.org> - 2016-05-11 18:50 +0200
[tip:perf/urgent] perf stat: Avoid fractional digits for integer scales tip-bot for Andi Kleen <tipbot@zytor.com> - 2016-05-20 08:50 +0200
[PATCH 02/10] x86, perf: Support sysfs files depending on SMT status Andi Kleen <andi@firstfloor.org> - 2016-05-06 01:10 +0200
Re: [PATCH 02/10] x86, perf: Support sysfs files depending on SMT status Peter Zijlstra <peterz@infradead.org> - 2016-05-09 11:50 +0200
Re: [PATCH 02/10] x86, perf: Support sysfs files depending on SMT status Andi Kleen <ak@linux.intel.com> - 2016-05-09 16:30 +0200
Re: [PATCH 02/10] x86, perf: Support sysfs files depending on SMT status Peter Zijlstra <peterz@infradead.org> - 2016-05-09 16:40 +0200
Re: [PATCH 02/10] x86, perf: Support sysfs files depending on SMT status Ingo Molnar <mingo@kernel.org> - 2016-05-12 10:10 +0200
[PATCH 03/10] x86, perf: Add Top Down events to Intel Core Andi Kleen <andi@firstfloor.org> - 2016-05-06 01:10 +0200
Re: [PATCH 03/10] x86, perf: Add Top Down events to Intel Core Peter Zijlstra <peterz@infradead.org> - 2016-05-11 15:30 +0200
Re: [PATCH 03/10] x86, perf: Add Top Down events to Intel Core Jiri Olsa <jolsa@redhat.com> - 2016-05-11 15:30 +0200
Re: [PATCH 03/10] x86, perf: Add Top Down events to Intel Core Ingo Molnar <mingo@kernel.org> - 2016-05-12 10:20 +0200
[PATCH 08/10] perf, tools, stat: Basic support for TopDown in perf stat Andi Kleen <andi@firstfloor.org> - 2016-05-06 01:10 +0200
Re: Add top down metrics to perf stat Jiri Olsa <jolsa@redhat.com> - 2016-05-12 09:50 +0200
Page 2 of 2 — ← Prev page 1 [2]
| From | Ingo Molnar <mingo@kernel.org> |
|---|---|
| Date | 2016-05-12 10:10 +0200 |
| Subject | Re: [PATCH 02/10] x86, perf: Support sysfs files depending on SMT status |
| Message-ID | <rxTQZ-1yW-15@gated-at.bofh.it> |
| In reply to | #1395470 |
* Andi Kleen <andi@firstfloor.org> wrote:
> +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);
> +
> + /*
> + * Report conditional events depending on Hyper-Threading.
> + *
> + * 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.
> + */
> +
> + return sprintf(page, "%s",
> + topology_max_smt_threads() > 1 ?
> + 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/events/perf_event.h b/arch/x86/events/perf_event.h
> index 8bd764df815d..ad2e870f77d9 100644
> --- a/arch/x86/events/perf_event.h
> +++ b/arch/x86/events/perf_event.h
> @@ -668,6 +668,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)
> @@ -938,6 +946,12 @@ int p6_pmu_init(void);
>
> 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)
> {
> return !!(x86_pmu.flags & PMU_FL_EXCL_ENABLED);
> diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h
> index 9e1c3ada91c4..b425f2d24b26 100644
> --- a/include/linux/perf_event.h
> +++ b/include/linux/perf_event.h
> @@ -1304,6 +1304,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);
>
NAK for the following stylistic reasons:
- structure definition does not follow existing style.
- silly line breaks inserted into random positions that make the code ugly.
Thanks,
Ingo
[toc] | [prev] | [next] | [standalone]
| From | Andi Kleen <andi@firstfloor.org> |
|---|---|
| Date | 2016-05-06 01:10 +0200 |
| Subject | [PATCH 03/10] x86, perf: Add Top Down events to Intel Core |
| Message-ID | <rvAz8-1bh-33@gated-at.bofh.it> |
| In reply to | #1395460 |
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
A slot is a single operation in the CPU pipe line.
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 their scaling factors (such as the pipeline width)
and perf stat then computes the formulas based on the
available metrics. This is similar how existing
perf metrics, such as TSC metrics or IPC, are implemented.
This abstracts all CPU pipe line specific knowledge in the
kernel driver, but still avoids the need for larger scale perf
interface changes.
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.
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)
v2: Rework scaling. Fix formulas for HyperThreading.
v3: Rename agg-per-core to aggr-per-core
Always set aggr-per-core to one to get same output for HT off.
v4: Separate between forced and advisory aggr-per-core
v5: Remove .aggr-per-core attributes
Signed-off-by: Andi Kleen <ak@linux.intel.com>
---
arch/x86/events/intel/core.c | 50 ++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 50 insertions(+)
diff --git a/arch/x86/events/intel/core.c b/arch/x86/events/intel/core.c
index cd319400dc10..8b146007c264 100644
--- a/arch/x86/events/intel/core.c
+++ b/arch/x86/events/intel/core.c
@@ -230,9 +230,46 @@ struct attribute *nhm_events_attrs[] = {
NULL,
};
+/*
+ * TopDown events for Core.
+ *
+ * The events are all in slots, which is a free slot in a 4 wide
+ * pipeline. Some events are already reported in slots, for cycle
+ * events we multiply by the pipeline width (4).
+ *
+ * With Hyper Threading on, TopDown metrics are either summed or averaged
+ * between the threads of a core: (count_t0 + count_t1).
+ *
+ * For the average case the metric is always scaled to pipeline width,
+ * so we use factor 2 ((count_t0 + count_t1) / 2 * 4)
+ */
+
+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(topdown-slots-issued, td_slots_issued,
+ "event=0xe,umask=0x1"); /* uops_issued.any */
+EVENT_ATTR_STR(topdown-slots-retired, td_slots_retired,
+ "event=0xc2,umask=0x2"); /* uops_retired.retire_slots */
+EVENT_ATTR_STR(topdown-fetch-bubbles, td_fetch_bubbles,
+ "event=0x9c,umask=0x1"); /* idq_uops_not_delivered_core */
+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");
+
struct attribute *snb_events_attrs[] = {
EVENT_PTR(mem_ld_snb),
EVENT_PTR(mem_st_snb),
+ EVENT_PTR(td_slots_issued),
+ EVENT_PTR(td_slots_retired),
+ EVENT_PTR(td_fetch_bubbles),
+ EVENT_PTR(td_total_slots),
+ EVENT_PTR(td_total_slots_scale),
+ EVENT_PTR(td_recovery_bubbles),
+ EVENT_PTR(td_recovery_bubbles_scale),
NULL,
};
@@ -3437,6 +3474,13 @@ 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_retired),
+ EVENT_PTR(td_fetch_bubbles),
+ EVENT_PTR(td_total_slots),
+ EVENT_PTR(td_total_slots_scale),
+ EVENT_PTR(td_recovery_bubbles),
+ EVENT_PTR(td_recovery_bubbles_scale),
NULL
};
@@ -3805,6 +3849,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.5.5
[toc] | [prev] | [next] | [standalone]
| From | Peter Zijlstra <peterz@infradead.org> |
|---|---|
| Date | 2016-05-11 15:30 +0200 |
| Subject | Re: [PATCH 03/10] x86, perf: Add Top Down events to Intel Core |
| Message-ID | <rxCn8-F9-1@gated-at.bofh.it> |
| In reply to | #1395472 |
On Wed, May 11, 2016 at 03:23:36PM +0200, Jiri Olsa wrote:
> On Thu, May 05, 2016 at 04:04:00PM -0700, Andi Kleen wrote:
>
> SNIP
>
> > +
> > +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(topdown-slots-issued, td_slots_issued,
> > + "event=0xe,umask=0x1"); /* uops_issued.any */
> > +EVENT_ATTR_STR(topdown-slots-retired, td_slots_retired,
> > + "event=0xc2,umask=0x2"); /* uops_retired.retire_slots */
> > +EVENT_ATTR_STR(topdown-fetch-bubbles, td_fetch_bubbles,
> > + "event=0x9c,umask=0x1"); /* idq_uops_not_delivered_core */
> > +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");
> > +
> > struct attribute *snb_events_attrs[] = {
> > EVENT_PTR(mem_ld_snb),
> > EVENT_PTR(mem_st_snb),
> > + EVENT_PTR(td_slots_issued),
> > + EVENT_PTR(td_slots_retired),
> > + EVENT_PTR(td_fetch_bubbles),
> > + EVENT_PTR(td_total_slots),
> > + EVENT_PTR(td_total_slots_scale),
> > + EVENT_PTR(td_recovery_bubbles),
> > + EVENT_PTR(td_recovery_bubbles_scale),
>
> Peter, Ingo,
> any thoughts about adding these events? The rest of the
> tooling code is based on them being accepted..
I queued up these patches; but left the tool parts.
[toc] | [prev] | [next] | [standalone]
| From | Jiri Olsa <jolsa@redhat.com> |
|---|---|
| Date | 2016-05-11 15:30 +0200 |
| Subject | Re: [PATCH 03/10] x86, perf: Add Top Down events to Intel Core |
| Message-ID | <rxCn8-F9-3@gated-at.bofh.it> |
| In reply to | #1395472 |
On Thu, May 05, 2016 at 04:04:00PM -0700, Andi Kleen wrote:
SNIP
> +
> +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(topdown-slots-issued, td_slots_issued,
> + "event=0xe,umask=0x1"); /* uops_issued.any */
> +EVENT_ATTR_STR(topdown-slots-retired, td_slots_retired,
> + "event=0xc2,umask=0x2"); /* uops_retired.retire_slots */
> +EVENT_ATTR_STR(topdown-fetch-bubbles, td_fetch_bubbles,
> + "event=0x9c,umask=0x1"); /* idq_uops_not_delivered_core */
> +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");
> +
> struct attribute *snb_events_attrs[] = {
> EVENT_PTR(mem_ld_snb),
> EVENT_PTR(mem_st_snb),
> + EVENT_PTR(td_slots_issued),
> + EVENT_PTR(td_slots_retired),
> + EVENT_PTR(td_fetch_bubbles),
> + EVENT_PTR(td_total_slots),
> + EVENT_PTR(td_total_slots_scale),
> + EVENT_PTR(td_recovery_bubbles),
> + EVENT_PTR(td_recovery_bubbles_scale),
Peter, Ingo,
any thoughts about adding these events? The rest of the
tooling code is based on them being accepted..
thanks,
jirka
[toc] | [prev] | [next] | [standalone]
| From | Ingo Molnar <mingo@kernel.org> |
|---|---|
| Date | 2016-05-12 10:20 +0200 |
| Subject | Re: [PATCH 03/10] x86, perf: Add Top Down events to Intel Core |
| Message-ID | <rxU0H-1DT-17@gated-at.bofh.it> |
| In reply to | #1395472 |
* Andi Kleen <andi@firstfloor.org> wrote: > Subject: Re: [PATCH 03/10] x86, perf: Add Top Down events to Intel Core > arch/x86/events/intel/core.c | 50 ++++++++++++++++++++++++++++++++++++++++++++ You consistently mis-spell patches to the x86 perf code and for large series this adds unnecessary maintainer work. Use 'perf/x86:' for patches that affect all PMU using x86 CPUs, and 'perf/x86/intel:' for patches that affect only Intel CPUs. Generally a 'git log arch/x86/events/<file>.c' will tell you what pattern to use. This applies to most of the other patches of yours in this series as well, please fix it - and use this consistently for future patches as well. Thanks, Ingo
[toc] | [prev] | [next] | [standalone]
| From | Andi Kleen <andi@firstfloor.org> |
|---|---|
| Date | 2016-05-06 01:10 +0200 |
| Subject | [PATCH 08/10] perf, tools, stat: Basic support for TopDown in perf stat |
| Message-ID | <rvAz8-1bh-31@gated-at.bofh.it> |
| In reply to | #1395460 |
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.
v2: Use standard sysctl read function.
v3: Move x86 specific code to arch/
v4: Enable --metric-only implicitly for topdown.
v5: Add --single-thread option to not force per core mode
v6: Fix output order of topdown metrics
v7: Allow combining with -d
v8: Remove --single-thread again
Signed-off-by: Andi Kleen <ak@linux.intel.com>
---
tools/perf/Documentation/perf-stat.txt | 16 +++++
tools/perf/arch/x86/util/Build | 1 +
tools/perf/arch/x86/util/group.c | 27 ++++++++
tools/perf/builtin-stat.c | 114 ++++++++++++++++++++++++++++++++-
tools/perf/util/group.h | 7 ++
tools/perf/util/parse-events.l | 1 +
6 files changed, 163 insertions(+), 3 deletions(-)
create mode 100644 tools/perf/arch/x86/util/group.c
create mode 100644 tools/perf/util/group.h
diff --git a/tools/perf/Documentation/perf-stat.txt b/tools/perf/Documentation/perf-stat.txt
index 04f23b404bbc..3aaa2916f604 100644
--- a/tools/perf/Documentation/perf-stat.txt
+++ b/tools/perf/Documentation/perf-stat.txt
@@ -204,6 +204,22 @@ Aggregate counts per physical processor for system-wide mode measurements.
--no-aggr::
Do not aggregate counts across all monitored CPUs.
+--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. Metrics are only printed when they cross a threshold.
+
+The top down metrics may be collected per core instead of per
+CPU thread. In this case per core mode is automatically enabled
+and -a (global monitoring) is needed, requiring root rights or
+perf.perf_event_paranoid=-1.
+
+This enables --metric-only, unless overriden with --no-metric-only.
+
+To interpret the results it is usually needed to know on which
+CPUs the workload runs on. If needed the CPUs can be forced using
+taskset.
EXAMPLES
--------
diff --git a/tools/perf/arch/x86/util/Build b/tools/perf/arch/x86/util/Build
index 465970370f3e..4cd8a16b1b7b 100644
--- a/tools/perf/arch/x86/util/Build
+++ b/tools/perf/arch/x86/util/Build
@@ -3,6 +3,7 @@ libperf-y += tsc.o
libperf-y += pmu.o
libperf-y += kvm-stat.o
libperf-y += perf_regs.o
+libperf-y += group.o
libperf-$(CONFIG_DWARF) += dwarf-regs.o
libperf-$(CONFIG_BPF_PROLOGUE) += dwarf-regs.o
diff --git a/tools/perf/arch/x86/util/group.c b/tools/perf/arch/x86/util/group.c
new file mode 100644
index 000000000000..f3039b5ce8b1
--- /dev/null
+++ b/tools/perf/arch/x86/util/group.c
@@ -0,0 +1,27 @@
+#include <stdio.h>
+#include "api/fs/fs.h"
+#include "util/group.h"
+
+/*
+ * Check whether we can use a group for top down.
+ * Without a group may get bad results due to multiplexing.
+ */
+bool check_group(bool *warn)
+{
+ int n;
+
+ if (sysctl__read_int("kernel/nmi_watchdog", &n) < 0)
+ return false;
+ if (n > 0) {
+ *warn = true;
+ return false;
+ }
+ return true;
+}
+
+void group_warn(void)
+{
+ fprintf(stderr,
+ "nmi_watchdog enabled with topdown. May give wrong results.\n"
+ "Disable with echo 0 > /proc/sys/kernel/nmi_watchdog\n");
+}
diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
index b407a11c6e22..707eef9314da 100644
--- a/tools/perf/builtin-stat.c
+++ b/tools/perf/builtin-stat.c
@@ -59,10 +59,13 @@
#include "util/thread.h"
#include "util/thread_map.h"
#include "util/counts.h"
+#include "util/group.h"
#include "util/session.h"
#include "util/tool.h"
+#include "util/group.h"
#include "asm/bug.h"
+#include <api/fs/fs.h>
#include <stdlib.h>
#include <sys/prctl.h>
#include <locale.h>
@@ -98,6 +101,15 @@ static const char * transaction_limited_attrs = {
"}"
};
+static const char * topdown_attrs[] = {
+ "topdown-total-slots",
+ "topdown-slots-retired",
+ "topdown-recovery-bubbles",
+ "topdown-fetch-bubbles",
+ "topdown-slots-issued",
+ NULL,
+};
+
static struct perf_evlist *evsel_list;
static struct target target = {
@@ -112,6 +124,7 @@ static volatile pid_t child_pid = -1;
static bool null_run = false;
static int detailed_run = 0;
static bool transaction_run;
+static bool topdown_run = false;
static bool big_num = true;
static int big_num_opt = -1;
static const char *csv_sep = NULL;
@@ -124,6 +137,7 @@ static unsigned int initial_delay = 0;
static unsigned int unit_width = 4; /* strlen("unit") */
static bool forever = false;
static bool metric_only = false;
+static bool force_metric_only = false;
static struct timespec ref_time;
static struct cpu_map *aggr_map;
static aggr_get_id_t aggr_get_id;
@@ -1507,6 +1521,14 @@ static int stat__set_big_num(const struct option *opt __maybe_unused,
return 0;
}
+static int enable_metric_only(const struct option *opt __maybe_unused,
+ const char *s __maybe_unused, int unset)
+{
+ force_metric_only = true;
+ metric_only = !unset;
+ return 0;
+}
+
static const struct option stat_options[] = {
OPT_BOOLEAN('T', "transaction", &transaction_run,
"hardware transaction statistics"),
@@ -1565,8 +1587,10 @@ static const struct option stat_options[] = {
"aggregate counts per thread", AGGR_THREAD),
OPT_UINTEGER('D', "delay", &initial_delay,
"ms to wait before starting measurement after program start"),
- OPT_BOOLEAN(0, "metric-only", &metric_only,
- "Only print computed metrics. No raw values"),
+ OPT_CALLBACK_NOOPT(0, "metric-only", &metric_only, NULL,
+ "Only print computed metrics. No raw values", enable_metric_only),
+ OPT_BOOLEAN(0, "topdown", &topdown_run,
+ "measure topdown level 1 statistics"),
OPT_END()
};
@@ -1759,12 +1783,61 @@ static int perf_stat_init_aggr_mode_file(struct perf_stat *st)
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;
+}
+
+__weak bool check_group(bool *warn)
+{
+ *warn = false;
+ return false;
+}
+
+__weak void group_warn(void)
+{
+}
+
/*
* 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_attrs0[] = {
{ .type = PERF_TYPE_SOFTWARE, .config = PERF_COUNT_SW_TASK_CLOCK },
@@ -1883,7 +1956,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);
@@ -1896,6 +1968,42 @@ static int add_default_attributes(void)
return 0;
}
+ if (topdown_run) {
+ char *str = NULL;
+ bool warn = false;
+
+ if (stat_config.aggr_mode != AGGR_GLOBAL &&
+ stat_config.aggr_mode != AGGR_CORE) {
+ pr_err("top down event configuration requires --per-core mode\n");
+ return -1;
+ }
+ stat_config.aggr_mode = AGGR_CORE;
+ if (nr_cgroups || !target__has_cpu(&target)) {
+ pr_err("top down event configuration requires system-wide mode (-a)\n");
+ return -1;
+ }
+
+ if (!force_metric_only)
+ metric_only = true;
+ filter_events(topdown_attrs, &str, check_group(&warn));
+ if (topdown_attrs[0] && str) {
+ if (warn)
+ group_warn();
+ 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);
+ }
+
if (!evsel_list->nr_entries) {
if (perf_evlist__add_default_attrs(evsel_list, default_attrs0) < 0)
return -1;
diff --git a/tools/perf/util/group.h b/tools/perf/util/group.h
new file mode 100644
index 000000000000..daad3ffdc68d
--- /dev/null
+++ b/tools/perf/util/group.h
@@ -0,0 +1,7 @@
+#ifndef GROUP_H
+#define GROUP_H 1
+
+bool check_group(bool *warn);
+void group_warn(void);
+
+#endif
diff --git a/tools/perf/util/parse-events.l b/tools/perf/util/parse-events.l
index 1477fbc78993..744ebe3fa30f 100644
--- a/tools/perf/util/parse-events.l
+++ b/tools/perf/util/parse-events.l
@@ -259,6 +259,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.5.5
[toc] | [prev] | [next] | [standalone]
| From | Jiri Olsa <jolsa@redhat.com> |
|---|---|
| Date | 2016-05-12 09:50 +0200 |
| Message-ID | <rxTxE-17U-9@gated-at.bofh.it> |
| In reply to | #1395460 |
On Thu, May 05, 2016 at 04:03:57PM -0700, Andi Kleen wrote:
SNIP
> 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 -I 1000 cmd
> 1.000735655 frontend bound retiring bad speculation backend bound
> 1.000735655 S0-C0 2 47.84% 11.69% 8.37% 32.10%
> 1.000735655 S0-C1 2 45.53% 11.39% 8.52% 34.56%
> 2.003978563 S0-C0 2 49.47% 12.22% 8.65% 29.66%
> 2.003978563 S0-C1 2 47.21% 12.98% 8.77% 31.04%
> 3.004901432 S0-C0 2 49.35% 12.26% 8.68% 29.70%
> 3.004901432 S0-C1 2 47.23% 12.67% 8.76% 31.35%
> 4.005766611 S0-C0 2 48.44% 12.14% 8.59% 30.82%
> 4.005766611 S0-C1 2 46.07% 12.41% 8.67% 32.85%
> 5.006580592 S0-C0 2 47.91% 12.08% 8.57% 31.44%
> 5.006580592 S0-C1 2 45.57% 12.27% 8.63% 33.53%
> 6.007545125 S0-C0 2 47.45% 12.02% 8.57% 31.96%
> 6.007545125 S0-C1 2 45.13% 12.17% 8.57% 34.14%
> 7.008539347 S0-C0 2 47.07% 12.03% 8.61% 32.29%
getting -0% for bad speculation.. im on your perf/top-down-20
thanks,
jirka
[root@ibm-x3650m4-01 perf]# ./perf stat --topdown -a -I 1000
nmi_watchdog enabled with topdown. May give wrong results.
Disable with echo 0 > /proc/sys/kernel/nmi_watchdog
1.002322346 retiring bad speculation frontend bound backend bound
1.002322346 S0-C0 2 38.3% 0.0% 57.9% 3.8%
1.002322346 S0-C1 2 38.3% 0.0% 59.1% 2.6%
1.002322346 S0-C2 2 38.3% 0.0% 59.0% 2.6%
1.002322346 S0-C3 2 38.3% 0.0% 58.7% 3.0%
1.002322346 S0-C4 2 38.3% -0.0% 58.6% 3.1%
1.002322346 S0-C5 2 38.4% -0.0% 58.3% 3.3%
1.002322346 S1-C0 2 38.3% -0.0% 58.7% 3.0%
1.002322346 S1-C1 2 38.3% 0.0% 59.7% 2.0%
1.002322346 S1-C2 2 38.3% -0.0% 59.3% 2.5%
1.002322346 S1-C3 2 38.3% -0.0% 59.1% 2.5%
1.002322346 S1-C4 2 38.3% 0.0% 59.1% 2.6%
1.002322346 S1-C5 2 38.3% -0.0% 59.1% 2.7%
2.005429451 S0-C0 2 38.3% 0.0% 57.9% 3.8%
...
[toc] | [prev] | [standalone]
Page 2 of 2 — ← Prev page 1 [2]
Back to top | Article view | linux.kernel
csiph-web