linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* perf PMU support for Haswell
@ 2012-09-28  4:31 Andi Kleen
  2012-09-28  4:31 ` [PATCH 01/31] perf, x86: Add PEBSv2 record support Andi Kleen
                   ` (30 more replies)
  0 siblings, 31 replies; 58+ messages in thread
From: Andi Kleen @ 2012-09-28  4:31 UTC (permalink / raw)
  To: linux-kernel; +Cc: x86, a.p.zijlstra, eranian, acme

This adds perf PMU support for the upcoming Haswell core. The patchkit 
is fairly large, mainly due to various enhancement for TSX. TSX tuning
relies heavily on the PMU, so I tried hard to make all facilities 
easily available. In addition it also has some other enhancements.

This includes changes to the core perf code, to the x86 specific part,
to the perf user land tools and to KVM

High level overview:

- Basic Haswell PMU support
- Easy high level TSX measurement in perf stat -T
- Generic transactional memory events, plus Haswell implementations.
- Generic weightend profiling for memory latency and transaction abort costs.
- Support for address profiling
- Support for filtering events inside/outside transactions
- KVM support to do this from guests
- Support for filtering/sorting/bucketing transaction abort types based on 
PEBS information
- LBR support for transactions

For more details on the Haswell PMU please see the SDM. For more details on TSX
please see http://halobates.de/adding-lock-elision-to-linux.pdf

Review appreciated.

-Andi


^ permalink raw reply	[flat|nested] 58+ messages in thread

* [PATCH 01/31] perf, x86: Add PEBSv2 record support
  2012-09-28  4:31 perf PMU support for Haswell Andi Kleen
@ 2012-09-28  4:31 ` Andi Kleen
  2012-09-28  8:43   ` Peter Zijlstra
  2012-09-28  4:31 ` [PATCH 02/31] perf, x86: Basic Haswell PMU support Andi Kleen
                   ` (29 subsequent siblings)
  30 siblings, 1 reply; 58+ messages in thread
From: Andi Kleen @ 2012-09-28  4:31 UTC (permalink / raw)
  To: linux-kernel; +Cc: x86, a.p.zijlstra, eranian, acme, Andi Kleen

From: Andi Kleen <ak@linux.intel.com>

Add support for the v2 PEBS format. It has a superset of the v1 PEBS
fields, but has a longer record so we need to adjust the code paths.

The main advantage is the new "EventingRip" support which directly
gives the instruction, not off-by-one instruction. So with precise == 2
we use that directly and don't try to use LBRs and walking basic blocks.
This lowers the overhead significantly.

Some other features are added in later patches.

Signed-off-by: Andi Kleen <ak@linux.intel.com>
---
 arch/x86/kernel/cpu/perf_event.c          |    2 +-
 arch/x86/kernel/cpu/perf_event_intel_ds.c |  101 ++++++++++++++++++++++-------
 2 files changed, 79 insertions(+), 24 deletions(-)

diff --git a/arch/x86/kernel/cpu/perf_event.c b/arch/x86/kernel/cpu/perf_event.c
index 915b876..87c2ab0 100644
--- a/arch/x86/kernel/cpu/perf_event.c
+++ b/arch/x86/kernel/cpu/perf_event.c
@@ -395,7 +395,7 @@ int x86_pmu_hw_config(struct perf_event *event)
 		 * check that PEBS LBR correction does not conflict with
 		 * whatever the user is asking with attr->branch_sample_type
 		 */
-		if (event->attr.precise_ip > 1) {
+		if (event->attr.precise_ip > 1 && x86_pmu.intel_cap.pebs_format < 2) {
 			u64 *br_type = &event->attr.branch_sample_type;
 
 			if (has_branch_stack(event)) {
diff --git a/arch/x86/kernel/cpu/perf_event_intel_ds.c b/arch/x86/kernel/cpu/perf_event_intel_ds.c
index e38d97b..c8ab670 100644
--- a/arch/x86/kernel/cpu/perf_event_intel_ds.c
+++ b/arch/x86/kernel/cpu/perf_event_intel_ds.c
@@ -41,6 +41,12 @@ struct pebs_record_nhm {
 	u64 status, dla, dse, lat;
 };
 
+struct pebs_record_v2 {
+	struct pebs_record_nhm nhm;
+	u64 eventingrip;
+	u64 tsx_tuning;
+};
+
 void init_debug_store_on_cpu(int cpu)
 {
 	struct debug_store *ds = per_cpu(cpu_hw_events, cpu).ds;
@@ -545,8 +551,7 @@ static void __intel_pmu_pebs_event(struct perf_event *event,
 {
 	/*
 	 * We cast to pebs_record_core since that is a subset of
-	 * both formats and we don't use the other fields in this
-	 * routine.
+	 * both formats.
 	 */
 	struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
 	struct pebs_record_core *pebs = __pebs;
@@ -574,7 +579,10 @@ static void __intel_pmu_pebs_event(struct perf_event *event,
 	regs.bp = pebs->bp;
 	regs.sp = pebs->sp;
 
-	if (event->attr.precise_ip > 1 && intel_pmu_pebs_fixup_ip(&regs))
+	if (event->attr.precise_ip > 1 && x86_pmu.intel_cap.pebs_format >= 2) {
+		regs.ip = ((struct pebs_record_v2 *)pebs)->eventingrip;
+		regs.flags |= PERF_EFLAGS_EXACT;
+	} else if (event->attr.precise_ip > 1 && intel_pmu_pebs_fixup_ip(&regs))
 		regs.flags |= PERF_EFLAGS_EXACT;
 	else
 		regs.flags &= ~PERF_EFLAGS_EXACT;
@@ -627,35 +635,21 @@ static void intel_pmu_drain_pebs_core(struct pt_regs *iregs)
 	__intel_pmu_pebs_event(event, iregs, at);
 }
 
-static void intel_pmu_drain_pebs_nhm(struct pt_regs *iregs)
+static void intel_pmu_drain_pebs_common(struct pt_regs *iregs, void *at, 
+					void *top)
 {
 	struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
 	struct debug_store *ds = cpuc->ds;
-	struct pebs_record_nhm *at, *top;
 	struct perf_event *event = NULL;
 	u64 status = 0;
-	int bit, n;
-
-	if (!x86_pmu.pebs_active)
-		return;
-
-	at  = (struct pebs_record_nhm *)(unsigned long)ds->pebs_buffer_base;
-	top = (struct pebs_record_nhm *)(unsigned long)ds->pebs_index;
+	int bit;
 
 	ds->pebs_index = ds->pebs_buffer_base;
 
-	n = top - at;
-	if (n <= 0)
-		return;
+	for ( ; at < top; at += x86_pmu.pebs_record_size) {
+		struct pebs_record_nhm *p = at;
 
-	/*
-	 * Should not happen, we program the threshold at 1 and do not
-	 * set a reset value.
-	 */
-	WARN_ONCE(n > x86_pmu.max_pebs_events, "Unexpected number of pebs records %d\n", n);
-
-	for ( ; at < top; at++) {
-		for_each_set_bit(bit, (unsigned long *)&at->status, x86_pmu.max_pebs_events) {
+		for_each_set_bit(bit, (unsigned long *)&p->status, x86_pmu.max_pebs_events) {
 			event = cpuc->events[bit];
 			if (!test_bit(bit, cpuc->active_mask))
 				continue;
@@ -678,6 +672,61 @@ static void intel_pmu_drain_pebs_nhm(struct pt_regs *iregs)
 	}
 }
 
+static void intel_pmu_drain_pebs_nhm(struct pt_regs *iregs)
+{
+	struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
+	struct debug_store *ds = cpuc->ds;
+	struct pebs_record_nhm *at, *top;
+	int n;
+
+	if (!x86_pmu.pebs_active)
+		return;
+
+	at  = (struct pebs_record_nhm *)(unsigned long)ds->pebs_buffer_base;
+	top = (struct pebs_record_nhm *)(unsigned long)ds->pebs_index;
+
+	ds->pebs_index = ds->pebs_buffer_base;
+
+	n = top - at;
+	if (n <= 0)
+		return;
+
+	/*
+	 * Should not happen, we program the threshold at 1 and do not
+	 * set a reset value.
+	 */
+	WARN_ONCE(n > x86_pmu.max_pebs_events, 
+		  "Unexpected number of pebs records %d\n", n);
+
+	return intel_pmu_drain_pebs_common(iregs, at, top);
+}
+
+static void intel_pmu_drain_pebs_v2(struct pt_regs *iregs)
+{
+	struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
+	struct debug_store *ds = cpuc->ds;
+	struct pebs_record_v2 *at, *top;
+	int n;
+
+	if (!x86_pmu.pebs_active)
+		return;
+
+	at  = (struct pebs_record_v2 *)(unsigned long)ds->pebs_buffer_base;
+	top = (struct pebs_record_v2 *)(unsigned long)ds->pebs_index;
+
+	n = top - at;
+	if (n <= 0)
+		return;
+	/*
+	 * Should not happen, we program the threshold at 1 and do not
+	 * set a reset value.
+	 */
+	WARN_ONCE(n > x86_pmu.max_pebs_events,
+		  "Unexpected number of pebs records %d\n", n);
+
+	return intel_pmu_drain_pebs_common(iregs, at, top);
+}
+
 /*
  * BTS, PEBS probe and setup
  */
@@ -709,6 +758,12 @@ void intel_ds_init(void)
 			x86_pmu.drain_pebs = intel_pmu_drain_pebs_nhm;
 			break;
 
+		case 2:
+			printk(KERN_CONT "PEBS fmt2%c, ", pebs_type);
+			x86_pmu.pebs_record_size = sizeof(struct pebs_record_v2);
+			x86_pmu.drain_pebs = intel_pmu_drain_pebs_v2;
+			break;
+
 		default:
 			printk(KERN_CONT "no PEBS fmt%d%c, ", format, pebs_type);
 			x86_pmu.pebs = 0;
-- 
1.7.7.6


^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [PATCH 02/31] perf, x86: Basic Haswell PMU support
  2012-09-28  4:31 perf PMU support for Haswell Andi Kleen
  2012-09-28  4:31 ` [PATCH 01/31] perf, x86: Add PEBSv2 record support Andi Kleen
@ 2012-09-28  4:31 ` Andi Kleen
  2012-09-28  9:05   ` Peter Zijlstra
  2012-09-28  4:31 ` [PATCH 03/31] perf, x86: Basic Haswell PEBS support Andi Kleen
                   ` (28 subsequent siblings)
  30 siblings, 1 reply; 58+ messages in thread
From: Andi Kleen @ 2012-09-28  4:31 UTC (permalink / raw)
  To: linux-kernel; +Cc: x86, a.p.zijlstra, eranian, acme, Andi Kleen

From: Andi Kleen <ak@linux.intel.com>

Add basic Haswell PMU support.

Similar to SandyBridge, but has a few new events. Further
differences are handled in followon patches.

There are some new counter flags that need to be prevented
from being set on fixed counters.

Contains fixes from Stephane Eranian

Signed-off-by: Andi Kleen <ak@linux.intel.com>
---
 arch/x86/include/asm/perf_event.h      |    3 +++
 arch/x86/kernel/cpu/perf_event.h       |    7 +++++++
 arch/x86/kernel/cpu/perf_event_intel.c |   29 +++++++++++++++++++++++++++++
 3 files changed, 39 insertions(+), 0 deletions(-)

diff --git a/arch/x86/include/asm/perf_event.h b/arch/x86/include/asm/perf_event.h
index cb4e43b..c1fe6e9 100644
--- a/arch/x86/include/asm/perf_event.h
+++ b/arch/x86/include/asm/perf_event.h
@@ -29,6 +29,9 @@
 #define ARCH_PERFMON_EVENTSEL_INV			(1ULL << 23)
 #define ARCH_PERFMON_EVENTSEL_CMASK			0xFF000000ULL
 
+#define HSW_INTX					(1ULL << 32)
+#define HSW_INTX_CHECKPOINTED				(1ULL << 33)
+
 #define AMD_PERFMON_EVENTSEL_GUESTONLY			(1ULL << 40)
 #define AMD_PERFMON_EVENTSEL_HOSTONLY			(1ULL << 41)
 
diff --git a/arch/x86/kernel/cpu/perf_event.h b/arch/x86/kernel/cpu/perf_event.h
index 6605a81..a135a5a 100644
--- a/arch/x86/kernel/cpu/perf_event.h
+++ b/arch/x86/kernel/cpu/perf_event.h
@@ -226,6 +226,13 @@ struct cpu_hw_events {
 	EVENT_CONSTRAINT(c, (1ULL << (32+n)), X86_RAW_EVENT_MASK)
 
 /*
+ * Also filter out TSX bits.
+ */
+#define TSX_FIXED_EVENT_CONSTRAINT(c, n)	\
+	EVENT_CONSTRAINT(c, (1ULL << (32+n)),	\
+			 X86_RAW_EVENT_MASK|HSW_INTX|HSW_INTX_CHECKPOINTED)
+
+/*
  * Constraint on the Event code + UMask
  */
 #define INTEL_UEVENT_CONSTRAINT(c, n)	\
diff --git a/arch/x86/kernel/cpu/perf_event_intel.c b/arch/x86/kernel/cpu/perf_event_intel.c
index 0d3d63a..82bae24 100644
--- a/arch/x86/kernel/cpu/perf_event_intel.c
+++ b/arch/x86/kernel/cpu/perf_event_intel.c
@@ -133,6 +133,17 @@ static struct extra_reg intel_snb_extra_regs[] __read_mostly = {
 	EVENT_EXTRA_END
 };
 
+static struct event_constraint intel_hsw_event_constraints[] =
+{
+	TSX_FIXED_EVENT_CONSTRAINT(0x00c0, 0), /* INST_RETIRED.ANY */
+	TSX_FIXED_EVENT_CONSTRAINT(0x003c, 1), /* CPU_CLK_UNHALTED.CORE */
+	TSX_FIXED_EVENT_CONSTRAINT(0x0300, 2), /* CPU_CLK_UNHALTED.REF */
+	INTEL_EVENT_CONSTRAINT(0x48, 0x4), /* L1D_PEND_MISS.PENDING */
+	INTEL_UEVENT_CONSTRAINT(0x01c0, 0x2), /* INST_RETIRED.PREC_DIST */
+	INTEL_EVENT_CONSTRAINT(0xcd, 0x8), /* MEM_TRANS_RETIRED.LOAD_LATENCY */
+	EVENT_CONSTRAINT_END
+};
+
 static u64 intel_pmu_event_map(int hw_event)
 {
 	return intel_perfmon_event_map[hw_event];
@@ -2074,6 +2085,24 @@ __init int intel_pmu_init(void)
 		pr_cont("SandyBridge events, ");
 		break;
 
+	case 60: /* Haswell Client */
+	case 70:
+	case 71:
+		memcpy(hw_cache_event_ids, snb_hw_cache_event_ids,
+		       sizeof(hw_cache_event_ids));
+
+		intel_pmu_lbr_init_nhm();
+
+		x86_pmu.event_constraints = intel_hsw_event_constraints;
+
+		x86_pmu.extra_regs = intel_snb_extra_regs;
+		/* all extra regs are per-cpu when HT is on */
+		x86_pmu.er_flags |= ERF_HAS_RSP_1;
+		x86_pmu.er_flags |= ERF_NO_HT_SHARING;
+
+		pr_cont("Haswell events, ");
+		break;
+
 	default:
 		switch (x86_pmu.version) {
 		case 1:
-- 
1.7.7.6


^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [PATCH 03/31] perf, x86: Basic Haswell PEBS support
  2012-09-28  4:31 perf PMU support for Haswell Andi Kleen
  2012-09-28  4:31 ` [PATCH 01/31] perf, x86: Add PEBSv2 record support Andi Kleen
  2012-09-28  4:31 ` [PATCH 02/31] perf, x86: Basic Haswell PMU support Andi Kleen
@ 2012-09-28  4:31 ` Andi Kleen
  2012-09-28  8:50   ` Peter Zijlstra
  2012-09-28  4:31 ` [PATCH 04/31] perf, core: Add generic intx/intx_checkpointed counter modifiers Andi Kleen
                   ` (27 subsequent siblings)
  30 siblings, 1 reply; 58+ messages in thread
From: Andi Kleen @ 2012-09-28  4:31 UTC (permalink / raw)
  To: linux-kernel; +Cc: x86, a.p.zijlstra, eranian, acme, Andi Kleen

From: Andi Kleen <ak@linux.intel.com>

Add basic PEBS support for Haswell.
The constraints are similar to SandyBridge with a few new events.

Signed-off-by: Andi Kleen <ak@linux.intel.com>
---
 arch/x86/kernel/cpu/perf_event.h          |    2 ++
 arch/x86/kernel/cpu/perf_event_intel.c    |    2 +-
 arch/x86/kernel/cpu/perf_event_intel_ds.c |   29 +++++++++++++++++++++++++++++
 3 files changed, 32 insertions(+), 1 deletions(-)

diff --git a/arch/x86/kernel/cpu/perf_event.h b/arch/x86/kernel/cpu/perf_event.h
index a135a5a..8200c69 100644
--- a/arch/x86/kernel/cpu/perf_event.h
+++ b/arch/x86/kernel/cpu/perf_event.h
@@ -593,6 +593,8 @@ extern struct event_constraint intel_westmere_pebs_event_constraints[];
 
 extern struct event_constraint intel_snb_pebs_event_constraints[];
 
+extern struct event_constraint intel_hsw_pebs_event_constraints[];
+
 struct event_constraint *intel_pebs_constraints(struct perf_event *event);
 
 void intel_pmu_pebs_enable(struct perf_event *event);
diff --git a/arch/x86/kernel/cpu/perf_event_intel.c b/arch/x86/kernel/cpu/perf_event_intel.c
index 82bae24..695abd1 100644
--- a/arch/x86/kernel/cpu/perf_event_intel.c
+++ b/arch/x86/kernel/cpu/perf_event_intel.c
@@ -2094,7 +2094,7 @@ __init int intel_pmu_init(void)
 		intel_pmu_lbr_init_nhm();
 
 		x86_pmu.event_constraints = intel_hsw_event_constraints;
-
+		x86_pmu.pebs_constraints = intel_hsw_pebs_event_constraints;
 		x86_pmu.extra_regs = intel_snb_extra_regs;
 		/* all extra regs are per-cpu when HT is on */
 		x86_pmu.er_flags |= ERF_HAS_RSP_1;
diff --git a/arch/x86/kernel/cpu/perf_event_intel_ds.c b/arch/x86/kernel/cpu/perf_event_intel_ds.c
index c8ab670..994156f 100644
--- a/arch/x86/kernel/cpu/perf_event_intel_ds.c
+++ b/arch/x86/kernel/cpu/perf_event_intel_ds.c
@@ -413,6 +413,35 @@ struct event_constraint intel_snb_pebs_event_constraints[] = {
 	EVENT_CONSTRAINT_END
 };
 
+struct event_constraint intel_hsw_pebs_event_constraints[] = {
+	INTEL_UEVENT_CONSTRAINT(0x01c0, 0x2), /* INST_RETIRED.PRECDIST */
+	INTEL_UEVENT_CONSTRAINT(0x01c2, 0xf), /* UOPS_RETIRED.ALL */
+	INTEL_UEVENT_CONSTRAINT(0x02c2, 0xf), /* UOPS_RETIRED.RETIRE_SLOTS */
+	INTEL_EVENT_CONSTRAINT(0xc4, 0xf),    /* BR_INST_RETIRED.* */
+	INTEL_EVENT_CONSTRAINT(0x01c5, 0xf),  /* BR_MISP_RETIRED.CONDITIONAL */
+	INTEL_EVENT_CONSTRAINT(0x04c5, 0xf),  /* BR_MISP_RETIRED.ALL_BRANCHES */
+	INTEL_EVENT_CONSTRAINT(0x20c5, 0xf),  /* BR_MISP_RETIRED.NEAR_TAKEN */
+	INTEL_EVENT_CONSTRAINT(0xcd, 0x8),    /* MEM_TRANS_RETIRED.* */
+	INTEL_UEVENT_CONSTRAINT(0x11d0, 0xf), /* MEM_UOPS_RETIRED.STLB_MISS_LOADS */
+	INTEL_UEVENT_CONSTRAINT(0x12d0, 0xf), /* MEM_UOPS_RETIRED.STLB_MISS_STORES */
+	INTEL_UEVENT_CONSTRAINT(0x21d0, 0xf), /* MEM_UOPS_RETIRED.LOCK_LOADS */
+	INTEL_UEVENT_CONSTRAINT(0x41d0, 0xf), /* MEM_UOPS_RETIRED.SPLIT_LOADS */
+	INTEL_UEVENT_CONSTRAINT(0x42d0, 0xf), /* MEM_UOPS_RETIRED.SPLIT_STORES */
+	INTEL_UEVENT_CONSTRAINT(0x81d0, 0xf), /* MEM_UOPS_RETIRED.ALL_LOADS */
+	INTEL_UEVENT_CONSTRAINT(0x82d0, 0xf), /* MEM_UOPS_RETIRED.ALL_STORES */
+	INTEL_UEVENT_CONSTRAINT(0x01d1, 0xf), /* MEM_LOAD_UOPS_RETIRED.L1_HIT */
+	INTEL_UEVENT_CONSTRAINT(0x02d1, 0xf), /* MEM_LOAD_UOPS_RETIRED.L2_HIT */
+	INTEL_UEVENT_CONSTRAINT(0x04d1, 0xf), /* MEM_LOAD_UOPS_RETIRED.L3_HIT */
+	INTEL_UEVENT_CONSTRAINT(0x40d1, 0xf), /* MEM_LOAD_UOPS_RETIRED.HIT_LFB */
+	INTEL_UEVENT_CONSTRAINT(0x01d2, 0xf), /* MEM_LOAD_UOPS_LLC_HIT_RETIRED.XSNP_MISS */
+	INTEL_UEVENT_CONSTRAINT(0x02d2, 0xf), /* MEM_LOAD_UOPS_LLC_HIT_RETIRED.XSNP_HIT */
+	INTEL_UEVENT_CONSTRAINT(0x02d3, 0xf), /* MEM_LOAD_UOPS_LLC_MISS_RETIRED.LOCAL_DRAM */
+	INTEL_UEVENT_CONSTRAINT(0x04c8, 0xf), /* HLE_RETIRED.Abort */
+	INTEL_UEVENT_CONSTRAINT(0x04c9, 0xf), /* RTM_RETIRED.Abort */
+
+	EVENT_CONSTRAINT_END
+};
+
 struct event_constraint *intel_pebs_constraints(struct perf_event *event)
 {
 	struct event_constraint *c;
-- 
1.7.7.6


^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [PATCH 04/31] perf, core: Add generic intx/intx_checkpointed counter modifiers
  2012-09-28  4:31 perf PMU support for Haswell Andi Kleen
                   ` (2 preceding siblings ...)
  2012-09-28  4:31 ` [PATCH 03/31] perf, x86: Basic Haswell PEBS support Andi Kleen
@ 2012-09-28  4:31 ` Andi Kleen
  2012-09-28  9:02   ` Peter Zijlstra
  2012-09-28  4:31 ` [PATCH 05/31] perf, tools: Add :c,:t event modifiers in perf tools Andi Kleen
                   ` (26 subsequent siblings)
  30 siblings, 1 reply; 58+ messages in thread
From: Andi Kleen @ 2012-09-28  4:31 UTC (permalink / raw)
  To: linux-kernel; +Cc: x86, a.p.zijlstra, eranian, acme, Andi Kleen

From: Andi Kleen <ak@linux.intel.com>

Expose INTX (count in transaction only, :t) and INTX_CHECKPOINTED
(on transaction abort restore counter, :c) attributes as generic perf event
attributes. These are important for measuring basic hardware transactional behaviour.

They also need to be handled in a special way in the Haswell port, so it's useful
to have them as generic attributes.

Typically they would be used as a group with:

{cycles,cycles:t,cycles:ct}

Then:

Total cycles = cycles
Percent cycles in transaction = (cycles:t/cycles)*100
Percent cycles in transaction lost due to aborts = ((cycles:t-cycles:ct) / cycles)*100

This gives a quick overview of the transactional execution.

Used in followon patches.

Signed-off-by: Andi Kleen <ak@linux.intel.com>
---
 include/linux/perf_event.h |    7 +++++--
 1 files changed, 5 insertions(+), 2 deletions(-)

diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h
index 33ed9d6..4c2adfa 100644
--- a/include/linux/perf_event.h
+++ b/include/linux/perf_event.h
@@ -251,11 +251,14 @@ struct perf_event_attr {
 				precise_ip     :  2, /* skid constraint       */
 				mmap_data      :  1, /* non-exec mmap data    */
 				sample_id_all  :  1, /* sample_type all events */
-
 				exclude_host   :  1, /* don't count in host   */
 				exclude_guest  :  1, /* don't count in guest  */
+				intx           :  1, /* count inside transaction */
+				intx_checkpointed :  1, /* checkpointed in transaction */
+
+
 
-				__reserved_1   : 43;
+				__reserved_1   : 41;
 
 	union {
 		__u32		wakeup_events;	  /* wakeup every n events */
-- 
1.7.7.6


^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [PATCH 05/31] perf, tools: Add :c,:t event modifiers in perf tools
  2012-09-28  4:31 perf PMU support for Haswell Andi Kleen
                   ` (3 preceding siblings ...)
  2012-09-28  4:31 ` [PATCH 04/31] perf, core: Add generic intx/intx_checkpointed counter modifiers Andi Kleen
@ 2012-09-28  4:31 ` Andi Kleen
  2012-09-28  4:31 ` [PATCH 06/31] perf, tools: Add intx/intx_checkpoint to perf script and header printing Andi Kleen
                   ` (25 subsequent siblings)
  30 siblings, 0 replies; 58+ messages in thread
From: Andi Kleen @ 2012-09-28  4:31 UTC (permalink / raw)
  To: linux-kernel; +Cc: x86, a.p.zijlstra, eranian, acme, Andi Kleen

From: Andi Kleen <ak@linux.intel.com>

Haswell supports new per event qualifiers for TSX transactions and
checkpointed transaction qualifiers that can be used to compute the
events discarded due to aborts.

Implement it in the usertool as :t and :c

Signed-off-by: Andi Kleen <ak@linux.intel.com>
---
 tools/perf/Documentation/perf-list.txt |    6 ++++++
 tools/perf/util/evsel.c                |   14 ++++++++++++--
 tools/perf/util/parse-events.c         |    7 +++++++
 tools/perf/util/parse-events.l         |    2 +-
 4 files changed, 26 insertions(+), 3 deletions(-)

diff --git a/tools/perf/Documentation/perf-list.txt b/tools/perf/Documentation/perf-list.txt
index ddc2252..52ea166 100644
--- a/tools/perf/Documentation/perf-list.txt
+++ b/tools/perf/Documentation/perf-list.txt
@@ -34,6 +34,12 @@ Intel PEBS and can be specified multiple times:
 
 The PEBS implementation now supports up to 2.
 
+On Intel Haswell CPUs t and c can be specified to request that the event
+is only counted inside transactions ('t') or that the counter is rolled
+back to the beginning of the transaction on a abort ('c'). This can
+be used to account for transaction residency and cycles lost to transaction
+aborts.
+
 RAW HARDWARE EVENT DESCRIPTOR
 -----------------------------
 Even when an event is not available in a symbolic form within perf right now,
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
index 2eaae14..cda3805 100644
--- a/tools/perf/util/evsel.c
+++ b/tools/perf/util/evsel.c
@@ -93,11 +93,12 @@ static int perf_evsel__add_modifiers(struct perf_evsel *evsel, char *bf, size_t
 	struct perf_event_attr *attr = &evsel->attr;
 	bool exclude_guest_default = false;
 
-#define MOD_PRINT(context, mod)	do {					\
-		if (!attr->exclude_##context) {				\
+#define __MOD_PRINT(test, mod)	do {				\
+		if (test) {					\
 			if (!colon) colon = ++r;			\
 			r += scnprintf(bf + r, size - r, "%c", mod);	\
 		} } while(0)
+#define MOD_PRINT(context, mod) __MOD_PRINT(!attr->exclude_##context, mod)
 
 	if (attr->exclude_kernel || attr->exclude_user || attr->exclude_hv) {
 		MOD_PRINT(kernel, 'k');
@@ -113,11 +114,20 @@ static int perf_evsel__add_modifiers(struct perf_evsel *evsel, char *bf, size_t
 		exclude_guest_default = true;
 	}
 
+	if (attr->intx || attr->intx_checkpointed) {
+		__MOD_PRINT(attr->intx_checkpointed, 'c');
+		__MOD_PRINT(attr->intx, 't');
+		/* Set the bizarro flag: */
+		exclude_guest_default = true;
+	}
+
 	if (attr->exclude_host || attr->exclude_guest == exclude_guest_default) {
 		MOD_PRINT(host, 'H');
 		MOD_PRINT(guest, 'G');
 	}
+
 #undef MOD_PRINT
+#undef __MOD_PRINT
 	if (colon)
 		bf[colon - 1] = ':';
 	return r;
diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c
index 74a5af4..5668ca6 100644
--- a/tools/perf/util/parse-events.c
+++ b/tools/perf/util/parse-events.c
@@ -628,6 +628,7 @@ int parse_events_modifier(struct list_head *list, char *str)
 	struct perf_evsel *evsel;
 	int exclude = 0, exclude_GH = 0;
 	int eu = 0, ek = 0, eh = 0, eH = 0, eG = 0, precise = 0;
+	int intx = 0, intx_cp = 0;
 
 	if (str == NULL)
 		return 0;
@@ -655,6 +656,10 @@ int parse_events_modifier(struct list_head *list, char *str)
 			eH = 0;
 		} else if (*str == 'p') {
 			precise++;
+		} else if (*str == 't') {
+			intx = 1;
+		} else if (*str == 'c') {
+			intx_cp = 1;
 		} else
 			break;
 
@@ -681,6 +686,8 @@ int parse_events_modifier(struct list_head *list, char *str)
 		evsel->attr.precise_ip     = precise;
 		evsel->attr.exclude_host   = eH;
 		evsel->attr.exclude_guest  = eG;
+		evsel->attr.intx_checkpointed = intx_cp;
+		evsel->attr.intx	     = intx;
 	}
 
 	return 0;
diff --git a/tools/perf/util/parse-events.l b/tools/perf/util/parse-events.l
index 384ca74..96ab100 100644
--- a/tools/perf/util/parse-events.l
+++ b/tools/perf/util/parse-events.l
@@ -75,7 +75,7 @@ num_dec		[0-9]+
 num_hex		0x[a-fA-F0-9]+
 num_raw_hex	[a-fA-F0-9]+
 name		[a-zA-Z_*?][a-zA-Z0-9_*?]*
-modifier_event	[ukhpGH]{1,8}
+modifier_event	[ukhpGHct]+
 modifier_bp	[rwx]{1,3}
 
 %%
-- 
1.7.7.6


^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [PATCH 06/31] perf, tools: Add intx/intx_checkpoint to perf script and header printing
  2012-09-28  4:31 perf PMU support for Haswell Andi Kleen
                   ` (4 preceding siblings ...)
  2012-09-28  4:31 ` [PATCH 05/31] perf, tools: Add :c,:t event modifiers in perf tools Andi Kleen
@ 2012-09-28  4:31 ` Andi Kleen
  2012-09-28  4:31 ` [PATCH 07/31] perf, x86: Implement the :t and :c qualifiers for Haswell Andi Kleen
                   ` (24 subsequent siblings)
  30 siblings, 0 replies; 58+ messages in thread
From: Andi Kleen @ 2012-09-28  4:31 UTC (permalink / raw)
  To: linux-kernel; +Cc: x86, a.p.zijlstra, eranian, acme, Andi Kleen

From: Andi Kleen <ak@linux.intel.com>

Just straight forward use of the new flags

Signed-off-by: Andi Kleen <ak@linux.intel.com>
---
 tools/perf/util/header.c |    6 ++++--
 tools/perf/util/python.c |    8 +++++++-
 2 files changed, 11 insertions(+), 3 deletions(-)

diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c
index 74ea3c2..558b3b3 100644
--- a/tools/perf/util/header.c
+++ b/tools/perf/util/header.c
@@ -1217,9 +1217,11 @@ static void print_event_desc(struct perf_header *ph, int fd, FILE *fp)
 				(u64)attr.config1,
 				(u64)attr.config2);
 
-		fprintf(fp, ", excl_usr = %d, excl_kern = %d",
+		fprintf(fp, ", excl_usr = %d, excl_kern = %d, intx = %d, intx_cp = %d",
 				attr.exclude_user,
-				attr.exclude_kernel);
+				attr.exclude_kernel,
+				attr.intx,
+				attr.intx_checkpointed);
 
 		fprintf(fp, ", excl_host = %d, excl_guest = %d",
 				attr.exclude_host,
diff --git a/tools/perf/util/python.c b/tools/perf/util/python.c
index 0688bfb..70c234d 100644
--- a/tools/perf/util/python.c
+++ b/tools/perf/util/python.c
@@ -528,6 +528,8 @@ static int pyrf_evsel__init(struct pyrf_evsel *pevsel,
 		"bp_type",
 		"bp_addr",
 		"bp_len",
+		"intx",
+		"intx_checkpointed",
 		 NULL
 	};
 	u64 sample_period = 0;
@@ -548,6 +550,8 @@ static int pyrf_evsel__init(struct pyrf_evsel *pevsel,
 	    watermark = 0,
 	    precise_ip = 0,
 	    mmap_data = 0,
+	    intx = 0,
+	    intx_cp = 0,
 	    sample_id_all = 1;
 	int idx = 0;
 
@@ -562,7 +566,7 @@ static int pyrf_evsel__init(struct pyrf_evsel *pevsel,
 					 &enable_on_exec, &task, &watermark,
 					 &precise_ip, &mmap_data, &sample_id_all,
 					 &attr.wakeup_events, &attr.bp_type,
-					 &attr.bp_addr, &attr.bp_len, &idx))
+					 &attr.bp_addr, &attr.bp_len, &intx, &intx_cp, &idx))
 		return -1;
 
 	/* union... */
@@ -591,6 +595,8 @@ static int pyrf_evsel__init(struct pyrf_evsel *pevsel,
 	attr.precise_ip	    = precise_ip;
 	attr.mmap_data	    = mmap_data;
 	attr.sample_id_all  = sample_id_all;
+	attr.intx	    = intx;
+	attr.intx_checkpointed = intx_cp;
 
 	perf_evsel__init(&pevsel->evsel, &attr, idx);
 	return 0;
-- 
1.7.7.6


^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [PATCH 07/31] perf, x86: Implement the :t and :c qualifiers for Haswell
  2012-09-28  4:31 perf PMU support for Haswell Andi Kleen
                   ` (5 preceding siblings ...)
  2012-09-28  4:31 ` [PATCH 06/31] perf, tools: Add intx/intx_checkpoint to perf script and header printing Andi Kleen
@ 2012-09-28  4:31 ` Andi Kleen
  2012-09-28  4:31 ` [PATCH 08/31] perf, x86: Report PEBS event in a raw format Andi Kleen
                   ` (23 subsequent siblings)
  30 siblings, 0 replies; 58+ messages in thread
From: Andi Kleen @ 2012-09-28  4:31 UTC (permalink / raw)
  To: linux-kernel; +Cc: x86, a.p.zijlstra, eranian, acme, Andi Kleen

From: Andi Kleen <ak@linux.intel.com>

Implement the TSX transaction and checkpointed transaction qualifiers for
Haswell. This allows e.g. to profile the number of cycles in transactions.
The checkpointed qualifier requires forcing the event to
counter 2, implement this with a custom constraint for Haswell.

Signed-off-by: Andi Kleen <ak@linux.intel.com>
---
 arch/x86/kernel/cpu/perf_event_intel.c |   38 +++++++++++++++++++++++++++++++-
 1 files changed, 37 insertions(+), 1 deletions(-)

diff --git a/arch/x86/kernel/cpu/perf_event_intel.c b/arch/x86/kernel/cpu/perf_event_intel.c
index 695abd1..7dab353 100644
--- a/arch/x86/kernel/cpu/perf_event_intel.c
+++ b/arch/x86/kernel/cpu/perf_event_intel.c
@@ -13,6 +13,7 @@
 #include <linux/slab.h>
 #include <linux/export.h>
 
+#include <asm/cpufeature.h>
 #include <asm/hardirq.h>
 #include <asm/apic.h>
 
@@ -826,7 +827,8 @@ static inline bool intel_pmu_needs_lbr_smpl(struct perf_event *event)
 		return true;
 
 	/* implicit branch sampling to correct PEBS skid */
-	if (x86_pmu.intel_cap.pebs_trap && event->attr.precise_ip > 1)
+	if (x86_pmu.intel_cap.pebs_trap && event->attr.precise_ip > 1 &&
+	    x86_pmu.intel_cap.pebs_format < 2)
 		return true;
 
 	return false;
@@ -1614,6 +1616,38 @@ static struct attribute *intel_arch_formats_attr[] = {
 	NULL,
 };
 
+static int hsw_hw_config(struct perf_event *event)
+{
+	int ret = intel_pmu_hw_config(event);
+
+	if (ret)
+		return ret;
+	if (!boot_cpu_has(X86_FEATURE_RTM) && !boot_cpu_has(X86_FEATURE_HLE))
+		return 0;
+	if (event->attr.intx)
+		event->hw.config |= HSW_INTX;
+	if (event->attr.intx_checkpointed)
+		event->hw.config |= HSW_INTX_CHECKPOINTED;
+	return 0;
+}
+
+static struct event_constraint counter2_constraint = EVENT_CONSTRAINT(0, 0x4, 0);
+
+static struct event_constraint *
+hsw_get_event_constraints(struct cpu_hw_events *cpuc, struct perf_event *event)
+{
+	struct event_constraint *c = intel_get_event_constraints(cpuc, event);
+
+	/* Handle special quirk on intx_checkpointed only in counter 2 */
+	if (event->hw.config & HSW_INTX_CHECKPOINTED) {
+		if (c->idxmsk64 & (1U << 2))
+			return &counter2_constraint;
+		return &emptyconstraint;
+	}
+
+	return c;
+}
+
 static __initconst const struct x86_pmu core_pmu = {
 	.name			= "core",
 	.handle_irq		= x86_pmu_handle_irq,
@@ -2100,6 +2134,8 @@ __init int intel_pmu_init(void)
 		x86_pmu.er_flags |= ERF_HAS_RSP_1;
 		x86_pmu.er_flags |= ERF_NO_HT_SHARING;
 
+		x86_pmu.hw_config = hsw_hw_config;
+		x86_pmu.get_event_constraints = hsw_get_event_constraints;
 		pr_cont("Haswell events, ");
 		break;
 
-- 
1.7.7.6


^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [PATCH 08/31] perf, x86: Report PEBS event in a raw format
  2012-09-28  4:31 perf PMU support for Haswell Andi Kleen
                   ` (6 preceding siblings ...)
  2012-09-28  4:31 ` [PATCH 07/31] perf, x86: Implement the :t and :c qualifiers for Haswell Andi Kleen
@ 2012-09-28  4:31 ` Andi Kleen
  2012-09-28  8:54   ` Peter Zijlstra
  2012-09-28  4:31 ` [PATCH 09/31] perf, kvm: Support :t and :c perf modifiers in KVM arch perfmon emulation Andi Kleen
                   ` (22 subsequent siblings)
  30 siblings, 1 reply; 58+ messages in thread
From: Andi Kleen @ 2012-09-28  4:31 UTC (permalink / raw)
  To: linux-kernel; +Cc: x86, a.p.zijlstra, eranian, acme, Andi Kleen

From: Andi Kleen <ak@linux.intel.com>

Add support for reporting PEBS records in a raw format that can
be then parsed by perf script.

We exposed most of the Haswell PEBS fields in a generic way
in this patchkit:
- Aborted cycles is in weight
- Memory latency is in weight
- DataLA is in address
- EventingRIP is used for precise ip
- tsx_tuning and some bits of the abort code in RAX are
mapped to transaction flags

Left over are the general registers. We need them for some analysis
too: for example for loop trip count and string instruction trip
count sampling.

There isn't really any good way to generalize general registers.
Obviously they are different for every architecture.

So patch exports the RAW PEBS record when requested.

With the new perf script infrastructure that was recently added
it is reasonably easy and clean to process with script.

Signed-off-by: Andi Kleen <ak@linux.intel.com>
---
 arch/x86/kernel/cpu/perf_event_intel_ds.c |    7 +++++++
 1 files changed, 7 insertions(+), 0 deletions(-)

diff --git a/arch/x86/kernel/cpu/perf_event_intel_ds.c b/arch/x86/kernel/cpu/perf_event_intel_ds.c
index 994156f..5b60dcf 100644
--- a/arch/x86/kernel/cpu/perf_event_intel_ds.c
+++ b/arch/x86/kernel/cpu/perf_event_intel_ds.c
@@ -586,6 +586,7 @@ static void __intel_pmu_pebs_event(struct perf_event *event,
 	struct pebs_record_core *pebs = __pebs;
 	struct perf_sample_data data;
 	struct pt_regs regs;
+	struct perf_raw_record raw;
 
 	if (!intel_pmu_save_and_restart(event))
 		return;
@@ -616,6 +617,12 @@ static void __intel_pmu_pebs_event(struct perf_event *event,
 	else
 		regs.flags &= ~PERF_EFLAGS_EXACT;
 
+	if (event->attr.sample_type & PERF_SAMPLE_RAW) {
+		raw.size = x86_pmu.pebs_record_size;
+		raw.data = __pebs;
+		data.raw = &raw;
+	}
+
 	if (has_branch_stack(event))
 		data.br_stack = &cpuc->lbr_stack;
 
-- 
1.7.7.6


^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [PATCH 09/31] perf, kvm: Support :t and :c perf modifiers in KVM arch perfmon emulation
  2012-09-28  4:31 perf PMU support for Haswell Andi Kleen
                   ` (7 preceding siblings ...)
  2012-09-28  4:31 ` [PATCH 08/31] perf, x86: Report PEBS event in a raw format Andi Kleen
@ 2012-09-28  4:31 ` Andi Kleen
  2012-09-28  4:31 ` [PATCH 10/31] perf, x86: Support PERF_SAMPLE_ADDR on Haswell Andi Kleen
                   ` (21 subsequent siblings)
  30 siblings, 0 replies; 58+ messages in thread
From: Andi Kleen @ 2012-09-28  4:31 UTC (permalink / raw)
  To: linux-kernel; +Cc: x86, a.p.zijlstra, eranian, acme, Andi Kleen, avi

From: Andi Kleen <ak@linux.intel.com>

This is not arch perfmon, but older CPUs will just ignore it. This makes
it possible to do at least some TSX measurements from a KVM guest

Cc: avi@redhat.com
Signed-off-by: Andi Kleen <ak@linux.intel.com>
---
 arch/x86/kernel/cpu/perf_event_intel.c |    3 ++-
 arch/x86/kvm/pmu.c                     |   10 +++++++---
 2 files changed, 9 insertions(+), 4 deletions(-)

diff --git a/arch/x86/kernel/cpu/perf_event_intel.c b/arch/x86/kernel/cpu/perf_event_intel.c
index 7dab353..cd48669 100644
--- a/arch/x86/kernel/cpu/perf_event_intel.c
+++ b/arch/x86/kernel/cpu/perf_event_intel.c
@@ -1631,7 +1631,8 @@ static int hsw_hw_config(struct perf_event *event)
 	return 0;
 }
 
-static struct event_constraint counter2_constraint = EVENT_CONSTRAINT(0, 0x4, 0);
+static struct event_constraint counter2_constraint = 
+			EVENT_CONSTRAINT(0, 0x4, 0);
 
 static struct event_constraint *
 hsw_get_event_constraints(struct cpu_hw_events *cpuc, struct perf_event *event)
diff --git a/arch/x86/kvm/pmu.c b/arch/x86/kvm/pmu.c
index 9b7ec11..03ba87b 100644
--- a/arch/x86/kvm/pmu.c
+++ b/arch/x86/kvm/pmu.c
@@ -160,7 +160,7 @@ static void stop_counter(struct kvm_pmc *pmc)
 
 static void reprogram_counter(struct kvm_pmc *pmc, u32 type,
 		unsigned config, bool exclude_user, bool exclude_kernel,
-		bool intr)
+		bool intr, bool intx, bool intx_cp)
 {
 	struct perf_event *event;
 	struct perf_event_attr attr = {
@@ -172,6 +172,8 @@ static void reprogram_counter(struct kvm_pmc *pmc, u32 type,
 		.exclude_user = exclude_user,
 		.exclude_kernel = exclude_kernel,
 		.config = config,
+		.intx = intx,
+		.intx_checkpointed = intx_cp
 	};
 
 	attr.sample_period = (-pmc->counter) & pmc_bitmask(pmc);
@@ -239,7 +241,9 @@ static void reprogram_gp_counter(struct kvm_pmc *pmc, u64 eventsel)
 	reprogram_counter(pmc, type, config,
 			!(eventsel & ARCH_PERFMON_EVENTSEL_USR),
 			!(eventsel & ARCH_PERFMON_EVENTSEL_OS),
-			eventsel & ARCH_PERFMON_EVENTSEL_INT);
+			eventsel & ARCH_PERFMON_EVENTSEL_INT,
+			!!(eventsel & HSW_INTX),
+			!!(eventsel & HSW_INTX_CHECKPOINTED));
 }
 
 static void reprogram_fixed_counter(struct kvm_pmc *pmc, u8 en_pmi, int idx)
@@ -256,7 +260,7 @@ static void reprogram_fixed_counter(struct kvm_pmc *pmc, u8 en_pmi, int idx)
 			arch_events[fixed_pmc_events[idx]].event_type,
 			!(en & 0x2), /* exclude user */
 			!(en & 0x1), /* exclude kernel */
-			pmi);
+			pmi, false, false);
 }
 
 static inline u8 fixed_en_pmi(u64 ctrl, int idx)
-- 
1.7.7.6


^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [PATCH 10/31] perf, x86: Support PERF_SAMPLE_ADDR on Haswell
  2012-09-28  4:31 perf PMU support for Haswell Andi Kleen
                   ` (8 preceding siblings ...)
  2012-09-28  4:31 ` [PATCH 09/31] perf, kvm: Support :t and :c perf modifiers in KVM arch perfmon emulation Andi Kleen
@ 2012-09-28  4:31 ` Andi Kleen
  2012-09-28  4:31 ` [PATCH 11/31] perf, x86: Support Haswell v4 LBR format Andi Kleen
                   ` (20 subsequent siblings)
  30 siblings, 0 replies; 58+ messages in thread
From: Andi Kleen @ 2012-09-28  4:31 UTC (permalink / raw)
  To: linux-kernel; +Cc: x86, a.p.zijlstra, eranian, acme, Andi Kleen

From: Andi Kleen <ak@linux.intel.com>

Haswell supplies the address for every PEBS event, so always fill it in
when the user requested it.  It will be 0 when not useful (no memory access)

Signed-off-by: Andi Kleen <ak@linux.intel.com>
---
 arch/x86/kernel/cpu/perf_event_intel_ds.c |    4 ++++
 1 files changed, 4 insertions(+), 0 deletions(-)

diff --git a/arch/x86/kernel/cpu/perf_event_intel_ds.c b/arch/x86/kernel/cpu/perf_event_intel_ds.c
index 5b60dcf..81fc14a 100644
--- a/arch/x86/kernel/cpu/perf_event_intel_ds.c
+++ b/arch/x86/kernel/cpu/perf_event_intel_ds.c
@@ -623,6 +623,10 @@ static void __intel_pmu_pebs_event(struct perf_event *event,
 		data.raw = &raw;
 	}
 
+	if ((event->attr.sample_type & PERF_SAMPLE_ADDR) &&
+		x86_pmu.intel_cap.pebs_format >= 2)
+		data.addr = ((struct pebs_record_v2 *)pebs)->nhm.dla;
+
 	if (has_branch_stack(event))
 		data.br_stack = &cpuc->lbr_stack;
 
-- 
1.7.7.6


^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [PATCH 11/31] perf, x86: Support Haswell v4 LBR format
  2012-09-28  4:31 perf PMU support for Haswell Andi Kleen
                   ` (9 preceding siblings ...)
  2012-09-28  4:31 ` [PATCH 10/31] perf, x86: Support PERF_SAMPLE_ADDR on Haswell Andi Kleen
@ 2012-09-28  4:31 ` Andi Kleen
  2012-09-28  4:31 ` [PATCH 12/31] perf, x86: Disable LBR recording for unknown LBR_FMT Andi Kleen
                   ` (19 subsequent siblings)
  30 siblings, 0 replies; 58+ messages in thread
From: Andi Kleen @ 2012-09-28  4:31 UTC (permalink / raw)
  To: linux-kernel; +Cc: x86, a.p.zijlstra, eranian, acme, Andi Kleen

From: Andi Kleen <ak@linux.intel.com>

Haswell has two additional LBR from flags for TSX: intx and abort, implemented
as a new v4 version of the PEBS record.

Handle those in and adjust the sign extension code to still correctly extend.
The flags are exported similarly in the LBR record to the existing misprediction
flag

Signed-off-by: Andi Kleen <ak@linux.intel.com>
---
 arch/x86/kernel/cpu/perf_event_intel_lbr.c |   18 +++++++++++++++---
 include/linux/perf_event.h                 |    7 ++++++-
 2 files changed, 21 insertions(+), 4 deletions(-)

diff --git a/arch/x86/kernel/cpu/perf_event_intel_lbr.c b/arch/x86/kernel/cpu/perf_event_intel_lbr.c
index da02e9c..2af6695b 100644
--- a/arch/x86/kernel/cpu/perf_event_intel_lbr.c
+++ b/arch/x86/kernel/cpu/perf_event_intel_lbr.c
@@ -12,6 +12,7 @@ enum {
 	LBR_FORMAT_LIP		= 0x01,
 	LBR_FORMAT_EIP		= 0x02,
 	LBR_FORMAT_EIP_FLAGS	= 0x03,
+	LBR_FORMAT_EIP_FLAGS2	= 0x04,
 };
 
 /*
@@ -56,6 +57,8 @@ enum {
 	 LBR_FAR)
 
 #define LBR_FROM_FLAG_MISPRED  (1ULL << 63)
+#define LBR_FROM_FLAG_INTX     (1ULL << 62)
+#define LBR_FROM_FLAG_ABORT    (1ULL << 61)
 
 #define for_each_branch_sample_type(x) \
 	for ((x) = PERF_SAMPLE_BRANCH_USER; \
@@ -270,21 +273,30 @@ static void intel_pmu_lbr_read_64(struct cpu_hw_events *cpuc)
 
 	for (i = 0; i < x86_pmu.lbr_nr; i++) {
 		unsigned long lbr_idx = (tos - i) & mask;
-		u64 from, to, mis = 0, pred = 0;
+		u64 from, to, mis = 0, pred = 0, intx = 0, abort = 0;
 
 		rdmsrl(x86_pmu.lbr_from + lbr_idx, from);
 		rdmsrl(x86_pmu.lbr_to   + lbr_idx, to);
 
-		if (lbr_format == LBR_FORMAT_EIP_FLAGS) {
+		if (lbr_format == LBR_FORMAT_EIP_FLAGS ||
+		    lbr_format == LBR_FORMAT_EIP_FLAGS2) {
 			mis = !!(from & LBR_FROM_FLAG_MISPRED);
 			pred = !mis;
-			from = (u64)((((s64)from) << 1) >> 1);
+			if (lbr_format == LBR_FORMAT_EIP_FLAGS)
+				from = (u64)((((s64)from) << 1) >> 1);
+			else if (lbr_format == LBR_FORMAT_EIP_FLAGS2) {
+				intx = !!(from & LBR_FROM_FLAG_INTX);
+				abort = !!(from & LBR_FROM_FLAG_ABORT);
+				from = (u64)((((s64)from) << 3) >> 3);
+			}
 		}
 
 		cpuc->lbr_entries[i].from	= from;
 		cpuc->lbr_entries[i].to		= to;
 		cpuc->lbr_entries[i].mispred	= mis;
 		cpuc->lbr_entries[i].predicted	= pred;
+		cpuc->lbr_entries[i].intx	= intx;
+		cpuc->lbr_entries[i].abort	= abort;
 		cpuc->lbr_entries[i].reserved	= 0;
 	}
 	cpuc->lbr_stack.nr = i;
diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h
index 4c2adfa..fadd14b 100644
--- a/include/linux/perf_event.h
+++ b/include/linux/perf_event.h
@@ -634,13 +634,18 @@ struct perf_raw_record {
  *
  * support for mispred, predicted is optional. In case it
  * is not supported mispred = predicted = 0.
+ *
+ *     intx: running in a hardware transaction
+ *     abort: aborting a hardware transaction
  */
 struct perf_branch_entry {
 	__u64	from;
 	__u64	to;
 	__u64	mispred:1,  /* target mispredicted */
 		predicted:1,/* target predicted */
-		reserved:62;
+		intx:1,	    /* in transaction */
+		abort:1,    /* transaction abort */
+		reserved:60;
 };
 
 /*
-- 
1.7.7.6


^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [PATCH 12/31] perf, x86: Disable LBR recording for unknown LBR_FMT
  2012-09-28  4:31 perf PMU support for Haswell Andi Kleen
                   ` (10 preceding siblings ...)
  2012-09-28  4:31 ` [PATCH 11/31] perf, x86: Support Haswell v4 LBR format Andi Kleen
@ 2012-09-28  4:31 ` Andi Kleen
  2012-09-28  4:31 ` [PATCH 13/31] perf, x86: Support LBR filtering by INTX/NOTX/ABORT Andi Kleen
                   ` (18 subsequent siblings)
  30 siblings, 0 replies; 58+ messages in thread
From: Andi Kleen @ 2012-09-28  4:31 UTC (permalink / raw)
  To: linux-kernel; +Cc: x86, a.p.zijlstra, eranian, acme, Andi Kleen

From: Andi Kleen <ak@linux.intel.com>

When the LBR format is unknown disable LBR recording. This prevents
crashes when the LBR address is misdecoded and mis-sign extended.

Signed-off-by: Andi Kleen <ak@linux.intel.com>
---
 arch/x86/kernel/cpu/perf_event_intel_lbr.c |    3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)

diff --git a/arch/x86/kernel/cpu/perf_event_intel_lbr.c b/arch/x86/kernel/cpu/perf_event_intel_lbr.c
index 2af6695b..ad5af13 100644
--- a/arch/x86/kernel/cpu/perf_event_intel_lbr.c
+++ b/arch/x86/kernel/cpu/perf_event_intel_lbr.c
@@ -13,6 +13,7 @@ enum {
 	LBR_FORMAT_EIP		= 0x02,
 	LBR_FORMAT_EIP_FLAGS	= 0x03,
 	LBR_FORMAT_EIP_FLAGS2	= 0x04,
+	LBR_FORMAT_MAX_KNOWN	= LBR_FORMAT_EIP_FLAGS2,
 };
 
 /*
@@ -392,7 +393,7 @@ int intel_pmu_setup_lbr_filter(struct perf_event *event)
 	/*
 	 * no LBR on this PMU
 	 */
-	if (!x86_pmu.lbr_nr)
+	if (!x86_pmu.lbr_nr || x86_pmu.intel_cap.lbr_format > LBR_FORMAT_MAX_KNOWN)
 		return -EOPNOTSUPP;
 
 	/*
-- 
1.7.7.6


^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [PATCH 13/31] perf, x86: Support LBR filtering by INTX/NOTX/ABORT
  2012-09-28  4:31 perf PMU support for Haswell Andi Kleen
                   ` (11 preceding siblings ...)
  2012-09-28  4:31 ` [PATCH 12/31] perf, x86: Disable LBR recording for unknown LBR_FMT Andi Kleen
@ 2012-09-28  4:31 ` Andi Kleen
  2012-09-28  4:31 ` [PATCH 14/31] perf, tools: Add abort,notx,intx branch filter options to perf report -j Andi Kleen
                   ` (17 subsequent siblings)
  30 siblings, 0 replies; 58+ messages in thread
From: Andi Kleen @ 2012-09-28  4:31 UTC (permalink / raw)
  To: linux-kernel; +Cc: x86, a.p.zijlstra, eranian, acme, Andi Kleen

From: Andi Kleen <ak@linux.intel.com>

Add LBR filtering for branch in transaction, branch not in transaction
or transaction abort. This is exposed as new sample types.

Signed-off-by: Andi Kleen <ak@linux.intel.com>
---
 arch/x86/kernel/cpu/perf_event_intel_lbr.c |   31 +++++++++++++++++++++++++--
 include/linux/perf_event.h                 |    5 +++-
 2 files changed, 32 insertions(+), 4 deletions(-)

diff --git a/arch/x86/kernel/cpu/perf_event_intel_lbr.c b/arch/x86/kernel/cpu/perf_event_intel_lbr.c
index ad5af13..63451b1 100644
--- a/arch/x86/kernel/cpu/perf_event_intel_lbr.c
+++ b/arch/x86/kernel/cpu/perf_event_intel_lbr.c
@@ -85,9 +85,13 @@ enum {
 	X86_BR_JMP      = 1 << 9, /* jump */
 	X86_BR_IRQ      = 1 << 10,/* hw interrupt or trap or fault */
 	X86_BR_IND_CALL = 1 << 11,/* indirect calls */
+	X86_BR_ABORT    = 1 << 12,/* transaction abort */
+	X86_BR_INTX     = 1 << 13,/* in transaction */
+	X86_BR_NOTX     = 1 << 14,/* not in transaction */
 };
 
 #define X86_BR_PLM (X86_BR_USER | X86_BR_KERNEL)
+#define X86_BR_ANYTX (X86_BR_NOTX | X86_BR_INTX)
 
 #define X86_BR_ANY       \
 	(X86_BR_CALL    |\
@@ -99,6 +103,7 @@ enum {
 	 X86_BR_JCC     |\
 	 X86_BR_JMP	 |\
 	 X86_BR_IRQ	 |\
+	 X86_BR_ABORT	 |\
 	 X86_BR_IND_CALL)
 
 #define X86_BR_ALL (X86_BR_PLM | X86_BR_ANY)
@@ -347,6 +352,16 @@ static void intel_pmu_setup_sw_lbr_filter(struct perf_event *event)
 
 	if (br_type & PERF_SAMPLE_BRANCH_IND_CALL)
 		mask |= X86_BR_IND_CALL;
+
+	if (br_type & PERF_SAMPLE_BRANCH_ABORT)
+		mask |= X86_BR_ABORT;
+
+	if (br_type & PERF_SAMPLE_BRANCH_INTX)
+		mask |= X86_BR_INTX;
+
+	if (br_type & PERF_SAMPLE_BRANCH_NOTX)
+		mask |= X86_BR_NOTX;
+
 	/*
 	 * stash actual user request into reg, it may
 	 * be used by fixup code for some CPU
@@ -393,7 +408,8 @@ int intel_pmu_setup_lbr_filter(struct perf_event *event)
 	/*
 	 * no LBR on this PMU
 	 */
-	if (!x86_pmu.lbr_nr || x86_pmu.intel_cap.lbr_format > LBR_FORMAT_MAX_KNOWN)
+	if (!x86_pmu.lbr_nr || 
+	    x86_pmu.intel_cap.lbr_format > LBR_FORMAT_MAX_KNOWN)
 		return -EOPNOTSUPP;
 
 	/*
@@ -421,7 +437,7 @@ int intel_pmu_setup_lbr_filter(struct perf_event *event)
  * decoded (e.g., text page not present), then X86_BR_NONE is
  * returned.
  */
-static int branch_type(unsigned long from, unsigned long to)
+static int branch_type(unsigned long from, unsigned long to, int abort)
 {
 	struct insn insn;
 	void *addr;
@@ -441,6 +457,9 @@ static int branch_type(unsigned long from, unsigned long to)
 	if (from == 0 || to == 0)
 		return X86_BR_NONE;
 
+	if (abort)
+		return X86_BR_ABORT | to_plm;
+
 	if (from_plm == X86_BR_USER) {
 		/*
 		 * can happen if measuring at the user level only
@@ -577,7 +596,13 @@ intel_pmu_lbr_filter(struct cpu_hw_events *cpuc)
 		from = cpuc->lbr_entries[i].from;
 		to = cpuc->lbr_entries[i].to;
 
-		type = branch_type(from, to);
+		type = branch_type(from, to, cpuc->lbr_entries[i].abort);
+		if (type != X86_BR_NONE && (br_sel & X86_BR_ANYTX)) {
+			if (cpuc->lbr_entries[i].intx)
+				type |= X86_BR_INTX;
+			else
+				type |= X86_BR_NOTX;
+		}
 
 		/* if type does not correspond, then discard */
 		if (type == X86_BR_NONE || (br_sel & type) != type) {
diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h
index fadd14b..5bc0e8b 100644
--- a/include/linux/perf_event.h
+++ b/include/linux/perf_event.h
@@ -153,8 +153,11 @@ enum perf_branch_sample_type {
 	PERF_SAMPLE_BRANCH_ANY_CALL	= 1U << 4, /* any call branch */
 	PERF_SAMPLE_BRANCH_ANY_RETURN	= 1U << 5, /* any return branch */
 	PERF_SAMPLE_BRANCH_IND_CALL	= 1U << 6, /* indirect calls */
+	PERF_SAMPLE_BRANCH_ABORT	= 1U << 7, /* transaction aborts */
+	PERF_SAMPLE_BRANCH_INTX		= 1U << 8, /* in transaction (flag) */
+	PERF_SAMPLE_BRANCH_NOTX		= 1U << 9, /* not in transaction (flag) */
 
-	PERF_SAMPLE_BRANCH_MAX		= 1U << 7, /* non-ABI */
+	PERF_SAMPLE_BRANCH_MAX		= 1U << 10, /* non-ABI */
 };
 
 #define PERF_SAMPLE_BRANCH_PLM_ALL \
-- 
1.7.7.6


^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [PATCH 14/31] perf, tools: Add abort,notx,intx branch filter options to perf report -j
  2012-09-28  4:31 perf PMU support for Haswell Andi Kleen
                   ` (12 preceding siblings ...)
  2012-09-28  4:31 ` [PATCH 13/31] perf, x86: Support LBR filtering by INTX/NOTX/ABORT Andi Kleen
@ 2012-09-28  4:31 ` Andi Kleen
  2012-09-28  4:31 ` [PATCH 15/31] perf, tools: Support sorting by intx, abort branch flags Andi Kleen
                   ` (16 subsequent siblings)
  30 siblings, 0 replies; 58+ messages in thread
From: Andi Kleen @ 2012-09-28  4:31 UTC (permalink / raw)
  To: linux-kernel; +Cc: x86, a.p.zijlstra, eranian, acme, Andi Kleen

From: Andi Kleen <ak@linux.intel.com>

Make perf report -j aware of the new intx,notx,abort branch qualifiers.

Signed-off-by: Andi Kleen <ak@linux.intel.com>
---
 tools/perf/builtin-record.c |    3 +++
 1 files changed, 3 insertions(+), 0 deletions(-)

diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
index 4db6e1b..e851bf2 100644
--- a/tools/perf/builtin-record.c
+++ b/tools/perf/builtin-record.c
@@ -666,6 +666,9 @@ static const struct branch_mode branch_modes[] = {
 	BRANCH_OPT("any_call", PERF_SAMPLE_BRANCH_ANY_CALL),
 	BRANCH_OPT("any_ret", PERF_SAMPLE_BRANCH_ANY_RETURN),
 	BRANCH_OPT("ind_call", PERF_SAMPLE_BRANCH_IND_CALL),
+	BRANCH_OPT("abort", PERF_SAMPLE_BRANCH_ABORT),
+	BRANCH_OPT("intx", PERF_SAMPLE_BRANCH_INTX),
+	BRANCH_OPT("notx", PERF_SAMPLE_BRANCH_NOTX),
 	BRANCH_END
 };
 
-- 
1.7.7.6


^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [PATCH 15/31] perf, tools: Support sorting by intx, abort branch flags
  2012-09-28  4:31 perf PMU support for Haswell Andi Kleen
                   ` (13 preceding siblings ...)
  2012-09-28  4:31 ` [PATCH 14/31] perf, tools: Add abort,notx,intx branch filter options to perf report -j Andi Kleen
@ 2012-09-28  4:31 ` Andi Kleen
  2012-09-28  4:31 ` [PATCH 16/31] perf, x86: Support full width counting on Haswell Andi Kleen
                   ` (15 subsequent siblings)
  30 siblings, 0 replies; 58+ messages in thread
From: Andi Kleen @ 2012-09-28  4:31 UTC (permalink / raw)
  To: linux-kernel; +Cc: x86, a.p.zijlstra, eranian, acme, Andi Kleen

From: Andi Kleen <ak@linux.intel.com>

Extend the perf branch sorting code to support sorting by intx
or abort qualifiers. Also print out those qualifiers.

Signed-off-by: Andi Kleen <ak@linux.intel.com>
---
 tools/perf/builtin-report.c |    3 +-
 tools/perf/builtin-top.c    |    4 ++-
 tools/perf/perf.h           |    4 ++-
 tools/perf/util/hist.h      |    2 +
 tools/perf/util/sort.c      |   55 +++++++++++++++++++++++++++++++++++++++++++
 tools/perf/util/sort.h      |    2 +
 6 files changed, 67 insertions(+), 3 deletions(-)

diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c
index 7c88a24..8231cb1 100644
--- a/tools/perf/builtin-report.c
+++ b/tools/perf/builtin-report.c
@@ -594,7 +594,8 @@ int cmd_report(int argc, const char **argv, const char *prefix __used)
 		    "Use the stdio interface"),
 	OPT_STRING('s', "sort", &sort_order, "key[,key2...]",
 		   "sort by key(s): pid, comm, dso, symbol, parent, dso_to,"
-		   " dso_from, symbol_to, symbol_from, mispredict"),
+		   " dso_from, symbol_to, symbol_from, mispredict, srcline,"
+		   " abort, intx"),
 	OPT_BOOLEAN(0, "showcpuutilization", &symbol_conf.show_cpu_utilization,
 		    "Show sample percentage for different cpu modes"),
 	OPT_STRING('p', "parent", &parent_pattern, "regex",
diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c
index 68cd61e..5ab2188 100644
--- a/tools/perf/builtin-top.c
+++ b/tools/perf/builtin-top.c
@@ -1227,7 +1227,9 @@ int cmd_top(int argc, const char **argv, const char *prefix __used)
 	OPT_INCR('v', "verbose", &verbose,
 		    "be more verbose (show counter open errors, etc)"),
 	OPT_STRING('s', "sort", &sort_order, "key[,key2...]",
-		   "sort by key(s): pid, comm, dso, symbol, parent"),
+		   "sort by key(s): pid, comm, dso, symbol, parent, dso_to,"
+		   " dso_from, symbol_to, symbol_from, mispredict, srcline,"
+		   " abort, intx"),
 	OPT_BOOLEAN('n', "show-nr-samples", &symbol_conf.show_nr_samples,
 		    "Show a column with the number of samples"),
 	OPT_CALLBACK_DEFAULT('G', "call-graph", &top, "output_type,min_percent, call_order",
diff --git a/tools/perf/perf.h b/tools/perf/perf.h
index f960ccb..9147ffc 100644
--- a/tools/perf/perf.h
+++ b/tools/perf/perf.h
@@ -188,7 +188,9 @@ struct ip_callchain {
 struct branch_flags {
 	u64 mispred:1;
 	u64 predicted:1;
-	u64 reserved:62;
+	u64 intx:1;
+	u64 abort:1;
+	u64 reserved:60;
 };
 
 struct branch_entry {
diff --git a/tools/perf/util/hist.h b/tools/perf/util/hist.h
index 0b096c2..71837aa 100644
--- a/tools/perf/util/hist.h
+++ b/tools/perf/util/hist.h
@@ -43,6 +43,8 @@ enum hist_column {
 	HISTC_PARENT,
 	HISTC_CPU,
 	HISTC_MISPREDICT,
+	HISTC_INTX,
+	HISTC_ABORT,
 	HISTC_SYMBOL_FROM,
 	HISTC_SYMBOL_TO,
 	HISTC_DSO_FROM,
diff --git a/tools/perf/util/sort.c b/tools/perf/util/sort.c
index 0f5a0a4..596b82c 100644
--- a/tools/perf/util/sort.c
+++ b/tools/perf/util/sort.c
@@ -467,6 +467,55 @@ struct sort_entry sort_mispredict = {
 	.se_width_idx	= HISTC_MISPREDICT,
 };
 
+static int64_t
+sort__abort_cmp(struct hist_entry *left, struct hist_entry *right)
+{
+	return left->branch_info->flags.abort !=
+		right->branch_info->flags.abort;
+}
+
+static int hist_entry__abort_snprintf(struct hist_entry *self, char *bf,
+				    size_t size, unsigned int width)
+{
+	static const char *out = ".";
+
+	if (self->branch_info->flags.abort)
+		out = "A";
+	return repsep_snprintf(bf, size, "%-*s", width, out);
+}
+
+struct sort_entry sort_abort = {
+	.se_header	= "Transaction abort",
+	.se_cmp		= sort__abort_cmp,
+	.se_snprintf	= hist_entry__abort_snprintf,
+	.se_width_idx	= HISTC_ABORT,
+};
+
+static int64_t
+sort__intx_cmp(struct hist_entry *left, struct hist_entry *right)
+{
+	return left->branch_info->flags.intx !=
+		right->branch_info->flags.intx;
+}
+
+static int hist_entry__intx_snprintf(struct hist_entry *self, char *bf,
+				    size_t size, unsigned int width)
+{
+	static const char *out = ".";
+
+	if (self->branch_info->flags.intx)
+		out = "T";
+
+	return repsep_snprintf(bf, size, "%-*s", width, out);
+}
+
+struct sort_entry sort_intx = {
+	.se_header	= "Branch in transaction",
+	.se_cmp		= sort__intx_cmp,
+	.se_snprintf	= hist_entry__intx_snprintf,
+	.se_width_idx	= HISTC_INTX,
+};
+
 struct sort_dimension {
 	const char		*name;
 	struct sort_entry	*entry;
@@ -488,6 +537,8 @@ static struct sort_dimension sort_dimensions[] = {
 	DIM(SORT_CPU, "cpu", sort_cpu),
 	DIM(SORT_MISPREDICT, "mispredict", sort_mispredict),
 	DIM(SORT_SRCLINE, "srcline", sort_srcline),
+	DIM(SORT_ABORT, "abort", sort_abort),
+	DIM(SORT_INTX, "intx", sort_intx)
 };
 
 int sort_dimension__add(const char *tok)
@@ -540,6 +591,10 @@ int sort_dimension__add(const char *tok)
 				sort__first_dimension = SORT_DSO_TO;
 			else if (!strcmp(sd->name, "mispredict"))
 				sort__first_dimension = SORT_MISPREDICT;
+			else if (!strcmp(sd->name, "intx"))
+				sort__first_dimension = SORT_INTX;
+			else if (!strcmp(sd->name, "abort"))
+				sort__first_dimension = SORT_ABORT;
 		}
 
 		list_add_tail(&sd->entry->list, &hist_entry__sort_list);
diff --git a/tools/perf/util/sort.h b/tools/perf/util/sort.h
index e724b26..fdb033f 100644
--- a/tools/perf/util/sort.h
+++ b/tools/perf/util/sort.h
@@ -95,6 +95,8 @@ enum sort_type {
 	SORT_SYM_TO,
 	SORT_MISPREDICT,
 	SORT_SRCLINE,
+	SORT_ABORT,
+	SORT_INTX,
 };
 
 /*
-- 
1.7.7.6


^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [PATCH 16/31] perf, x86: Support full width counting on Haswell
  2012-09-28  4:31 perf PMU support for Haswell Andi Kleen
                   ` (14 preceding siblings ...)
  2012-09-28  4:31 ` [PATCH 15/31] perf, tools: Support sorting by intx, abort branch flags Andi Kleen
@ 2012-09-28  4:31 ` Andi Kleen
  2012-09-28  4:31 ` [PATCH 17/31] perf, x86: Avoid checkpointed counters causing excessive TSX aborts Andi Kleen
                   ` (14 subsequent siblings)
  30 siblings, 0 replies; 58+ messages in thread
From: Andi Kleen @ 2012-09-28  4:31 UTC (permalink / raw)
  To: linux-kernel; +Cc: x86, a.p.zijlstra, eranian, acme, Andi Kleen

From: Andi Kleen <ak@linux.intel.com>

Haswell has a new alternative MSR range for perfctrs that allows writing the full
counter width. Enable this range if the hardware reports it using a new capability
bit. This lowers overhead of perf stat slightly because it has to do less interrupts
to accumulate the counter value. It also avoids some problems with TSX
aborting when the end of the counter range is reached.

Signed-off-by: Andi Kleen <ak@linux.intel.com>
---
 arch/x86/include/asm/msr-index.h       |    3 +++
 arch/x86/kernel/cpu/perf_event.h       |    1 +
 arch/x86/kernel/cpu/perf_event_intel.c |    6 ++++++
 3 files changed, 10 insertions(+), 0 deletions(-)

diff --git a/arch/x86/include/asm/msr-index.h b/arch/x86/include/asm/msr-index.h
index 957ec87..cbf344f 100644
--- a/arch/x86/include/asm/msr-index.h
+++ b/arch/x86/include/asm/msr-index.h
@@ -121,6 +121,9 @@
 #define MSR_P6_EVNTSEL0			0x00000186
 #define MSR_P6_EVNTSEL1			0x00000187
 
+/* Alternative perfctr range with full access. */
+#define MSR_IA32_PMC0			0x000004c1
+
 /* AMD64 MSRs. Not complete. See the architecture manual for a more
    complete list. */
 
diff --git a/arch/x86/kernel/cpu/perf_event.h b/arch/x86/kernel/cpu/perf_event.h
index 8200c69..8550601 100644
--- a/arch/x86/kernel/cpu/perf_event.h
+++ b/arch/x86/kernel/cpu/perf_event.h
@@ -282,6 +282,7 @@ union perf_capabilities {
 		u64	pebs_arch_reg:1;
 		u64	pebs_format:4;
 		u64	smm_freeze:1;
+		u64	fw_write:1;
 	};
 	u64	capabilities;
 };
diff --git a/arch/x86/kernel/cpu/perf_event_intel.c b/arch/x86/kernel/cpu/perf_event_intel.c
index cd48669..e302186 100644
--- a/arch/x86/kernel/cpu/perf_event_intel.c
+++ b/arch/x86/kernel/cpu/perf_event_intel.c
@@ -2188,5 +2188,11 @@ __init int intel_pmu_init(void)
 		}
 	}
 
+	/* Support full width counters using alternative MSR range */
+	if (x86_pmu.intel_cap.fw_write) {
+		x86_pmu.max_period = x86_pmu.cntval_mask;
+		x86_pmu.perfctr = MSR_IA32_PMC0;
+	}
+
 	return 0;
 }
-- 
1.7.7.6


^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [PATCH 17/31] perf, x86: Avoid checkpointed counters causing excessive TSX aborts
  2012-09-28  4:31 perf PMU support for Haswell Andi Kleen
                   ` (15 preceding siblings ...)
  2012-09-28  4:31 ` [PATCH 16/31] perf, x86: Support full width counting on Haswell Andi Kleen
@ 2012-09-28  4:31 ` Andi Kleen
  2012-09-28  4:31 ` [PATCH 18/31] perf, core: Add a concept of a weightened sample Andi Kleen
                   ` (13 subsequent siblings)
  30 siblings, 0 replies; 58+ messages in thread
From: Andi Kleen @ 2012-09-28  4:31 UTC (permalink / raw)
  To: linux-kernel; +Cc: x86, a.p.zijlstra, eranian, acme, Andi Kleen

From: Andi Kleen <ak@linux.intel.com>

With checkpointed counters there can be a situation where the counter
is overflowing, aborts the transaction, is set back to a non overflowing
checkpoint, causes interupt. The interrupt doesn't see the overflow
because it has been checkpointed.  This is then a spurious PMI, typically with a
ugly NMI message.  It can also lead to excessive aborts.

Avoid this problem by:
- Using the full counter width for counting counters (previous patch)
- Forbid sampling for checkpointed counters. It's not too useful anyways,
checkpointing is mainly for counting.
- On a PMI always set back checkpointed counters to zero.

Signed-off-by: Andi Kleen <ak@linux.intel.com>
---
 arch/x86/kernel/cpu/perf_event_intel.c |   26 +++++++++++++++++++++++++-
 1 files changed, 25 insertions(+), 1 deletions(-)

diff --git a/arch/x86/kernel/cpu/perf_event_intel.c b/arch/x86/kernel/cpu/perf_event_intel.c
index e302186..83ced1a 100644
--- a/arch/x86/kernel/cpu/perf_event_intel.c
+++ b/arch/x86/kernel/cpu/perf_event_intel.c
@@ -1079,6 +1079,17 @@ static void intel_pmu_enable_event(struct perf_event *event)
 int intel_pmu_save_and_restart(struct perf_event *event)
 {
 	x86_perf_event_update(event);
+	/*
+	 * For a checkpointed counter always reset back to 0.  This
+	 * avoids a situation where the counter overflows, aborts the
+	 * transaction and is then set back to shortly before the
+	 * overflow, and overflows and aborts again.
+	 */
+	if (event->attr.intx_checkpointed) {
+		/* No race with NMIs because the counter should not be armed */
+		wrmsrl(event->hw.event_base, 0);
+		local64_set(&event->hw.prev_count, 0);
+	}
 	return x86_perf_event_set_period(event);
 }
 
@@ -1162,6 +1173,10 @@ again:
 		x86_pmu.drain_pebs(regs);
 	}
 
+	/* XXX move somewhere else. */
+	if (cpuc->events[2] && cpuc->events[2]->attr.intx_checkpointed)
+		status |= (1ULL << 2);
+
 	for_each_set_bit(bit, (unsigned long *)&status, X86_PMC_IDX_MAX) {
 		struct perf_event *event = cpuc->events[bit];
 
@@ -1626,8 +1641,17 @@ static int hsw_hw_config(struct perf_event *event)
 		return 0;
 	if (event->attr.intx)
 		event->hw.config |= HSW_INTX;
-	if (event->attr.intx_checkpointed)
+	if (event->attr.intx_checkpointed) {
+		/*
+		 * Sampling of checkpointed events can cause situations where
+		 * the CPU constantly aborts because of a overflow, which is
+		 * then checkpointed back and ignored. Forbid checkpointing
+		 * for sampling.
+		 */
+		if (is_sampling_event(event))
+			return -EIO;
 		event->hw.config |= HSW_INTX_CHECKPOINTED;
+	}
 	return 0;
 }
 
-- 
1.7.7.6


^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [PATCH 18/31] perf, core: Add a concept of a weightened sample
  2012-09-28  4:31 perf PMU support for Haswell Andi Kleen
                   ` (16 preceding siblings ...)
  2012-09-28  4:31 ` [PATCH 17/31] perf, x86: Avoid checkpointed counters causing excessive TSX aborts Andi Kleen
@ 2012-09-28  4:31 ` Andi Kleen
  2012-09-28  9:06   ` Stephane Eranian
  2012-09-28  4:31 ` [PATCH 19/31] perf, x86: Support weight samples for PEBS Andi Kleen
                   ` (12 subsequent siblings)
  30 siblings, 1 reply; 58+ messages in thread
From: Andi Kleen @ 2012-09-28  4:31 UTC (permalink / raw)
  To: linux-kernel; +Cc: x86, a.p.zijlstra, eranian, acme, Andi Kleen

From: Andi Kleen <ak@linux.intel.com>

For some events it's useful to weight sample with a hardware
provided number. This expresses how expensive the action the
sample represent was.  This allows the profiler to scale
the samples to be more informative to the programmer.

There is already the period which is used similarly, but it means
something different, so I chose to not overload it. Instead
a new sample type for WEIGHT is added.

Can be used for multiple things. Initially it is used for TSX abort costs
and profiling by memory latencies (so to make expensive load appear higher
up in the histograms)  The concept is quite generic and can be extended
to many other kinds of events or architectures, as long as the hardware
provides suitable auxillary values. In principle it could be also
used for software tracpoints.

This adds the generic glue. A new optional sample format for a 64bit
weight value.

Signed-off-by: Andi Kleen <ak@linux.intel.com>
---
 include/linux/perf_event.h |    9 +++++++--
 kernel/events/core.c       |    6 ++++++
 2 files changed, 13 insertions(+), 2 deletions(-)

diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h
index 5bc0e8b..c488ae2 100644
--- a/include/linux/perf_event.h
+++ b/include/linux/perf_event.h
@@ -130,8 +130,9 @@ enum perf_event_sample_format {
 	PERF_SAMPLE_STREAM_ID			= 1U << 9,
 	PERF_SAMPLE_RAW				= 1U << 10,
 	PERF_SAMPLE_BRANCH_STACK		= 1U << 11,
+	PERF_SAMPLE_WEIGHT			= 1U << 12,
 
-	PERF_SAMPLE_MAX = 1U << 12,		/* non-ABI */
+	PERF_SAMPLE_MAX = 1U << 13,		/* non-ABI */
 };
 
 /*
@@ -190,8 +191,9 @@ enum perf_event_read_format {
 	PERF_FORMAT_TOTAL_TIME_RUNNING		= 1U << 1,
 	PERF_FORMAT_ID				= 1U << 2,
 	PERF_FORMAT_GROUP			= 1U << 3,
+	PERF_FORMAT_WEIGHT			= 1U << 4,
 
-	PERF_FORMAT_MAX = 1U << 4,		/* non-ABI */
+	PERF_FORMAT_MAX = 1U << 5,		/* non-ABI */
 };
 
 #define PERF_ATTR_SIZE_VER0	64	/* sizeof first published struct */
@@ -533,6 +535,7 @@ enum perf_event_type {
 	 *	{ u64			stream_id;} && PERF_SAMPLE_STREAM_ID
 	 *	{ u32			cpu, res; } && PERF_SAMPLE_CPU
 	 *	{ u64			period;   } && PERF_SAMPLE_PERIOD
+	 *	{ u64			weight;   } && PERF_SAMPLE_WEIGHT
 	 *
 	 *	{ struct read_format	values;	  } && PERF_SAMPLE_READ
 	 *
@@ -1144,6 +1147,7 @@ struct perf_sample_data {
 	struct perf_callchain_entry	*callchain;
 	struct perf_raw_record		*raw;
 	struct perf_branch_stack	*br_stack;
+	u64				weight;
 };
 
 static inline void perf_sample_data_init(struct perf_sample_data *data,
@@ -1154,6 +1158,7 @@ static inline void perf_sample_data_init(struct perf_sample_data *data,
 	data->raw  = NULL;
 	data->br_stack = NULL;
 	data->period	= period;
+	data->weight = 0;
 }
 
 extern void perf_output_sample(struct perf_output_handle *handle,
diff --git a/kernel/events/core.c b/kernel/events/core.c
index 7fee567..74e4ff4 100644
--- a/kernel/events/core.c
+++ b/kernel/events/core.c
@@ -949,6 +949,9 @@ static void perf_event__header_size(struct perf_event *event)
 	if (sample_type & PERF_SAMPLE_PERIOD)
 		size += sizeof(data->period);
 
+	if (sample_type & PERF_SAMPLE_WEIGHT)
+		size += sizeof(data->weight);
+
 	if (sample_type & PERF_SAMPLE_READ)
 		size += event->read_size;
 
@@ -3957,6 +3960,9 @@ void perf_output_sample(struct perf_output_handle *handle,
 	if (sample_type & PERF_SAMPLE_PERIOD)
 		perf_output_put(handle, data->period);
 
+	if (sample_type & PERF_SAMPLE_WEIGHT)
+		perf_output_put(handle, data->weight);
+
 	if (sample_type & PERF_SAMPLE_READ)
 		perf_output_read(handle, event);
 
-- 
1.7.7.6


^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [PATCH 19/31] perf, x86: Support weight samples for PEBS
  2012-09-28  4:31 perf PMU support for Haswell Andi Kleen
                   ` (17 preceding siblings ...)
  2012-09-28  4:31 ` [PATCH 18/31] perf, core: Add a concept of a weightened sample Andi Kleen
@ 2012-09-28  4:31 ` Andi Kleen
  2012-09-28  4:31 ` [PATCH 20/31] perf, tools: Add support for weight Andi Kleen
                   ` (11 subsequent siblings)
  30 siblings, 0 replies; 58+ messages in thread
From: Andi Kleen @ 2012-09-28  4:31 UTC (permalink / raw)
  To: linux-kernel; +Cc: x86, a.p.zijlstra, eranian, acme, Andi Kleen

From: Andi Kleen <ak@linux.intel.com>

When a weighted sample is requested, first try to report the TSX abort cost
on Haswell. If that is not available report the memory latency. This
allows profiling both by abort cost and by memory latencies.

Memory latencies requires enabling a different PEBS mode (LL).
When both address and weight is requested address wins.

The LL mode only works for memory related PEBS events, so add a
separate event constraint table for those.

I only did this for Haswell for now, but it could be added
for several other Intel CPUs too by just adding the right
table for them.

Signed-off-by: Andi Kleen <ak@linux.intel.com>
---
 arch/x86/kernel/cpu/perf_event.h          |    4 ++
 arch/x86/kernel/cpu/perf_event_intel.c    |    4 ++
 arch/x86/kernel/cpu/perf_event_intel_ds.c |   47 +++++++++++++++++++++++++++-
 3 files changed, 53 insertions(+), 2 deletions(-)

diff --git a/arch/x86/kernel/cpu/perf_event.h b/arch/x86/kernel/cpu/perf_event.h
index 8550601..724a141 100644
--- a/arch/x86/kernel/cpu/perf_event.h
+++ b/arch/x86/kernel/cpu/perf_event.h
@@ -168,6 +168,7 @@ struct cpu_hw_events {
 	u64				perf_ctr_virt_mask;
 
 	void				*kfree_on_online;
+	u8				*memory_latency_events;
 };
 
 #define __EVENT_CONSTRAINT(c, n, m, w, o) {\
@@ -392,6 +393,7 @@ struct x86_pmu {
 	struct event_constraint *pebs_constraints;
 	void		(*pebs_aliases)(struct perf_event *event);
 	int 		max_pebs_events;
+	struct event_constraint *memory_lat_events;
 
 	/*
 	 * Intel LBR
@@ -596,6 +598,8 @@ extern struct event_constraint intel_snb_pebs_event_constraints[];
 
 extern struct event_constraint intel_hsw_pebs_event_constraints[];
 
+extern struct event_constraint intel_hsw_memory_latency_events[];
+
 struct event_constraint *intel_pebs_constraints(struct perf_event *event);
 
 void intel_pmu_pebs_enable(struct perf_event *event);
diff --git a/arch/x86/kernel/cpu/perf_event_intel.c b/arch/x86/kernel/cpu/perf_event_intel.c
index 83ced1a..2c4cbf3 100644
--- a/arch/x86/kernel/cpu/perf_event_intel.c
+++ b/arch/x86/kernel/cpu/perf_event_intel.c
@@ -1637,6 +1637,9 @@ static int hsw_hw_config(struct perf_event *event)
 
 	if (ret)
 		return ret;
+	/* PEBS cannot capture both */
+	if (event->attr.sample_type & PERF_SAMPLE_ADDR)
+		event->attr.sample_type &= ~PERF_SAMPLE_WEIGHT;
 	if (!boot_cpu_has(X86_FEATURE_RTM) && !boot_cpu_has(X86_FEATURE_HLE))
 		return 0;
 	if (event->attr.intx)
@@ -2161,6 +2164,7 @@ __init int intel_pmu_init(void)
 
 		x86_pmu.hw_config = hsw_hw_config;
 		x86_pmu.get_event_constraints = hsw_get_event_constraints;
+		x86_pmu.memory_lat_events = intel_hsw_memory_latency_events;
 		pr_cont("Haswell events, ");
 		break;
 
diff --git a/arch/x86/kernel/cpu/perf_event_intel_ds.c b/arch/x86/kernel/cpu/perf_event_intel_ds.c
index 81fc14a..930bc65 100644
--- a/arch/x86/kernel/cpu/perf_event_intel_ds.c
+++ b/arch/x86/kernel/cpu/perf_event_intel_ds.c
@@ -442,6 +442,17 @@ struct event_constraint intel_hsw_pebs_event_constraints[] = {
 	EVENT_CONSTRAINT_END
 };
 
+/* Subset of PEBS events supporting memory latency. Not used for scheduling */
+
+struct event_constraint intel_hsw_memory_latency_events[] = {
+	INTEL_EVENT_CONSTRAINT(0xcd, 0), /* MEM_TRANS_RETIRED.* */
+	INTEL_EVENT_CONSTRAINT(0xd0, 0), /* MEM_UOPS_RETIRED.* */
+	INTEL_EVENT_CONSTRAINT(0xd1, 0), /* MEM_LOAD_UOPS_RETIRED.* */
+	INTEL_EVENT_CONSTRAINT(0xd2, 0), /* MEM_LOAD_UOPS_LLC_HIT_RETIRED.* */
+	INTEL_EVENT_CONSTRAINT(0xd3, 0), /* MEM_LOAD_UOPS_LLC_MISS_RETIRED.* */
+	EVENT_CONSTRAINT_END
+};
+
 struct event_constraint *intel_pebs_constraints(struct perf_event *event)
 {
 	struct event_constraint *c;
@@ -459,6 +470,21 @@ struct event_constraint *intel_pebs_constraints(struct perf_event *event)
 	return &emptyconstraint;
 }
 
+static bool is_memory_lat_event(struct perf_event *event)
+{
+	struct event_constraint *c;
+
+	if (x86_pmu.intel_cap.pebs_format < 1)
+		return false;
+	if (!x86_pmu.memory_lat_events)
+		return false;
+	for_each_event_constraint(c, x86_pmu.memory_lat_events) {
+		if ((event->hw.config & c->cmask) == c->code)
+			return true;
+	}
+	return false;
+}
+
 void intel_pmu_pebs_enable(struct perf_event *event)
 {
 	struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
@@ -466,7 +492,12 @@ void intel_pmu_pebs_enable(struct perf_event *event)
 
 	hwc->config &= ~ARCH_PERFMON_EVENTSEL_INT;
 
-	cpuc->pebs_enabled |= 1ULL << hwc->idx;
+	/* When weight is requested enable LL instead of normal PEBS */
+	if ((event->attr.sample_type & PERF_SAMPLE_WEIGHT) &&
+		is_memory_lat_event(event))
+		cpuc->pebs_enabled |= 1ULL << (32 + hwc->idx);
+	else
+		cpuc->pebs_enabled |= 1ULL << hwc->idx;
 }
 
 void intel_pmu_pebs_disable(struct perf_event *event)
@@ -474,7 +505,11 @@ void intel_pmu_pebs_disable(struct perf_event *event)
 	struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
 	struct hw_perf_event *hwc = &event->hw;
 
-	cpuc->pebs_enabled &= ~(1ULL << hwc->idx);
+	if ((event->attr.sample_type & PERF_SAMPLE_WEIGHT) &&
+		is_memory_lat_event(event))
+		cpuc->pebs_enabled &= ~(1ULL << (32 + hwc->idx));
+	else
+		cpuc->pebs_enabled &= ~(1ULL << hwc->idx);
 	if (cpuc->enabled)
 		wrmsrl(MSR_IA32_PEBS_ENABLE, cpuc->pebs_enabled);
 
@@ -627,6 +662,14 @@ static void __intel_pmu_pebs_event(struct perf_event *event,
 		x86_pmu.intel_cap.pebs_format >= 2)
 		data.addr = ((struct pebs_record_v2 *)pebs)->nhm.dla;
 
+	if ((event->attr.sample_type & PERF_SAMPLE_WEIGHT) &&
+	    x86_pmu.intel_cap.pebs_format >= 2) {
+		data.weight = ((struct pebs_record_v2 *)pebs)->tsx_tuning & 
+				0xffffffff;
+		if (!data.weight)
+			data.weight = ((struct pebs_record_v2 *)pebs)->nhm.lat;
+	}
+
 	if (has_branch_stack(event))
 		data.br_stack = &cpuc->lbr_stack;
 
-- 
1.7.7.6


^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [PATCH 20/31] perf, tools: Add support for weight
  2012-09-28  4:31 perf PMU support for Haswell Andi Kleen
                   ` (18 preceding siblings ...)
  2012-09-28  4:31 ` [PATCH 19/31] perf, x86: Support weight samples for PEBS Andi Kleen
@ 2012-09-28  4:31 ` Andi Kleen
  2012-09-28  4:31 ` [PATCH 21/31] perf, tools: Handle XBEGIN like a jump Andi Kleen
                   ` (10 subsequent siblings)
  30 siblings, 0 replies; 58+ messages in thread
From: Andi Kleen @ 2012-09-28  4:31 UTC (permalink / raw)
  To: linux-kernel; +Cc: x86, a.p.zijlstra, eranian, acme, Andi Kleen

From: Andi Kleen <ak@linux.intel.com>

perf record has a new option -W that enables weightened sampling.

Add sorting support in top/report for the average weight per sample and the
total weight sum. This allows to both compare relative cost per event
and the total cost over the measurement period.

Add the necessary glue to perf report, record and the library.

Signed-off-by: Andi Kleen <ak@linux.intel.com>
---
 tools/perf/Documentation/perf-record.txt |    6 +++
 tools/perf/builtin-annotate.c            |    2 +-
 tools/perf/builtin-diff.c                |    7 ++--
 tools/perf/builtin-record.c              |    2 +
 tools/perf/builtin-report.c              |    7 ++--
 tools/perf/builtin-top.c                 |    5 ++-
 tools/perf/perf.h                        |    1 +
 tools/perf/util/event.h                  |    1 +
 tools/perf/util/evsel.c                  |   10 ++++++
 tools/perf/util/hist.c                   |   20 ++++++++---
 tools/perf/util/hist.h                   |    8 +++-
 tools/perf/util/session.c                |    3 ++
 tools/perf/util/sort.c                   |   51 +++++++++++++++++++++++++++++-
 tools/perf/util/sort.h                   |    3 ++
 14 files changed, 108 insertions(+), 18 deletions(-)

diff --git a/tools/perf/Documentation/perf-record.txt b/tools/perf/Documentation/perf-record.txt
index b38a1f9..4930654 100644
--- a/tools/perf/Documentation/perf-record.txt
+++ b/tools/perf/Documentation/perf-record.txt
@@ -182,6 +182,12 @@ is enabled for all the sampling events. The sampled branch type is the same for
 The various filters must be specified as a comma separated list: --branch-filter any_ret,u,k
 Note that this feature may not be available on all processors.
 
+-W::
+--weight::
+Enable weightened sampling. When the event supports an additional weight per sample scale
+the histogram by this weight. This currently works for TSX abort events and some memory events
+in precise mode on modern Intel CPUs.
+
 SEE ALSO
 --------
 linkperf:perf-stat[1], linkperf:perf-list[1]
diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c
index 67522cf..c522367 100644
--- a/tools/perf/builtin-annotate.c
+++ b/tools/perf/builtin-annotate.c
@@ -62,7 +62,7 @@ static int perf_evsel__add_sample(struct perf_evsel *evsel,
 		return 0;
 	}
 
-	he = __hists__add_entry(&evsel->hists, al, NULL, 1);
+	he = __hists__add_entry(&evsel->hists, al, NULL, 1, 1);
 	if (he == NULL)
 		return -ENOMEM;
 
diff --git a/tools/perf/builtin-diff.c b/tools/perf/builtin-diff.c
index d29d350..04c1d21 100644
--- a/tools/perf/builtin-diff.c
+++ b/tools/perf/builtin-diff.c
@@ -30,9 +30,10 @@ struct perf_diff {
 };
 
 static int hists__add_entry(struct hists *self,
-			    struct addr_location *al, u64 period)
+			    struct addr_location *al, u64 period,
+			    u64 weight)
 {
-	if (__hists__add_entry(self, al, NULL, period) != NULL)
+	if (__hists__add_entry(self, al, NULL, period, weight) != NULL)
 		return 0;
 	return -ENOMEM;
 }
@@ -56,7 +57,7 @@ static int diff__process_sample_event(struct perf_tool *tool,
 	if (al.filtered || al.sym == NULL)
 		return 0;
 
-	if (hists__add_entry(&session->hists, &al, sample->period)) {
+	if (hists__add_entry(&session->hists, &al, sample->period, sample->weight)) {
 		pr_warning("problem incrementing symbol period, skipping event\n");
 		return -1;
 	}
diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
index e851bf2..4dbdc4e 100644
--- a/tools/perf/builtin-record.c
+++ b/tools/perf/builtin-record.c
@@ -836,6 +836,8 @@ const struct option record_options[] = {
 	OPT_CALLBACK('j', "branch-filter", &record.opts.branch_stack,
 		     "branch filter mask", "branch stack filter modes",
 		     parse_branch_stack),
+	OPT_BOOLEAN('W', "weight", &record.opts.sample_weight,
+		    "sample by weight (on special events only)"),
 	OPT_END()
 };
 
diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c
index 8231cb1..2c73578 100644
--- a/tools/perf/builtin-report.c
+++ b/tools/perf/builtin-report.c
@@ -88,7 +88,7 @@ static int perf_report__add_branch_hist_entry(struct perf_tool *tool,
 		 * and not events sampled. Thus we use a pseudo period of 1.
 		 */
 		he = __hists__add_branch_entry(&evsel->hists, al, parent,
-				&bi[i], 1);
+				&bi[i], 1, 1);
 		if (he) {
 			struct annotation *notes;
 			err = -ENOMEM;
@@ -146,7 +146,8 @@ static int perf_evsel__add_hist_entry(struct perf_evsel *evsel,
 			return err;
 	}
 
-	he = __hists__add_entry(&evsel->hists, al, parent, sample->period);
+	he = __hists__add_entry(&evsel->hists, al, parent, sample->period,
+					sample->weight);
 	if (he == NULL)
 		return -ENOMEM;
 
@@ -595,7 +596,7 @@ int cmd_report(int argc, const char **argv, const char *prefix __used)
 	OPT_STRING('s', "sort", &sort_order, "key[,key2...]",
 		   "sort by key(s): pid, comm, dso, symbol, parent, dso_to,"
 		   " dso_from, symbol_to, symbol_from, mispredict, srcline,"
-		   " abort, intx"),
+		   " abort, intx,  weight, global_weight"),
 	OPT_BOOLEAN(0, "showcpuutilization", &symbol_conf.show_cpu_utilization,
 		    "Show sample percentage for different cpu modes"),
 	OPT_STRING('p', "parent", &parent_pattern, "regex",
diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c
index 5ab2188..ee37ddc 100644
--- a/tools/perf/builtin-top.c
+++ b/tools/perf/builtin-top.c
@@ -269,7 +269,8 @@ static struct hist_entry *perf_evsel__add_hist_entry(struct perf_evsel *evsel,
 {
 	struct hist_entry *he;
 
-	he = __hists__add_entry(&evsel->hists, al, NULL, sample->period);
+	he = __hists__add_entry(&evsel->hists, al, NULL, sample->period,
+				sample->weight);
 	if (he == NULL)
 		return NULL;
 
@@ -1229,7 +1230,7 @@ int cmd_top(int argc, const char **argv, const char *prefix __used)
 	OPT_STRING('s', "sort", &sort_order, "key[,key2...]",
 		   "sort by key(s): pid, comm, dso, symbol, parent, dso_to,"
 		   " dso_from, symbol_to, symbol_from, mispredict, srcline,"
-		   " abort, intx"),
+		   " abort, intx, weight, global_weight"),
 	OPT_BOOLEAN('n', "show-nr-samples", &symbol_conf.show_nr_samples,
 		    "Show a column with the number of samples"),
 	OPT_CALLBACK_DEFAULT('G', "call-graph", &top, "output_type,min_percent, call_order",
diff --git a/tools/perf/perf.h b/tools/perf/perf.h
index 9147ffc..a98dcf2 100644
--- a/tools/perf/perf.h
+++ b/tools/perf/perf.h
@@ -222,6 +222,7 @@ struct perf_record_opts {
 	bool	     pipe_output;
 	bool	     raw_samples;
 	bool	     sample_address;
+	bool	     sample_weight;
 	bool	     sample_time;
 	bool	     sample_id_all_missing;
 	bool	     exclude_guest_missing;
diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h
index d84870b..5ac79f3 100644
--- a/tools/perf/util/event.h
+++ b/tools/perf/util/event.h
@@ -77,6 +77,7 @@ struct perf_sample {
 	u64 id;
 	u64 stream_id;
 	u64 period;
+	u64 weight;
 	u32 cpu;
 	u32 raw_size;
 	void *raw_data;
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
index cda3805..ff084b0 100644
--- a/tools/perf/util/evsel.c
+++ b/tools/perf/util/evsel.c
@@ -377,6 +377,9 @@ void perf_evsel__config(struct perf_evsel *evsel, struct perf_record_opts *opts,
 		attr->mmap_data = track;
 	}
 
+	if (opts->sample_weight)
+		attr->sample_type	|= PERF_SAMPLE_WEIGHT;
+
 	if (opts->call_graph)
 		attr->sample_type	|= PERF_SAMPLE_CALLCHAIN;
 
@@ -755,6 +758,7 @@ int perf_evsel__parse_sample(struct perf_evsel *evsel, union perf_event *event,
 	data->cpu = data->pid = data->tid = -1;
 	data->stream_id = data->id = data->time = -1ULL;
 	data->period = 1;
+	data->weight = 0;
 
 	if (event->header.type != PERF_RECORD_SAMPLE) {
 		if (!evsel->attr.sample_id_all)
@@ -826,6 +830,12 @@ int perf_evsel__parse_sample(struct perf_evsel *evsel, union perf_event *event,
 		array++;
 	}
 
+	data->weight = 0;
+	if (type & PERF_SAMPLE_WEIGHT) {
+		data->weight = *array;
+		array++;
+	}
+
 	if (type & PERF_SAMPLE_READ) {
 		fprintf(stderr, "PERF_SAMPLE_READ is unsupported for now\n");
 		return -1;
diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c
index f247ef2..566badc 100644
--- a/tools/perf/util/hist.c
+++ b/tools/perf/util/hist.c
@@ -236,13 +236,17 @@ static u8 symbol__parent_filter(const struct symbol *parent)
 static struct hist_entry *add_hist_entry(struct hists *hists,
 				      struct hist_entry *entry,
 				      struct addr_location *al,
-				      u64 period)
+				      u64 period,
+				      u64 weight)
 {
 	struct rb_node **p;
 	struct rb_node *parent = NULL;
 	struct hist_entry *he;
 	int cmp;
 
+	if (weight == 0)
+		weight = 1;
+
 	pthread_mutex_lock(&hists->lock);
 
 	p = &hists->entries_in->rb_node;
@@ -255,7 +259,8 @@ static struct hist_entry *add_hist_entry(struct hists *hists,
 
 		if (!cmp) {
 			he->period += period;
-			++he->nr_events;
+			he->nr_events++;
+			he->weight += weight;
 
 			/* If the map of an existing hist_entry has
 			 * become out-of-date due to an exec() or
@@ -294,7 +299,8 @@ struct hist_entry *__hists__add_branch_entry(struct hists *self,
 					     struct addr_location *al,
 					     struct symbol *sym_parent,
 					     struct branch_info *bi,
-					     u64 period)
+					     u64 period,
+					     u64 weight)
 {
 	struct hist_entry entry = {
 		.thread	= al->thread,
@@ -311,12 +317,13 @@ struct hist_entry *__hists__add_branch_entry(struct hists *self,
 		.branch_info = bi,
 	};
 
-	return add_hist_entry(self, &entry, al, period);
+	return add_hist_entry(self, &entry, al, period, weight);
 }
 
 struct hist_entry *__hists__add_entry(struct hists *self,
 				      struct addr_location *al,
-				      struct symbol *sym_parent, u64 period)
+				      struct symbol *sym_parent, u64 period,
+				      u64 weight)
 {
 	struct hist_entry entry = {
 		.thread	= al->thread,
@@ -332,7 +339,7 @@ struct hist_entry *__hists__add_entry(struct hists *self,
 		.filtered = symbol__parent_filter(sym_parent),
 	};
 
-	return add_hist_entry(self, &entry, al, period);
+	return add_hist_entry(self, &entry, al, period, weight);
 }
 
 int64_t
@@ -396,6 +403,7 @@ static bool hists__collapse_insert_entry(struct hists *hists __used,
 		if (!cmp) {
 			iter->period += he->period;
 			iter->nr_events += he->nr_events;
+			iter->weight += he->weight;
 			if (symbol_conf.use_callchain) {
 				callchain_cursor_reset(&callchain_cursor);
 				callchain_merge(&callchain_cursor,
diff --git a/tools/perf/util/hist.h b/tools/perf/util/hist.h
index 71837aa..a02d068 100644
--- a/tools/perf/util/hist.h
+++ b/tools/perf/util/hist.h
@@ -50,6 +50,8 @@ enum hist_column {
 	HISTC_DSO_FROM,
 	HISTC_DSO_TO,
 	HISTC_SRCLINE,
+	HISTC_WEIGHT,
+	HISTC_GLOBAL_WEIGHT,
 	HISTC_NR_COLS, /* Last entry */
 };
 
@@ -74,7 +76,8 @@ struct hists {
 
 struct hist_entry *__hists__add_entry(struct hists *self,
 				      struct addr_location *al,
-				      struct symbol *parent, u64 period);
+				      struct symbol *parent, u64 period,
+				      u64 weight);
 int64_t hist_entry__cmp(struct hist_entry *left, struct hist_entry *right);
 int64_t hist_entry__collapse(struct hist_entry *left, struct hist_entry *right);
 int hist_entry__snprintf(struct hist_entry *self, char *bf, size_t size,
@@ -85,7 +88,8 @@ struct hist_entry *__hists__add_branch_entry(struct hists *self,
 					     struct addr_location *al,
 					     struct symbol *sym_parent,
 					     struct branch_info *bi,
-					     u64 period);
+					     u64 period,
+					     u64 weight);
 
 void hists__output_resort(struct hists *self);
 void hists__output_resort_threaded(struct hists *hists);
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
index 2437fb0..84f000c 100644
--- a/tools/perf/util/session.c
+++ b/tools/perf/util/session.c
@@ -916,6 +916,9 @@ static void dump_sample(struct perf_session *session, union perf_event *event,
 
 	if (sample_type & PERF_SAMPLE_BRANCH_STACK)
 		branch_stack__printf(sample);
+
+	if (sample_type & PERF_SAMPLE_WEIGHT)
+		printf("... weight: %" PRIu64 "\n", sample->weight);
 }
 
 static struct machine *
diff --git a/tools/perf/util/sort.c b/tools/perf/util/sort.c
index 596b82c..0fcbbcd 100644
--- a/tools/perf/util/sort.c
+++ b/tools/perf/util/sort.c
@@ -516,6 +516,49 @@ struct sort_entry sort_intx = {
 	.se_width_idx	= HISTC_INTX,
 };
 
+static u64 he_weight(struct hist_entry *he)
+{
+	return he->nr_events ? he->weight / he->nr_events : 0;
+}
+
+static int64_t
+sort__weight_cmp(struct hist_entry *left, struct hist_entry *right)
+{
+	return he_weight(left) - he_weight(right);
+}
+
+static int hist_entry__weight_snprintf(struct hist_entry *self, char *bf,
+				    size_t size, unsigned int width)
+{
+	return repsep_snprintf(bf, size, "%-*llu", width, he_weight(self));
+}
+
+struct sort_entry sort_weight = {
+	.se_header	= "Weight",
+	.se_cmp		= sort__weight_cmp,
+	.se_snprintf	= hist_entry__weight_snprintf,
+	.se_width_idx	= HISTC_WEIGHT,
+};
+
+static int64_t
+sort__global_weight_cmp(struct hist_entry *left, struct hist_entry *right)
+{
+	return left->weight - right->weight;
+}
+
+static int hist_entry__global_weight_snprintf(struct hist_entry *self, char *bf,
+					      size_t size, unsigned int width)
+{
+	return repsep_snprintf(bf, size, "%-*llu", width, self->weight);
+}
+
+struct sort_entry sort_global_weight = {
+	.se_header	= "Total weight",
+	.se_cmp		= sort__global_weight_cmp,
+	.se_snprintf	= hist_entry__global_weight_snprintf,
+	.se_width_idx	= HISTC_GLOBAL_WEIGHT,
+};
+
 struct sort_dimension {
 	const char		*name;
 	struct sort_entry	*entry;
@@ -538,7 +581,9 @@ static struct sort_dimension sort_dimensions[] = {
 	DIM(SORT_MISPREDICT, "mispredict", sort_mispredict),
 	DIM(SORT_SRCLINE, "srcline", sort_srcline),
 	DIM(SORT_ABORT, "abort", sort_abort),
-	DIM(SORT_INTX, "intx", sort_intx)
+	DIM(SORT_INTX, "intx", sort_intx),
+	DIM(SORT_WEIGHT, "weight", sort_weight),
+	DIM(SORT_GLOBAL_WEIGHT, "global_weight", sort_global_weight),
 };
 
 int sort_dimension__add(const char *tok)
@@ -595,6 +640,10 @@ int sort_dimension__add(const char *tok)
 				sort__first_dimension = SORT_INTX;
 			else if (!strcmp(sd->name, "abort"))
 				sort__first_dimension = SORT_ABORT;
+			else if (!strcmp(sd->name, "weight"))
+				sort__first_dimension = SORT_WEIGHT;
+			else if (!strcmp(sd->name, "global_weight"))
+				sort__first_dimension = SORT_GLOBAL_WEIGHT;
 		}
 
 		list_add_tail(&sd->entry->list, &hist_entry__sort_list);
diff --git a/tools/perf/util/sort.h b/tools/perf/util/sort.h
index fdb033f..8b2c5ae 100644
--- a/tools/perf/util/sort.h
+++ b/tools/perf/util/sort.h
@@ -60,6 +60,7 @@ struct hist_entry {
 	struct map_symbol	ms;
 	struct thread		*thread;
 	u64			ip;
+	u64			weight;
 	s32			cpu;
 	u32			nr_events;
 
@@ -97,6 +98,8 @@ enum sort_type {
 	SORT_SRCLINE,
 	SORT_ABORT,
 	SORT_INTX,
+	SORT_WEIGHT,
+	SORT_GLOBAL_WEIGHT,
 };
 
 /*
-- 
1.7.7.6


^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [PATCH 21/31] perf, tools: Handle XBEGIN like a jump
  2012-09-28  4:31 perf PMU support for Haswell Andi Kleen
                   ` (19 preceding siblings ...)
  2012-09-28  4:31 ` [PATCH 20/31] perf, tools: Add support for weight Andi Kleen
@ 2012-09-28  4:31 ` Andi Kleen
  2012-09-28  4:31 ` [PATCH 22/31] perf, core: Define generic hardware transaction events Andi Kleen
                   ` (9 subsequent siblings)
  30 siblings, 0 replies; 58+ messages in thread
From: Andi Kleen @ 2012-09-28  4:31 UTC (permalink / raw)
  To: linux-kernel; +Cc: x86, a.p.zijlstra, eranian, acme, Andi Kleen

From: Andi Kleen <ak@linux.intel.com>

So that the browser still shows the abort label

Signed-off-by: Andi Kleen <ak@linux.intel.com>
---
 tools/perf/util/annotate.c |    2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c
index 3a282c0..bf549cd 100644
--- a/tools/perf/util/annotate.c
+++ b/tools/perf/util/annotate.c
@@ -399,6 +399,8 @@ static struct ins instructions[] = {
 	{ .name = "testb", .ops  = &mov_ops, },
 	{ .name = "testl", .ops  = &mov_ops, },
 	{ .name = "xadd",  .ops  = &mov_ops, },
+	{ .name = "xbeginl", .ops  = &jump_ops, },
+	{ .name = "xbeginq", .ops  = &jump_ops, },
 };
 
 static int ins__cmp(const void *name, const void *insp)
-- 
1.7.7.6


^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [PATCH 22/31] perf, core: Define generic hardware transaction events
  2012-09-28  4:31 perf PMU support for Haswell Andi Kleen
                   ` (20 preceding siblings ...)
  2012-09-28  4:31 ` [PATCH 21/31] perf, tools: Handle XBEGIN like a jump Andi Kleen
@ 2012-09-28  4:31 ` Andi Kleen
  2012-09-28  9:33   ` Peter Zijlstra
  2012-09-28  4:31 ` [PATCH 23/31] perf, tools: Add support for generic transaction events to perf userspace Andi Kleen
                   ` (8 subsequent siblings)
  30 siblings, 1 reply; 58+ messages in thread
From: Andi Kleen @ 2012-09-28  4:31 UTC (permalink / raw)
  To: linux-kernel; +Cc: x86, a.p.zijlstra, eranian, acme, Andi Kleen

From: Andi Kleen <ak@linux.intel.com>

For tuning and debugging hardware transactional memory it is very
important to have hardware counter support.

This patch adds a simple and hopefully generic set of hardware events
for transactional memory and lock elision.

It is based on the TSX PMU support because I don't have any
information on other CPU's HTM support.

There are start, commit and abort events for transactions and
for lock elision.

The abort events are qualified by a generic abort reason that should
be roughly applicable to a wide range of memory transaction systems:

capacity for the buffering capacity
conflict for a dynamic conflict between CPUs
all      for all aborts. On TSX this can be precisely sampled.

We need to split the events into general transaction events and lock
elision events. Architecturs with HTM but no lock elision would only
use the first set.

Implementation for Haswell in a followon patch.

Signed-off-by: Andi Kleen <ak@linux.intel.com>
---
 arch/x86/kernel/cpu/perf_event.c |   36 ++++++++++++++++++++++++++++++++++++
 arch/x86/kernel/cpu/perf_event.h |    4 ++++
 include/linux/perf_event.h       |   25 +++++++++++++++++++++++++
 3 files changed, 65 insertions(+), 0 deletions(-)

diff --git a/arch/x86/kernel/cpu/perf_event.c b/arch/x86/kernel/cpu/perf_event.c
index 87c2ab0..cee8f80 100644
--- a/arch/x86/kernel/cpu/perf_event.c
+++ b/arch/x86/kernel/cpu/perf_event.c
@@ -53,6 +53,13 @@ u64 __read_mostly hw_cache_extra_regs
 				[PERF_COUNT_HW_CACHE_RESULT_MAX];
 
 /*
+ * Generalized transactional memory event table.
+ */
+u64 __read_mostly hw_transaction_event_ids
+				[PERF_COUNT_HW_TRANSACTION_MAX]
+				[PERF_COUNT_HW_ABORT_MAX];
+
+/*
  * Propagate event elapsed time into the generic event.
  * Can only be executed on the CPU where the event is active.
  * Returns the delta events processed.
@@ -285,6 +292,31 @@ set_ext_hw_attr(struct hw_perf_event *hwc, struct perf_event *event)
 	return x86_pmu_extra_regs(val, event);
 }
 
+static int
+set_hw_transaction_attr(struct hw_perf_event *hwc, struct perf_event *event)
+{
+	struct perf_event_attr *attr = &event->attr;
+	u64 config, val;
+	unsigned int op, reason;
+
+	config = attr->config;
+	op = config & 0xff;
+	if (op >= PERF_COUNT_HW_TRANSACTION_MAX)
+		return -EINVAL;
+	reason = (config >> 8) & 0xff;
+	if (reason >= PERF_COUNT_HW_ABORT_MAX)
+		return -EINVAL;
+	if (config >> 16)
+		return -EINVAL;
+	val = hw_transaction_event_ids[config][reason];
+	if (val == 0)
+		return -ENOENT;
+	if (val == -1)
+		return -EINVAL;
+	hwc->config |= val;
+	return 0;
+}
+
 int x86_setup_perfctr(struct perf_event *event)
 {
 	struct perf_event_attr *attr = &event->attr;
@@ -312,6 +344,9 @@ int x86_setup_perfctr(struct perf_event *event)
 	if (attr->type == PERF_TYPE_HW_CACHE)
 		return set_ext_hw_attr(hwc, event);
 
+	if (attr->type == PERF_TYPE_HW_TRANSACTION)
+		return set_hw_transaction_attr(hwc, event);
+
 	if (attr->config >= x86_pmu.max_events)
 		return -EINVAL;
 
@@ -1547,6 +1582,7 @@ static int x86_pmu_event_init(struct perf_event *event)
 	case PERF_TYPE_RAW:
 	case PERF_TYPE_HARDWARE:
 	case PERF_TYPE_HW_CACHE:
+	case PERF_TYPE_HW_TRANSACTION:
 		break;
 
 	default:
diff --git a/arch/x86/kernel/cpu/perf_event.h b/arch/x86/kernel/cpu/perf_event.h
index 724a141..6a8730e 100644
--- a/arch/x86/kernel/cpu/perf_event.h
+++ b/arch/x86/kernel/cpu/perf_event.h
@@ -452,6 +452,10 @@ extern u64 __read_mostly hw_cache_extra_regs
 				[PERF_COUNT_HW_CACHE_OP_MAX]
 				[PERF_COUNT_HW_CACHE_RESULT_MAX];
 
+extern u64 __read_mostly hw_transaction_event_ids
+				[PERF_COUNT_HW_TRANSACTION_MAX]
+				[PERF_COUNT_HW_ABORT_MAX];
+
 u64 x86_perf_event_update(struct perf_event *event);
 
 static inline int x86_pmu_addr_offset(int index)
diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h
index c488ae2..1867bed 100644
--- a/include/linux/perf_event.h
+++ b/include/linux/perf_event.h
@@ -32,6 +32,7 @@ enum perf_type_id {
 	PERF_TYPE_HW_CACHE			= 3,
 	PERF_TYPE_RAW				= 4,
 	PERF_TYPE_BREAKPOINT			= 5,
+	PERF_TYPE_HW_TRANSACTION		= 6,
 
 	PERF_TYPE_MAX,				/* non-ABI */
 };
@@ -94,6 +95,30 @@ enum perf_hw_cache_op_result_id {
 };
 
 /*
+ * Transactional memory related events:
+ * { op, reason } (8 bits each)
+ * Only aborts have a reason.
+ */
+enum perf_hw_transaction_op_id {
+	PERF_COUNT_HW_TRANSACTION_START		= 0,
+	PERF_COUNT_HW_TRANSACTION_COMMIT	= 1,
+	PERF_COUNT_HW_TRANSACTION_ABORT         = 2, /* qualified by reason */
+	PERF_COUNT_HW_ELISION_START		= 3,
+	PERF_COUNT_HW_ELISION_COMMIT		= 4,
+	PERF_COUNT_HW_ELISION_ABORT		= 5, /* qualified by reason */
+
+	PERF_COUNT_HW_TRANSACTION_MAX,		/* non-ABI */
+};
+
+enum perf_transaction_abort_reason_id {
+	PERF_COUNT_HW_ABORT_ALL			= 0, /* all aborts */
+	PERF_COUNT_HW_ABORT_CONFLICT		= 1, /* conflict with other CPU */
+	PERF_COUNT_HW_ABORT_CAPACITY		= 2, /* abort due to capacity */
+
+	PERF_COUNT_HW_ABORT_MAX,		/* non-ABI */
+};
+
+/*
  * Special "software" events provided by the kernel, even if the hardware
  * does not support performance events. These events measure various
  * physical and sw events of the kernel (and allow the profiling of them as
-- 
1.7.7.6


^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [PATCH 23/31] perf, tools: Add support for generic transaction events to perf userspace
  2012-09-28  4:31 perf PMU support for Haswell Andi Kleen
                   ` (21 preceding siblings ...)
  2012-09-28  4:31 ` [PATCH 22/31] perf, core: Define generic hardware transaction events Andi Kleen
@ 2012-09-28  4:31 ` Andi Kleen
  2012-09-28  4:31 ` [PATCH 24/31] perf, x86: Add the Haswell implementation of the generic transaction events Andi Kleen
                   ` (7 subsequent siblings)
  30 siblings, 0 replies; 58+ messages in thread
From: Andi Kleen @ 2012-09-28  4:31 UTC (permalink / raw)
  To: linux-kernel; +Cc: x86, a.p.zijlstra, eranian, acme, Andi Kleen

From: Andi Kleen <ak@linux.intel.com>

Add the generic transaction events with aliases to the parser, lexer
and the reverse map code.

Signed-off-by: Andi Kleen <ak@linux.intel.com>
---
 tools/perf/util/evsel.c        |   40 ++++++++++++++++++++++++++++++++++++++++
 tools/perf/util/parse-events.c |   24 ++++++++++++++++++++++++
 tools/perf/util/parse-events.l |   19 ++++++++++++++++++-
 tools/perf/util/parse-events.y |    4 ++--
 4 files changed, 84 insertions(+), 3 deletions(-)

diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
index ff084b0..8790069 100644
--- a/tools/perf/util/evsel.c
+++ b/tools/perf/util/evsel.c
@@ -288,6 +288,42 @@ static int perf_evsel__hw_cache_name(struct perf_evsel *evsel, char *bf, size_t
 	return ret + perf_evsel__add_modifiers(evsel, bf + ret, size - ret);
 }
 
+static const char *transaction_name[] = {
+ [PERF_COUNT_HW_TRANSACTION_START]  = "transaction-start",
+ [PERF_COUNT_HW_TRANSACTION_COMMIT] = "transaction-commit",
+ [PERF_COUNT_HW_TRANSACTION_ABORT]  = "transaction-abort",
+ [PERF_COUNT_HW_ELISION_START]      = "elision-start",
+ [PERF_COUNT_HW_ELISION_COMMIT]     = "elision-commit",
+ [PERF_COUNT_HW_ELISION_ABORT]      = "elision-abort",
+};
+
+static const char *transaction_reason[] = {
+ [PERF_COUNT_HW_ABORT_ALL]          = "all",
+ [PERF_COUNT_HW_ABORT_CONFLICT]     = "conflict",
+ [PERF_COUNT_HW_ABORT_CAPACITY]     = "capacity",
+};
+
+static int perf_evsel__transaction_name(struct perf_evsel *evsel, char *bf,
+					size_t size)
+{
+	u64 config = evsel->attr.config;
+	u8 name = config & 0xff, reason = (config >> 8) & 0xff;
+
+	if (name < PERF_COUNT_HW_TRANSACTION_MAX &&
+	    reason < PERF_COUNT_HW_ABORT_MAX) {
+		const char *sep = "", *rtxt = "";
+		if (name == PERF_COUNT_HW_TRANSACTION_ABORT ||
+		    name == PERF_COUNT_HW_ELISION_ABORT) {
+			sep = "-";
+			rtxt = transaction_reason[reason];
+		}
+		return scnprintf(bf, size, "%s%s%s", transaction_name[name],
+						     sep, rtxt);
+	}
+
+	return scnprintf(bf, size, "invalid-transaction");
+}
+
 static int perf_evsel__raw_name(struct perf_evsel *evsel, char *bf, size_t size)
 {
 	int ret = scnprintf(bf, size, "raw 0x%" PRIx64, evsel->attr.config);
@@ -326,6 +362,10 @@ const char *perf_evsel__name(struct perf_evsel *evsel)
 		perf_evsel__bp_name(evsel, bf, sizeof(bf));
 		break;
 
+	case PERF_TYPE_HW_TRANSACTION:
+		perf_evsel__transaction_name(evsel, bf, sizeof(bf));
+		break;
+
 	default:
 		scnprintf(bf, sizeof(bf), "%s", "unknown attr type");
 		break;
diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c
index 5668ca6..e24a490 100644
--- a/tools/perf/util/parse-events.c
+++ b/tools/perf/util/parse-events.c
@@ -110,6 +110,20 @@ static struct event_symbol event_symbols_sw[PERF_COUNT_SW_MAX] = {
 	},
 };
 
+static struct event_symbol event_symbols_txn[] = {
+	{ .symbol = "transaction-start",          .alias = "tx-start"    },
+	{ .symbol = "transaction-commit",         .alias = "tx-commit"   },
+	{ .symbol = "transaction-abort-all",      .alias = "tx-abort"    },
+	{ .symbol = "transaction-abort-capacity", .alias = "tx-capacity" },
+	{ .symbol = "transaction-abort-conflict", .alias = "tx-conflict" },
+	{ .symbol = "elision-start",              .alias = "le-start"    },
+	{ .symbol = "elision-commit",             .alias = "le-commit"   },
+	{ .symbol = "elision-abort-all",          .alias = "le-abort"    },
+	{ .symbol = "elision-abort-capacity",     .alias = "le-capacity" },
+	{ .symbol = "elision-abort-conflict",     .alias = "le-conflict" },
+
+};
+
 #define __PERF_EVENT_FIELD(config, name) \
 	((config & PERF_EVENT_##name##_MASK) >> PERF_EVENT_##name##_SHIFT)
 
@@ -232,6 +246,9 @@ const char *event_type(int type)
 	case PERF_TYPE_HW_CACHE:
 		return "hardware-cache";
 
+	case PERF_TYPE_HW_TRANSACTION:
+		return "hardware-transaction";
+
 	default:
 		break;
 	}
@@ -800,6 +817,7 @@ static const char * const event_type_descriptors[] = {
 	"Hardware cache event",
 	"Raw hardware event descriptor",
 	"Hardware breakpoint",
+	"Hardware transaction event",
 };
 
 /*
@@ -909,6 +927,9 @@ void print_events_type(u8 type)
 {
 	if (type == PERF_TYPE_SOFTWARE)
 		__print_events_type(type, event_symbols_sw, PERF_COUNT_SW_MAX);
+	else if (type == PERF_TYPE_HW_TRANSACTION)
+		__print_events_type(type, event_symbols_txn,
+				    ARRAY_SIZE(event_symbols_txn));
 	else
 		__print_events_type(type, event_symbols_hw, PERF_COUNT_HW_MAX);
 }
@@ -984,6 +1005,9 @@ void print_events(const char *event_glob)
 
 	print_hwcache_events(event_glob);
 
+	print_symbol_events(event_glob, PERF_TYPE_HW_TRANSACTION,
+			    event_symbols_txn, ARRAY_SIZE(event_symbols_txn));
+
 	if (event_glob != NULL)
 		return;
 
diff --git a/tools/perf/util/parse-events.l b/tools/perf/util/parse-events.l
index 96ab100..2c9dd04 100644
--- a/tools/perf/util/parse-events.l
+++ b/tools/perf/util/parse-events.l
@@ -56,7 +56,8 @@ static int sym(yyscan_t scanner, int type, int config)
 	YYSTYPE *yylval = parse_events_get_lval(scanner);
 
 	yylval->num = (type << 16) + config;
-	return type == PERF_TYPE_HARDWARE ? PE_VALUE_SYM_HW : PE_VALUE_SYM_SW;
+	return type == PERF_TYPE_HARDWARE || type == PERF_TYPE_HW_TRANSACTION ?
+	       PE_VALUE_SYM_HW : PE_VALUE_SYM_SW;
 }
 
 static int term(yyscan_t scanner, int type)
@@ -67,6 +68,11 @@ static int term(yyscan_t scanner, int type)
 	return PE_TERM;
 }
 
+#define txn(t)		sym(yyscanner, PERF_TYPE_HW_TRANSACTION, \
+                            PERF_COUNT_HW_##t)
+#define txn_abort(t, a) sym(yyscanner, PERF_TYPE_HW_TRANSACTION, \
+			    PERF_COUNT_HW_##t | ((PERF_COUNT_HW_ABORT_##a)<<8))
+
 %}
 
 %x mem
@@ -127,6 +133,17 @@ speculative-read|speculative-load	|
 refs|Reference|ops|access		|
 misses|miss				{ return str(yyscanner, PE_NAME_CACHE_OP_RESULT); }
 
+transaction-start|tx-start		{ return txn(TRANSACTION_START);  }
+transaction-commit|tx-commit		{ return txn(TRANSACTION_COMMIT); }
+transaction-abort-all|tx-aborts?	{ return txn_abort(TRANSACTION_ABORT, ALL); }
+transaction-abort-conflict|tx-conflict  { return txn_abort(TRANSACTION_ABORT, CONFLICT); }
+transaction-abort-capacity|tx-capacity  { return txn_abort(TRANSACTION_ABORT, CAPACITY); }
+elision-start|le-start			{ return txn(ELISION_START);  }
+elision-commit|le-commit		{ return txn(ELISION_COMMIT); }
+elision-abort-all|le-aborts?		{ return txn_abort(ELISION_ABORT, ALL); }
+elision-abort-conflict|le-conflict	{ return txn_abort(ELISION_ABORT, CONFLICT); }
+elision-abort-capacity|le-capacity	{ return txn_abort(ELISION_ABORT, CAPACITY); }
+
 	/*
 	 * These are event config hardcoded term names to be specified
 	 * within xxx/.../ syntax. So far we dont clash with other names,
diff --git a/tools/perf/util/parse-events.y b/tools/perf/util/parse-events.y
index 2bc5fbf..6485eb3 100644
--- a/tools/perf/util/parse-events.y
+++ b/tools/perf/util/parse-events.y
@@ -122,7 +122,7 @@ value_sym '/' event_config '/'
 	struct parse_events_data__events *data = _data;
 	struct list_head *list = NULL;
 	int type = $1 >> 16;
-	int config = $1 & 255;
+	int config = $1 & 0xffff;
 
 	ABORT_ON(parse_events_add_numeric(&list, &data->idx,
 					  type, config, $3));
@@ -135,7 +135,7 @@ value_sym sep_slash_dc
 	struct parse_events_data__events *data = _data;
 	struct list_head *list = NULL;
 	int type = $1 >> 16;
-	int config = $1 & 255;
+	int config = $1 & 0xffff;
 
 	ABORT_ON(parse_events_add_numeric(&list, &data->idx,
 					  type, config, NULL));
-- 
1.7.7.6


^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [PATCH 24/31] perf, x86: Add the Haswell implementation of the generic transaction events
  2012-09-28  4:31 perf PMU support for Haswell Andi Kleen
                   ` (22 preceding siblings ...)
  2012-09-28  4:31 ` [PATCH 23/31] perf, tools: Add support for generic transaction events to perf userspace Andi Kleen
@ 2012-09-28  4:31 ` Andi Kleen
  2012-09-28  4:31 ` [PATCH 25/31] perf, tools: Add perf stat --transaction Andi Kleen
                   ` (6 subsequent siblings)
  30 siblings, 0 replies; 58+ messages in thread
From: Andi Kleen @ 2012-09-28  4:31 UTC (permalink / raw)
  To: linux-kernel; +Cc: x86, a.p.zijlstra, eranian, acme, Andi Kleen

From: Andi Kleen <ak@linux.intel.com>

Straight forward table mapping from the generic transactional memory events
to the Haswell TSX events.

One special case is that the abort-all events force PEBS with precise level
two. Without using eventingrip abort IPs are generally useless (you get
something after the abort). So we really want PEBS here for any
sampling. Since it was very unintuitive for users to do this manually
I just made this default.

To do this the mapping table sets a magic flag, that is later checked in
the event setup and forces the precise event. For counting events
PEBS is not forced.

Signed-off-by: Andi Kleen <ak@linux.intel.com>
---
 arch/x86/kernel/cpu/perf_event_intel.c |   47 ++++++++++++++++++++++++++++++++
 1 files changed, 47 insertions(+), 0 deletions(-)

diff --git a/arch/x86/kernel/cpu/perf_event_intel.c b/arch/x86/kernel/cpu/perf_event_intel.c
index 2c4cbf3..be0d3c8 100644
--- a/arch/x86/kernel/cpu/perf_event_intel.c
+++ b/arch/x86/kernel/cpu/perf_event_intel.c
@@ -820,6 +820,38 @@ static __initconst const u64 atom_hw_cache_event_ids
  },
 };
 
+#define FORCE_PEBS (1ULL << 63)
+
+static u64 __initdata hsw_transaction_event_ids
+				[PERF_COUNT_HW_TRANSACTION_MAX]
+				[PERF_COUNT_HW_ABORT_MAX] =
+{
+	/* RTM_RETIRED.START */
+	[ PERF_COUNT_HW_TRANSACTION_START ]  = { 0x1c9 },
+	/* RTM_RETIRED.COMMIT */
+	[ PERF_COUNT_HW_TRANSACTION_COMMIT ] = { 0x2c9 },
+	[ PERF_COUNT_HW_TRANSACTION_ABORT ]  = {
+		/* RTM_RETIRED.ABORTED with pebs */
+		[ PERF_COUNT_HW_ABORT_ALL ]      = 0x4c9|FORCE_PEBS,
+		/* TX_MEM.ABORT_CONFLICT */
+		[ PERF_COUNT_HW_ABORT_CONFLICT ] = 0x154,
+		/* TX_MEM.ABORT_CAPACITY */
+		[ PERF_COUNT_HW_ABORT_CAPACITY ] = 0x254,
+	},
+	/* HLE_RETIRED.START */
+	[ PERF_COUNT_HW_ELISION_START ]  =     { 0x1c8 },
+	/* HLE_RETIRED.COMMIT */
+	[ PERF_COUNT_HW_ELISION_COMMIT ] =     { 0x2c8 },
+	[ PERF_COUNT_HW_ELISION_ABORT ]  = {
+		/* HLE_RETIRED.ABORTED with pebs */
+		[ PERF_COUNT_HW_ABORT_ALL ]      = 0x4c8|FORCE_PEBS,
+		/* TX_MEM.ABORT_CONFLICT */
+		[ PERF_COUNT_HW_ABORT_CONFLICT ] = 0x154,
+		/* TX_MEM.ABORT_CAPACITY */
+		[ PERF_COUNT_HW_ABORT_CAPACITY ] = 0x254,
+	}
+};
+
 static inline bool intel_pmu_needs_lbr_smpl(struct perf_event *event)
 {
 	/* user explicitly requested branch sampling */
@@ -1655,6 +1687,18 @@ static int hsw_hw_config(struct perf_event *event)
 			return -EIO;
 		event->hw.config |= HSW_INTX_CHECKPOINTED;
 	}
+
+	/*
+	 * Sampling transaction abort events work very poorly without
+	 * PEBS. So force it.
+	 */
+	if (event->attr.type == PERF_TYPE_HW_TRANSACTION &&
+	    (event->hw.config & FORCE_PEBS)) {
+		event->hw.config &= ~FORCE_PEBS;
+		if (is_sampling_event(event))
+			event->attr.precise_ip = 2;
+	}
+
 	return 0;
 }
 
@@ -2165,6 +2209,9 @@ __init int intel_pmu_init(void)
 		x86_pmu.hw_config = hsw_hw_config;
 		x86_pmu.get_event_constraints = hsw_get_event_constraints;
 		x86_pmu.memory_lat_events = intel_hsw_memory_latency_events;
+		memcpy(hw_transaction_event_ids, hsw_transaction_event_ids,
+		       sizeof(hsw_transaction_event_ids));
+
 		pr_cont("Haswell events, ");
 		break;
 
-- 
1.7.7.6


^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [PATCH 25/31] perf, tools: Add perf stat --transaction
  2012-09-28  4:31 perf PMU support for Haswell Andi Kleen
                   ` (23 preceding siblings ...)
  2012-09-28  4:31 ` [PATCH 24/31] perf, x86: Add the Haswell implementation of the generic transaction events Andi Kleen
@ 2012-09-28  4:31 ` Andi Kleen
  2012-09-28  4:31 ` [PATCH 26/31] perf, x86: Support for printing PMU state on spurious PMIs Andi Kleen
                   ` (5 subsequent siblings)
  30 siblings, 0 replies; 58+ messages in thread
From: Andi Kleen @ 2012-09-28  4:31 UTC (permalink / raw)
  To: linux-kernel; +Cc: x86, a.p.zijlstra, eranian, acme, Andi Kleen

From: Andi Kleen <ak@linux.intel.com>

Add support to perf stat to print the basic transactional execution statistics:
Total cycles, Cycles in Transaction, Cycles in aborted transsactions
using the intx and intx_checkpoint qualifiers.
Transaction Starts and Elision Starts, to compute the average transaction length.

This is a reasonable overview over the success of the transactions.

Enable with a new --transaction / -T option.

This requires measuring these events in a group, since they depend on each
other

Signed-off-by: Andi Kleen <ak@linux.intel.com>
---
 tools/perf/Documentation/perf-stat.txt |    3 +
 tools/perf/builtin-stat.c              |  104 +++++++++++++++++++++++++++++---
 2 files changed, 99 insertions(+), 8 deletions(-)

diff --git a/tools/perf/Documentation/perf-stat.txt b/tools/perf/Documentation/perf-stat.txt
index 2fa173b..6e55bd9 100644
--- a/tools/perf/Documentation/perf-stat.txt
+++ b/tools/perf/Documentation/perf-stat.txt
@@ -108,7 +108,10 @@ with it.  --append may be used here.  Examples:
      3>results  perf stat --log-fd 3          -- $cmd
      3>>results perf stat --log-fd 3 --append -- $cmd
 
+-T::
+--transaction::
 
+Print statistics of transactional execution.  Implies --group.
 
 EXAMPLES
 --------
diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
index 861f0ae..2364605 100644
--- a/tools/perf/builtin-stat.c
+++ b/tools/perf/builtin-stat.c
@@ -64,6 +64,9 @@
 #define CNTR_NOT_SUPPORTED	"<not supported>"
 #define CNTR_NOT_COUNTED	"<not counted>"
 
+#define is_intx(e)		((e)->attr.intx && !(e)->attr.intx_checkpointed)
+#define is_intx_cp(e)		((e)->attr.intx && (e)->attr.intx_checkpointed)
+
 static struct perf_event_attr default_attrs[] = {
 
   { .type = PERF_TYPE_SOFTWARE, .config = PERF_COUNT_SW_TASK_CLOCK		},
@@ -171,7 +174,21 @@ static struct perf_event_attr very_very_detailed_attrs[] = {
 	(PERF_COUNT_HW_CACHE_RESULT_MISS	<< 16)				},
 };
 
+/*
+ * Transactional memory stats (-T)
+ * Must run as a group.
+ */
+static struct perf_event_attr transaction_attrs[] = {
+  { .type = PERF_TYPE_SOFTWARE, .config = PERF_COUNT_SW_TASK_CLOCK		},
 
+  { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_INSTRUCTIONS		},
+  { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_CPU_CYCLES		},
+  { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_CPU_CYCLES, .intx = 1	},
+  { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_CPU_CYCLES,
+    .intx = 1, .intx_checkpointed = 1 },
+  { .type = PERF_TYPE_HW_TRANSACTION, .config = PERF_COUNT_HW_TRANSACTION_START	},
+  { .type = PERF_TYPE_HW_TRANSACTION, .config = PERF_COUNT_HW_ELISION_START	},
+};
 
 static struct perf_evlist	*evsel_list;
 
@@ -187,6 +204,7 @@ static bool			no_aggr				= false;
 static pid_t			child_pid			= -1;
 static bool			null_run			=  false;
 static int			detailed_run			=  0;
+static bool			transaction_run			=  false;
 static bool			sync_run			=  false;
 static bool			big_num				=  true;
 static int			big_num_opt			=  -1;
@@ -275,7 +293,11 @@ static struct stats runtime_l1_icache_stats[MAX_NR_CPUS];
 static struct stats runtime_ll_cache_stats[MAX_NR_CPUS];
 static struct stats runtime_itlb_cache_stats[MAX_NR_CPUS];
 static struct stats runtime_dtlb_cache_stats[MAX_NR_CPUS];
+static struct stats runtime_cycles_intx_stats[MAX_NR_CPUS];
+static struct stats runtime_cycles_intxcp_stats[MAX_NR_CPUS];
 static struct stats walltime_nsecs_stats;
+static struct stats runtime_transaction_stats[MAX_NR_CPUS];
+static struct stats runtime_elision_stats[MAX_NR_CPUS];
 
 static int create_perf_stat_counter(struct perf_evsel *evsel,
 				    struct perf_evsel *first)
@@ -350,10 +372,18 @@ static void update_shadow_stats(struct perf_evsel *counter, u64 *count)
 {
 	if (perf_evsel__match(counter, SOFTWARE, SW_TASK_CLOCK))
 		update_stats(&runtime_nsecs_stats[0], count[0]);
-	else if (perf_evsel__match(counter, HARDWARE, HW_CPU_CYCLES))
-		update_stats(&runtime_cycles_stats[0], count[0]);
-	else if (perf_evsel__match(counter, HARDWARE, HW_STALLED_CYCLES_FRONTEND))
-		update_stats(&runtime_stalled_cycles_front_stats[0], count[0]);
+	else if (perf_evsel__match(counter, HARDWARE, HW_CPU_CYCLES)) {
+		if (is_intx(counter))
+			update_stats(&runtime_cycles_intx_stats[0], count[0]);
+		else if (is_intx_cp(counter))
+			update_stats(&runtime_cycles_intxcp_stats[0], count[0]);
+		else
+			update_stats(&runtime_cycles_stats[0], count[0]);
+	} else if (perf_evsel__match(counter, HW_TRANSACTION,
+				     HW_TRANSACTION_START))
+		update_stats(&runtime_transaction_stats[0], count[0]);
+	else if (perf_evsel__match(counter, HW_TRANSACTION, HW_ELISION_START))
+		update_stats(&runtime_elision_stats[0], count[0]);
 	else if (perf_evsel__match(counter, HARDWARE, HW_STALLED_CYCLES_BACKEND))
 		update_stats(&runtime_stalled_cycles_back_stats[0], count[0]);
 	else if (perf_evsel__match(counter, HARDWARE, HW_BRANCH_INSTRUCTIONS))
@@ -774,7 +804,7 @@ static void print_ll_cache_misses(int cpu, struct perf_evsel *evsel __used, doub
 
 static void abs_printout(int cpu, struct perf_evsel *evsel, double avg)
 {
-	double total, ratio = 0.0;
+	double total, ratio = 0.0, total2;
 	char cpustr[16] = { '\0', };
 	const char *fmt;
 
@@ -868,12 +898,50 @@ static void abs_printout(int cpu, struct perf_evsel *evsel, double avg)
 	} else if (perf_evsel__match(evsel, HARDWARE, HW_STALLED_CYCLES_BACKEND)) {
 		print_stalled_cycles_backend(cpu, evsel, avg);
 	} else if (perf_evsel__match(evsel, HARDWARE, HW_CPU_CYCLES)) {
-		total = avg_stats(&runtime_nsecs_stats[cpu]);
+		if (is_intx(evsel)) {
+			total = avg_stats(&runtime_cycles_stats[cpu]);
+			if (total)
+				fprintf(output,
+					" #   %5.2f%% transactional          ",
+					100.0 * (avg / total));
+		} else if (is_intx_cp(evsel)) {
+			total = avg_stats(&runtime_cycles_stats[cpu]);
+			total2 = avg_stats(&runtime_cycles_intx_stats[cpu]);
+			if (total)
+				fprintf(output,
+					" #   %5.2f%% aborted cycles         ",
+					100.0 * ((total2-avg) / total));
+		} else {
+			total = avg_stats(&runtime_nsecs_stats[cpu]);
+
+			if (total)
+				ratio = 1.0 * avg / total;
+
+			fprintf(output, " # %8.3f GHz                    ", 
+					ratio);
+		}
+	} else if (perf_evsel__match(evsel, HW_TRANSACTION,
+				     HW_TRANSACTION_START) &&
+		   avg > 0 &&
+		   runtime_cycles_intx_stats[cpu].n != 0) {
+		total = avg_stats(&runtime_cycles_intx_stats[cpu]);
+
+		if (total)
+			ratio = total / avg;
+
+		fprintf(output, " # %8.0f cycles / transaction ", ratio);
+
+	} else if (perf_evsel__match(evsel, HW_TRANSACTION,
+				      HW_ELISION_START) &&
+		   avg > 0 &&
+		   runtime_cycles_intx_stats[cpu].n != 0) {
+		total = avg_stats(&runtime_cycles_intx_stats[cpu]);
 
 		if (total)
-			ratio = 1.0 * avg / total;
+			ratio = total / avg;
+
+		fprintf(output, " # %8.0f cycles / elision     ", ratio);
 
-		fprintf(output, " # %8.3f GHz                    ", ratio);
 	} else if (runtime_nsecs_stats[cpu].n != 0) {
 		char unit = 'M';
 
@@ -1068,6 +1136,16 @@ static int stat__set_big_num(const struct option *opt __used,
 	return 0;
 }
 
+/* Must force groups for transactions */
+static int stat__parse_transaction(const struct option *opt __used,
+				   const char *str __used,
+				   int unset __used)
+{
+	transaction_run = true;
+	group = true;
+	return 0;
+}
+
 static bool append_file;
 
 static const struct option options[] = {
@@ -1115,6 +1193,9 @@ static const struct option options[] = {
 	OPT_BOOLEAN(0, "append", &append_file, "append to the output file"),
 	OPT_INTEGER(0, "log-fd", &output_fd,
 		    "log output to fd, instead of stderr"),
+	OPT_CALLBACK_NOOPT('T', "transaction", NULL, NULL,
+		     "capture hardware transaction success",
+		     stat__parse_transaction),
 	OPT_END()
 };
 
@@ -1128,6 +1209,13 @@ static int add_default_attributes(void)
 	if (null_run)
 		return 0;
 
+	if (transaction_run) {
+		if (perf_evlist__add_attrs_array(evsel_list, 
+						 transaction_attrs) < 0)
+			return -1;
+		return 0;
+	}
+
 	if (!evsel_list->nr_entries) {
 		if (perf_evlist__add_default_attrs(evsel_list, default_attrs) < 0)
 			return -1;
-- 
1.7.7.6


^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [PATCH 26/31] perf, x86: Support for printing PMU state on spurious PMIs
  2012-09-28  4:31 perf PMU support for Haswell Andi Kleen
                   ` (24 preceding siblings ...)
  2012-09-28  4:31 ` [PATCH 25/31] perf, tools: Add perf stat --transaction Andi Kleen
@ 2012-09-28  4:31 ` Andi Kleen
  2012-09-28  9:36   ` Peter Zijlstra
  2012-09-28  4:31 ` [PATCH 27/31] perf, core: Add generic transaction flags Andi Kleen
                   ` (4 subsequent siblings)
  30 siblings, 1 reply; 58+ messages in thread
From: Andi Kleen @ 2012-09-28  4:31 UTC (permalink / raw)
  To: linux-kernel; +Cc: x86, a.p.zijlstra, eranian, acme, Andi Kleen

From: Andi Kleen <ak@linux.intel.com>

I had some problems with spurious PMIs, so print the PMU state
on a spurious one. This will not interact well with other NMI users.
Disabled by default, has to be explicitely enabled through sysfs.

Optional, but useful for debugging.

Signed-off-by: Andi Kleen <ak@linux.intel.com>
---
 arch/x86/kernel/cpu/perf_event_intel.c |    8 ++++++++
 1 files changed, 8 insertions(+), 0 deletions(-)

diff --git a/arch/x86/kernel/cpu/perf_event_intel.c b/arch/x86/kernel/cpu/perf_event_intel.c
index be0d3c8..baf78e0 100644
--- a/arch/x86/kernel/cpu/perf_event_intel.c
+++ b/arch/x86/kernel/cpu/perf_event_intel.c
@@ -12,6 +12,7 @@
 #include <linux/init.h>
 #include <linux/slab.h>
 #include <linux/export.h>
+#include <linux/moduleparam.h>
 
 #include <asm/cpufeature.h>
 #include <asm/hardirq.h>
@@ -19,6 +20,9 @@
 
 #include "perf_event.h"
 
+static bool print_spurious_pmi __read_mostly;
+module_param(print_spurious_pmi, bool, 0644);
+
 /*
  * Intel PerfMon, used on Core and later.
  */
@@ -1237,6 +1241,10 @@ again:
 		goto again;
 
 done:
+	if (!handled && print_spurious_pmi) {
+		pr_debug("Spurious PMI\n");
+		perf_event_print_debug();
+	}
 	intel_pmu_enable_all(0);
 	return handled;
 }
-- 
1.7.7.6


^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [PATCH 27/31] perf, core: Add generic transaction flags
  2012-09-28  4:31 perf PMU support for Haswell Andi Kleen
                   ` (25 preceding siblings ...)
  2012-09-28  4:31 ` [PATCH 26/31] perf, x86: Support for printing PMU state on spurious PMIs Andi Kleen
@ 2012-09-28  4:31 ` Andi Kleen
  2012-09-28  4:31 ` [PATCH 28/31] perf, x86: Add Haswell specific transaction flag reporting Andi Kleen
                   ` (3 subsequent siblings)
  30 siblings, 0 replies; 58+ messages in thread
From: Andi Kleen @ 2012-09-28  4:31 UTC (permalink / raw)
  To: linux-kernel; +Cc: x86, a.p.zijlstra, eranian, acme, Andi Kleen

From: Andi Kleen <ak@linux.intel.com>

Add a generic qualifier for transaction events, as a new sample
type that returns a flag word. This is particularly useful
for qualifying aborts: to distinguish aborts which happen
due to asynchronous events (like conflicts caused by another
CPU) versus instructions that lead to an abort.

The tuning strategies are very different for those cases,
so it's important to distinguish them easily and early.

Since it's inconvenient and inflexible to filter for this
in the kernel we report all the events out and allow
some post processing in user space.

The flags are based on the Intel TSX events, but should be fairly
generic and mostly applicable to other architectures too. In addition
to various flag words there's also reserved space to report an
program supplied abort code. For TSX this is used to distinguish specific
classes of aborts, like a lock busy abort when doing lock elision.

This adds the perf core glue needed for reporting the new flag word out.

Signed-off-by: Andi Kleen <ak@linux.intel.com>
---
 include/linux/perf_event.h |   25 ++++++++++++++++++++++++-
 kernel/events/core.c       |    6 ++++++
 2 files changed, 30 insertions(+), 1 deletions(-)

diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h
index 1867bed..beafd7f 100644
--- a/include/linux/perf_event.h
+++ b/include/linux/perf_event.h
@@ -156,8 +156,9 @@ enum perf_event_sample_format {
 	PERF_SAMPLE_RAW				= 1U << 10,
 	PERF_SAMPLE_BRANCH_STACK		= 1U << 11,
 	PERF_SAMPLE_WEIGHT			= 1U << 12,
+	PERF_SAMPLE_TRANSACTION			= 1U << 13,
 
-	PERF_SAMPLE_MAX = 1U << 13,		/* non-ABI */
+	PERF_SAMPLE_MAX = 1U << 14,		/* non-ABI */
 };
 
 /*
@@ -192,6 +193,26 @@ enum perf_branch_sample_type {
 	 PERF_SAMPLE_BRANCH_HV)
 
 /*
+ * Values for the transaction event qualifier, mostly for abort events.
+ */
+enum {
+	PERF_SAMPLE_TXN_ELISION     = (1 << 0), /* From elision */
+	PERF_SAMPLE_TXN_TRANSACTION = (1 << 1), /* From transaction */
+	PERF_SAMPLE_TXN_SYNC        = (1 << 2), /* Instruction is related */
+	PERF_SAMPLE_TXN_ASYNC       = (1 << 3), /* Instruction not related */
+	PERF_SAMPLE_TXN_RETRY       = (1 << 4), /* Retry possible */
+	PERF_SAMPLE_TXN_CONFLICT    = (1 << 5), /* Conflict abort */
+	PERF_SAMPLE_TXN_CAPACITY    = (1 << 6), /* Capacity abort */
+
+	PERF_SAMPLE_TXN_MAX	    = (1 << 7),  /* non-ABI */
+
+	/* bits 24..31 are reserved for the abort code */
+
+	PERF_SAMPLE_TXN_ABORT_MASK  = 0xff000000,
+	PERF_SAMPLE_TXN_ABORT_SHIFT = 24,
+};
+
+/*
  * The format of the data returned by read() on a perf event fd,
  * as specified by attr.read_format:
  *
@@ -1173,6 +1194,7 @@ struct perf_sample_data {
 	struct perf_raw_record		*raw;
 	struct perf_branch_stack	*br_stack;
 	u64				weight;
+	u64				transaction;
 };
 
 static inline void perf_sample_data_init(struct perf_sample_data *data,
@@ -1184,6 +1206,7 @@ static inline void perf_sample_data_init(struct perf_sample_data *data,
 	data->br_stack = NULL;
 	data->period	= period;
 	data->weight = 0;
+	data->transaction = 0;
 }
 
 extern void perf_output_sample(struct perf_output_handle *handle,
diff --git a/kernel/events/core.c b/kernel/events/core.c
index 74e4ff4..6af2e76 100644
--- a/kernel/events/core.c
+++ b/kernel/events/core.c
@@ -952,6 +952,9 @@ static void perf_event__header_size(struct perf_event *event)
 	if (sample_type & PERF_SAMPLE_WEIGHT)
 		size += sizeof(data->weight);
 
+	if (sample_type & PERF_SAMPLE_TRANSACTION)
+		size += sizeof(data->transaction);
+
 	if (sample_type & PERF_SAMPLE_READ)
 		size += event->read_size;
 
@@ -3963,6 +3966,9 @@ void perf_output_sample(struct perf_output_handle *handle,
 	if (sample_type & PERF_SAMPLE_WEIGHT)
 		perf_output_put(handle, data->weight);
 
+	if (sample_type & PERF_SAMPLE_TRANSACTION)
+		perf_output_put(handle, data->transaction);
+
 	if (sample_type & PERF_SAMPLE_READ)
 		perf_output_read(handle, event);
 
-- 
1.7.7.6


^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [PATCH 28/31] perf, x86: Add Haswell specific transaction flag reporting
  2012-09-28  4:31 perf PMU support for Haswell Andi Kleen
                   ` (26 preceding siblings ...)
  2012-09-28  4:31 ` [PATCH 27/31] perf, core: Add generic transaction flags Andi Kleen
@ 2012-09-28  4:31 ` Andi Kleen
  2012-09-28  4:31 ` [PATCH 29/31] perf, tools: Add support for record transaction flags Andi Kleen
                   ` (2 subsequent siblings)
  30 siblings, 0 replies; 58+ messages in thread
From: Andi Kleen @ 2012-09-28  4:31 UTC (permalink / raw)
  To: linux-kernel; +Cc: x86, a.p.zijlstra, eranian, acme, Andi Kleen

From: Andi Kleen <ak@linux.intel.com>

In the PEBS handler report the transaction flags using the new
generic transaction flags facility. Most of them come from
the "tsx_tuning" field in PEBSv2, but the abort code is derived
from the RAX register reported in the PEBS record.

Signed-off-by: Andi Kleen <ak@linux.intel.com>
---
 arch/x86/kernel/cpu/perf_event_intel_ds.c |    9 +++++++++
 1 files changed, 9 insertions(+), 0 deletions(-)

diff --git a/arch/x86/kernel/cpu/perf_event_intel_ds.c b/arch/x86/kernel/cpu/perf_event_intel_ds.c
index 930bc65..6df29c7 100644
--- a/arch/x86/kernel/cpu/perf_event_intel_ds.c
+++ b/arch/x86/kernel/cpu/perf_event_intel_ds.c
@@ -670,6 +670,15 @@ static void __intel_pmu_pebs_event(struct perf_event *event,
 			data.weight = ((struct pebs_record_v2 *)pebs)->nhm.lat;
 	}
 
+	if ((event->attr.sample_type & PERF_SAMPLE_TRANSACTION) &&
+	    x86_pmu.intel_cap.pebs_format >= 2) {
+		data.transaction =
+		     ((struct pebs_record_v2 *)pebs)->tsx_tuning >> 32;
+		if ((data.transaction & PERF_SAMPLE_TXN_TRANSACTION) &&
+		    (pebs->ax & 1))
+			data.transaction |= pebs->ax & 0xff000000;
+	}
+
 	if (has_branch_stack(event))
 		data.br_stack = &cpuc->lbr_stack;
 
-- 
1.7.7.6


^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [PATCH 29/31] perf, tools: Add support for record transaction flags
  2012-09-28  4:31 perf PMU support for Haswell Andi Kleen
                   ` (27 preceding siblings ...)
  2012-09-28  4:31 ` [PATCH 28/31] perf, x86: Add Haswell specific transaction flag reporting Andi Kleen
@ 2012-09-28  4:31 ` Andi Kleen
  2012-09-28  4:31 ` [PATCH 30/31] perf, tools: Point --sort documentation to --help Andi Kleen
  2012-09-28  4:31 ` [PATCH 31/31] perf, tools: Add browser support for transaction flags Andi Kleen
  30 siblings, 0 replies; 58+ messages in thread
From: Andi Kleen @ 2012-09-28  4:31 UTC (permalink / raw)
  To: linux-kernel; +Cc: x86, a.p.zijlstra, eranian, acme, Andi Kleen

From: Andi Kleen <ak@linux.intel.com>

Add the glue in the user tools to record transaction flags with
--transaction (-T was already taken) and dump them.

Followon patches will use them.

Signed-off-by: Andi Kleen <ak@linux.intel.com>
---
 tools/perf/Documentation/perf-record.txt |    5 ++++-
 tools/perf/builtin-record.c              |    2 ++
 tools/perf/perf.h                        |    1 +
 tools/perf/util/event.h                  |    1 +
 tools/perf/util/evsel.c                  |    9 +++++++++
 tools/perf/util/session.c                |    3 +++
 6 files changed, 20 insertions(+), 1 deletions(-)

diff --git a/tools/perf/Documentation/perf-record.txt b/tools/perf/Documentation/perf-record.txt
index 4930654..2ede9e6 100644
--- a/tools/perf/Documentation/perf-record.txt
+++ b/tools/perf/Documentation/perf-record.txt
@@ -182,12 +182,15 @@ is enabled for all the sampling events. The sampled branch type is the same for
 The various filters must be specified as a comma separated list: --branch-filter any_ret,u,k
 Note that this feature may not be available on all processors.
 
--W::
 --weight::
 Enable weightened sampling. When the event supports an additional weight per sample scale
 the histogram by this weight. This currently works for TSX abort events and some memory events
 in precise mode on modern Intel CPUs.
 
+-T::
+--transaction::
+Record transaction flags for transaction related events.
+
 SEE ALSO
 --------
 linkperf:perf-stat[1], linkperf:perf-list[1]
diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
index 4dbdc4e..5987f07 100644
--- a/tools/perf/builtin-record.c
+++ b/tools/perf/builtin-record.c
@@ -838,6 +838,8 @@ const struct option record_options[] = {
 		     parse_branch_stack),
 	OPT_BOOLEAN('W', "weight", &record.opts.sample_weight,
 		    "sample by weight (on special events only)"),
+	OPT_BOOLEAN(0, "transaction", &record.opts.sample_transaction,
+		    "sample transaction flags (special events only)"),
 	OPT_END()
 };
 
diff --git a/tools/perf/perf.h b/tools/perf/perf.h
index a98dcf2..d1b1e82 100644
--- a/tools/perf/perf.h
+++ b/tools/perf/perf.h
@@ -233,6 +233,7 @@ struct perf_record_opts {
 	u64          branch_stack;
 	u64	     default_interval;
 	u64	     user_interval;
+	bool	     sample_transaction;
 };
 
 #endif
diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h
index 5ac79f3..b902d16 100644
--- a/tools/perf/util/event.h
+++ b/tools/perf/util/event.h
@@ -78,6 +78,7 @@ struct perf_sample {
 	u64 stream_id;
 	u64 period;
 	u64 weight;
+	u64 transaction;
 	u32 cpu;
 	u32 raw_size;
 	void *raw_data;
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
index 8790069..b0921a6 100644
--- a/tools/perf/util/evsel.c
+++ b/tools/perf/util/evsel.c
@@ -420,6 +420,9 @@ void perf_evsel__config(struct perf_evsel *evsel, struct perf_record_opts *opts,
 	if (opts->sample_weight)
 		attr->sample_type	|= PERF_SAMPLE_WEIGHT;
 
+	if (opts->sample_transaction)
+		attr->sample_type	|= PERF_SAMPLE_TRANSACTION;
+
 	if (opts->call_graph)
 		attr->sample_type	|= PERF_SAMPLE_CALLCHAIN;
 
@@ -876,6 +879,12 @@ int perf_evsel__parse_sample(struct perf_evsel *evsel, union perf_event *event,
 		array++;
 	}
 
+	data->transaction = 0;
+	if (type & PERF_SAMPLE_TRANSACTION) {
+		data->transaction = *array;
+		array++;
+	}
+
 	if (type & PERF_SAMPLE_READ) {
 		fprintf(stderr, "PERF_SAMPLE_READ is unsupported for now\n");
 		return -1;
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
index 84f000c..ae79f22 100644
--- a/tools/perf/util/session.c
+++ b/tools/perf/util/session.c
@@ -919,6 +919,9 @@ static void dump_sample(struct perf_session *session, union perf_event *event,
 
 	if (sample_type & PERF_SAMPLE_WEIGHT)
 		printf("... weight: %" PRIu64 "\n", sample->weight);
+
+	if (sample_type & PERF_SAMPLE_TRANSACTION)
+		printf("... transaction: %" PRIx64 "\n", sample->transaction);
 }
 
 static struct machine *
-- 
1.7.7.6


^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [PATCH 30/31] perf, tools: Point --sort documentation to --help
  2012-09-28  4:31 perf PMU support for Haswell Andi Kleen
                   ` (28 preceding siblings ...)
  2012-09-28  4:31 ` [PATCH 29/31] perf, tools: Add support for record transaction flags Andi Kleen
@ 2012-09-28  4:31 ` Andi Kleen
  2012-09-28  4:31 ` [PATCH 31/31] perf, tools: Add browser support for transaction flags Andi Kleen
  30 siblings, 0 replies; 58+ messages in thread
From: Andi Kleen @ 2012-09-28  4:31 UTC (permalink / raw)
  To: linux-kernel; +Cc: x86, a.p.zijlstra, eranian, acme, Andi Kleen

From: Andi Kleen <ak@linux.intel.com>

The --sort documentation for top and report was hopelessly out-of-date
Instead of having two more places that would need to be updated,
just point to --help.

Signed-off-by: Andi Kleen <ak@linux.intel.com>
---
 tools/perf/Documentation/perf-report.txt |    2 +-
 tools/perf/Documentation/perf-top.txt    |    2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/tools/perf/Documentation/perf-report.txt b/tools/perf/Documentation/perf-report.txt
index 495210a..b4e747a 100644
--- a/tools/perf/Documentation/perf-report.txt
+++ b/tools/perf/Documentation/perf-report.txt
@@ -57,7 +57,7 @@ OPTIONS
 
 -s::
 --sort=::
-	Sort by key(s): pid, comm, dso, symbol, parent, srcline.
+	Sort by key(s): See --help for a full list.
 
 -p::
 --parent=<regex>::
diff --git a/tools/perf/Documentation/perf-top.txt b/tools/perf/Documentation/perf-top.txt
index 5b80d84..0f0fa3e 100644
--- a/tools/perf/Documentation/perf-top.txt
+++ b/tools/perf/Documentation/perf-top.txt
@@ -112,7 +112,7 @@ Default is to monitor all CPUS.
 
 -s::
 --sort::
-	Sort by key(s): pid, comm, dso, symbol, parent, srcline.
+	Sort by key(s): see --help for a full list.
 
 -n::
 --show-nr-samples::
-- 
1.7.7.6


^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [PATCH 31/31] perf, tools: Add browser support for transaction flags
  2012-09-28  4:31 perf PMU support for Haswell Andi Kleen
                   ` (29 preceding siblings ...)
  2012-09-28  4:31 ` [PATCH 30/31] perf, tools: Point --sort documentation to --help Andi Kleen
@ 2012-09-28  4:31 ` Andi Kleen
  30 siblings, 0 replies; 58+ messages in thread
From: Andi Kleen @ 2012-09-28  4:31 UTC (permalink / raw)
  To: linux-kernel; +Cc: x86, a.p.zijlstra, eranian, acme, Andi Kleen

From: Andi Kleen <ak@linux.intel.com>

Add histogram support for the transaction flags. Each flags instance becomes
a separate histogram. Support sorting and displaying the flags in report
and top.

The patch is fairly large, but it's really mostly just plumbing to pass the
flags around.

Signed-off-by: Andi Kleen <ak@linux.intel.com>
---
 tools/perf/builtin-annotate.c |    2 +-
 tools/perf/builtin-diff.c     |    8 ++++--
 tools/perf/builtin-report.c   |    4 +-
 tools/perf/builtin-top.c      |    4 +-
 tools/perf/util/hist.c        |    3 +-
 tools/perf/util/hist.h        |    3 +-
 tools/perf/util/sort.c        |   50 +++++++++++++++++++++++++++++++++++++++++
 tools/perf/util/sort.h        |    2 +
 8 files changed, 66 insertions(+), 10 deletions(-)

diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c
index c522367..a6f0ffc 100644
--- a/tools/perf/builtin-annotate.c
+++ b/tools/perf/builtin-annotate.c
@@ -62,7 +62,7 @@ static int perf_evsel__add_sample(struct perf_evsel *evsel,
 		return 0;
 	}
 
-	he = __hists__add_entry(&evsel->hists, al, NULL, 1, 1);
+	he = __hists__add_entry(&evsel->hists, al, NULL, 1, 1, 0);
 	if (he == NULL)
 		return -ENOMEM;
 
diff --git a/tools/perf/builtin-diff.c b/tools/perf/builtin-diff.c
index 04c1d21..cef8f5c 100644
--- a/tools/perf/builtin-diff.c
+++ b/tools/perf/builtin-diff.c
@@ -31,9 +31,10 @@ struct perf_diff {
 
 static int hists__add_entry(struct hists *self,
 			    struct addr_location *al, u64 period,
-			    u64 weight)
+			    u64 weight, u64 transaction)
 {
-	if (__hists__add_entry(self, al, NULL, period, weight) != NULL)
+	if (__hists__add_entry(self, al, NULL, period, weight, transaction)
+	    != NULL)
 		return 0;
 	return -ENOMEM;
 }
@@ -57,7 +58,8 @@ static int diff__process_sample_event(struct perf_tool *tool,
 	if (al.filtered || al.sym == NULL)
 		return 0;
 
-	if (hists__add_entry(&session->hists, &al, sample->period, sample->weight)) {
+	if (hists__add_entry(&session->hists, &al, sample->period, sample->weight,
+			     sample->transaction)) {
 		pr_warning("problem incrementing symbol period, skipping event\n");
 		return -1;
 	}
diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c
index 2c73578..b22a905 100644
--- a/tools/perf/builtin-report.c
+++ b/tools/perf/builtin-report.c
@@ -147,7 +147,7 @@ static int perf_evsel__add_hist_entry(struct perf_evsel *evsel,
 	}
 
 	he = __hists__add_entry(&evsel->hists, al, parent, sample->period,
-					sample->weight);
+				sample->weight, sample->transaction);
 	if (he == NULL)
 		return -ENOMEM;
 
@@ -596,7 +596,7 @@ int cmd_report(int argc, const char **argv, const char *prefix __used)
 	OPT_STRING('s', "sort", &sort_order, "key[,key2...]",
 		   "sort by key(s): pid, comm, dso, symbol, parent, dso_to,"
 		   " dso_from, symbol_to, symbol_from, mispredict, srcline,"
-		   " abort, intx,  weight, global_weight"),
+		   " abort, intx,  weight, global_weight, transaction"),
 	OPT_BOOLEAN(0, "showcpuutilization", &symbol_conf.show_cpu_utilization,
 		    "Show sample percentage for different cpu modes"),
 	OPT_STRING('p', "parent", &parent_pattern, "regex",
diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c
index ee37ddc..5e44f7c 100644
--- a/tools/perf/builtin-top.c
+++ b/tools/perf/builtin-top.c
@@ -270,7 +270,7 @@ static struct hist_entry *perf_evsel__add_hist_entry(struct perf_evsel *evsel,
 	struct hist_entry *he;
 
 	he = __hists__add_entry(&evsel->hists, al, NULL, sample->period,
-				sample->weight);
+				sample->weight, sample->transaction);
 	if (he == NULL)
 		return NULL;
 
@@ -1230,7 +1230,7 @@ int cmd_top(int argc, const char **argv, const char *prefix __used)
 	OPT_STRING('s', "sort", &sort_order, "key[,key2...]",
 		   "sort by key(s): pid, comm, dso, symbol, parent, dso_to,"
 		   " dso_from, symbol_to, symbol_from, mispredict, srcline,"
-		   " abort, intx, weight, global_weight"),
+		   " abort, intx, weight, global_weight, transaction"),
 	OPT_BOOLEAN('n', "show-nr-samples", &symbol_conf.show_nr_samples,
 		    "Show a column with the number of samples"),
 	OPT_CALLBACK_DEFAULT('G', "call-graph", &top, "output_type,min_percent, call_order",
diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c
index 566badc..072b418 100644
--- a/tools/perf/util/hist.c
+++ b/tools/perf/util/hist.c
@@ -323,7 +323,7 @@ struct hist_entry *__hists__add_branch_entry(struct hists *self,
 struct hist_entry *__hists__add_entry(struct hists *self,
 				      struct addr_location *al,
 				      struct symbol *sym_parent, u64 period,
-				      u64 weight)
+				      u64 weight, u64 transaction)
 {
 	struct hist_entry entry = {
 		.thread	= al->thread,
@@ -337,6 +337,7 @@ struct hist_entry *__hists__add_entry(struct hists *self,
 		.period	= period,
 		.parent = sym_parent,
 		.filtered = symbol__parent_filter(sym_parent),
+		.transaction = transaction,
 	};
 
 	return add_hist_entry(self, &entry, al, period, weight);
diff --git a/tools/perf/util/hist.h b/tools/perf/util/hist.h
index a02d068..ab6e262 100644
--- a/tools/perf/util/hist.h
+++ b/tools/perf/util/hist.h
@@ -52,6 +52,7 @@ enum hist_column {
 	HISTC_SRCLINE,
 	HISTC_WEIGHT,
 	HISTC_GLOBAL_WEIGHT,
+	HISTC_TRANSACTION,
 	HISTC_NR_COLS, /* Last entry */
 };
 
@@ -77,7 +78,7 @@ struct hists {
 struct hist_entry *__hists__add_entry(struct hists *self,
 				      struct addr_location *al,
 				      struct symbol *parent, u64 period,
-				      u64 weight);
+				      u64 weight, u64 transaction);
 int64_t hist_entry__cmp(struct hist_entry *left, struct hist_entry *right);
 int64_t hist_entry__collapse(struct hist_entry *left, struct hist_entry *right);
 int hist_entry__snprintf(struct hist_entry *self, char *bf, size_t size,
diff --git a/tools/perf/util/sort.c b/tools/perf/util/sort.c
index 0fcbbcd..258174e 100644
--- a/tools/perf/util/sort.c
+++ b/tools/perf/util/sort.c
@@ -559,6 +559,55 @@ struct sort_entry sort_global_weight = {
 	.se_width_idx	= HISTC_GLOBAL_WEIGHT,
 };
 
+static int64_t
+sort__transaction_cmp(struct hist_entry *left, struct hist_entry *right)
+{
+	return left->transaction - right->transaction;
+}
+
+static inline char *add_str(char *p, const char *str)
+{
+	strcpy(p, str);
+	return p + strlen(str);
+}
+
+static int hist_entry__transaction_snprintf(struct hist_entry *self, char *bf,
+				    size_t size, unsigned int width)
+{
+	u64 t = self->transaction;
+	char buf[128];
+	char *p = buf;
+
+	if (t & PERF_SAMPLE_TXN_ELISION)
+		*p++ = 'E';
+	if (t & PERF_SAMPLE_TXN_TRANSACTION)
+		*p++ = 'T';
+	if (t & PERF_SAMPLE_TXN_SYNC)
+		*p++ = 'I';
+	if (t & PERF_SAMPLE_TXN_RETRY)
+		*p++ = 'R';
+	*p = 0;
+	if (t & PERF_SAMPLE_TXN_CONFLICT)
+		p = add_str(p, ":con");
+	if (t & PERF_SAMPLE_TXN_CONFLICT)
+		p = add_str(p, ":cap");
+	if (t & PERF_SAMPLE_TXN_ABORT_MASK) {
+		sprintf(p, ":%" PRIx64,
+			(t & PERF_SAMPLE_TXN_ABORT_MASK) >>
+			PERF_SAMPLE_TXN_ABORT_SHIFT);
+		p += strlen(p);
+	}
+
+	return repsep_snprintf(bf, size, "%-*s", width, buf);
+}
+
+struct sort_entry sort_transaction = {
+	.se_header	= "Transaction",
+	.se_cmp		= sort__transaction_cmp,
+	.se_snprintf	= hist_entry__transaction_snprintf,
+	.se_width_idx	= HISTC_TRANSACTION,
+};
+
 struct sort_dimension {
 	const char		*name;
 	struct sort_entry	*entry;
@@ -584,6 +633,7 @@ static struct sort_dimension sort_dimensions[] = {
 	DIM(SORT_INTX, "intx", sort_intx),
 	DIM(SORT_WEIGHT, "weight", sort_weight),
 	DIM(SORT_GLOBAL_WEIGHT, "global_weight", sort_global_weight),
+	DIM(SORT_TRANSACTION, "transaction", sort_transaction),
 };
 
 int sort_dimension__add(const char *tok)
diff --git a/tools/perf/util/sort.h b/tools/perf/util/sort.h
index 8b2c5ae..1a74418 100644
--- a/tools/perf/util/sort.h
+++ b/tools/perf/util/sort.h
@@ -61,6 +61,7 @@ struct hist_entry {
 	struct thread		*thread;
 	u64			ip;
 	u64			weight;
+	u64			transaction;
 	s32			cpu;
 	u32			nr_events;
 
@@ -100,6 +101,7 @@ enum sort_type {
 	SORT_INTX,
 	SORT_WEIGHT,
 	SORT_GLOBAL_WEIGHT,
+	SORT_TRANSACTION,
 };
 
 /*
-- 
1.7.7.6


^ permalink raw reply related	[flat|nested] 58+ messages in thread

* Re: [PATCH 01/31] perf, x86: Add PEBSv2 record support
  2012-09-28  4:31 ` [PATCH 01/31] perf, x86: Add PEBSv2 record support Andi Kleen
@ 2012-09-28  8:43   ` Peter Zijlstra
  2012-09-28  8:54     ` Stephane Eranian
  2012-09-28 14:42     ` Andi Kleen
  0 siblings, 2 replies; 58+ messages in thread
From: Peter Zijlstra @ 2012-09-28  8:43 UTC (permalink / raw)
  To: Andi Kleen; +Cc: linux-kernel, x86, eranian, acme, Andi Kleen

On Thu, 2012-09-27 at 21:31 -0700, Andi Kleen wrote:
> +               if (event->attr.precise_ip > 1 && x86_pmu.intel_cap.pebs_format < 2) {

Shouldn't that be: && x86_pmu.intel_cap.pebs_trap, like most other sites
instead? Or didn't they flip the trap capability on Haswell?

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH 03/31] perf, x86: Basic Haswell PEBS support
  2012-09-28  4:31 ` [PATCH 03/31] perf, x86: Basic Haswell PEBS support Andi Kleen
@ 2012-09-28  8:50   ` Peter Zijlstra
  0 siblings, 0 replies; 58+ messages in thread
From: Peter Zijlstra @ 2012-09-28  8:50 UTC (permalink / raw)
  To: Andi Kleen; +Cc: linux-kernel, x86, eranian, acme, Andi Kleen

On Thu, 2012-09-27 at 21:31 -0700, Andi Kleen wrote:
> +       INTEL_UEVENT_CONSTRAINT(0x11d0, 0xf), /* MEM_UOPS_RETIRED.STLB_MISS_LOADS */
> +       INTEL_UEVENT_CONSTRAINT(0x12d0, 0xf), /* MEM_UOPS_RETIRED.STLB_MISS_STORES */
> +       INTEL_UEVENT_CONSTRAINT(0x21d0, 0xf), /* MEM_UOPS_RETIRED.LOCK_LOADS */

Did you miss umask 22, LOCK_STORES ? (I haven't looked at the SDM yet,
just seeing a glitch in the pattern).

> +       INTEL_UEVENT_CONSTRAINT(0x41d0, 0xf), /* MEM_UOPS_RETIRED.SPLIT_LOADS */
> +       INTEL_UEVENT_CONSTRAINT(0x42d0, 0xf), /* MEM_UOPS_RETIRED.SPLIT_STORES */
> +       INTEL_UEVENT_CONSTRAINT(0x81d0, 0xf), /* MEM_UOPS_RETIRED.ALL_LOADS */
> +       INTEL_UEVENT_CONSTRAINT(0x82d0, 0xf), /* MEM_UOPS_RETIRED.ALL_STORES */ 

Just wondering, are there all d0 events? Or is this a specific subset?
That is, why not use:

	INTEL_EVENT_CONSTRAINT(0xd0, 0xf), /* MEM_UOPS_RETIRED.* */


^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH 08/31] perf, x86: Report PEBS event in a raw format
  2012-09-28  4:31 ` [PATCH 08/31] perf, x86: Report PEBS event in a raw format Andi Kleen
@ 2012-09-28  8:54   ` Peter Zijlstra
  2012-09-28  8:57     ` Stephane Eranian
  0 siblings, 1 reply; 58+ messages in thread
From: Peter Zijlstra @ 2012-09-28  8:54 UTC (permalink / raw)
  To: Andi Kleen; +Cc: linux-kernel, x86, eranian, acme, Andi Kleen

On Thu, 2012-09-27 at 21:31 -0700, Andi Kleen wrote:
> Left over are the general registers. We need them for some analysis
> too: for example for loop trip count and string instruction trip
> count sampling.
> 
> There isn't really any good way to generalize general registers.
> Obviously they are different for every architecture.

You missed the whole PERF_SAMPLE_REGS_USER stuff?

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH 01/31] perf, x86: Add PEBSv2 record support
  2012-09-28  8:43   ` Peter Zijlstra
@ 2012-09-28  8:54     ` Stephane Eranian
  2012-09-28  9:28       ` Peter Zijlstra
  2012-09-28 14:42     ` Andi Kleen
  1 sibling, 1 reply; 58+ messages in thread
From: Stephane Eranian @ 2012-09-28  8:54 UTC (permalink / raw)
  To: Peter Zijlstra
  Cc: Andi Kleen, LKML, x86, Arnaldo Carvalho de Melo, Andi Kleen

On Fri, Sep 28, 2012 at 10:43 AM, Peter Zijlstra <a.p.zijlstra@chello.nl> wrote:
> On Thu, 2012-09-27 at 21:31 -0700, Andi Kleen wrote:
>> +               if (event->attr.precise_ip > 1 && x86_pmu.intel_cap.pebs_format < 2) {
>
> Shouldn't that be: && x86_pmu.intel_cap.pebs_trap, like most other sites
> instead? Or didn't they flip the trap capability on Haswell?

On Haswell, you get the event_ip which points to the sampled
instruction, i.e., the off-by-one
error can be avoided by using that value instead of pebs.rip. The nice
side effect is that you
free the LBR and minimize the overhead (no fixups). Therfore the LBR
filter can have any
setting when combined with PEBS, thus we do not need to check for
compatibility nor force
any setting for the LBR filter.

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH 08/31] perf, x86: Report PEBS event in a raw format
  2012-09-28  8:54   ` Peter Zijlstra
@ 2012-09-28  8:57     ` Stephane Eranian
  0 siblings, 0 replies; 58+ messages in thread
From: Stephane Eranian @ 2012-09-28  8:57 UTC (permalink / raw)
  To: Peter Zijlstra
  Cc: Andi Kleen, LKML, x86, Arnaldo Carvalho de Melo, Andi Kleen

On Fri, Sep 28, 2012 at 10:54 AM, Peter Zijlstra <a.p.zijlstra@chello.nl> wrote:
> On Thu, 2012-09-27 at 21:31 -0700, Andi Kleen wrote:
>> Left over are the general registers. We need them for some analysis
>> too: for example for loop trip count and string instruction trip
>> count sampling.
>>
>> There isn't really any good way to generalize general registers.
>> Obviously they are different for every architecture.
>
> You missed the whole PERF_SAMPLE_REGS_USER stuff?

I will soon post a patchset to expose PEBS state. The patch set piggybacks
on the infrastructure used for USER_REGS and introduce a new sample_intr_regs
bitmask. That would be a more generic way of exposing the other fields
of the PEBS
record.

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH 04/31] perf, core: Add generic intx/intx_checkpointed counter modifiers
  2012-09-28  4:31 ` [PATCH 04/31] perf, core: Add generic intx/intx_checkpointed counter modifiers Andi Kleen
@ 2012-09-28  9:02   ` Peter Zijlstra
  2012-09-28 11:35     ` Stephane Eranian
  2012-09-28 14:53     ` Andi Kleen
  0 siblings, 2 replies; 58+ messages in thread
From: Peter Zijlstra @ 2012-09-28  9:02 UTC (permalink / raw)
  To: Andi Kleen; +Cc: linux-kernel, x86, eranian, acme, Andi Kleen, Jiri Olsa

On Thu, 2012-09-27 at 21:31 -0700, Andi Kleen wrote:
> +                               intx           :  1, /* count inside transaction */
> +                               intx_checkpointed :  1, /* checkpointed in transaction */ 

I really hate those names.. what are they called in transactional memory
literature?

Also do we really need this? Using the event format stuff we could
equally well do:

{cpu/cycles/, cpu/cycles,intx/, cpu/cycles,intx_checkpointed/}

No need to push those bits through perf_event_attr::flags when you can
stuff then through perf_event_attr::config, esp. for very hardware
specific features.

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH 02/31] perf, x86: Basic Haswell PMU support
  2012-09-28  4:31 ` [PATCH 02/31] perf, x86: Basic Haswell PMU support Andi Kleen
@ 2012-09-28  9:05   ` Peter Zijlstra
  2012-09-28 14:58     ` Andi Kleen
  0 siblings, 1 reply; 58+ messages in thread
From: Peter Zijlstra @ 2012-09-28  9:05 UTC (permalink / raw)
  To: Andi Kleen; +Cc: linux-kernel, x86, eranian, acme, Andi Kleen

On Thu, 2012-09-27 at 21:31 -0700, Andi Kleen wrote:
>  /*
> + * Also filter out TSX bits.
> + */
> +#define TSX_FIXED_EVENT_CONSTRAINT(c, n)       \
> +       EVENT_CONSTRAINT(c, (1ULL << (32+n)),   \
> +                        X86_RAW_EVENT_MASK|HSW_INTX|HSW_INTX_CHECKPOINTED)

How volatile are those bits? Will the re-appear in future chips or are
they prone to get re-assigned different semantics in future chips?

If they're 'stable' we might as well add then to FIXED_EVENT_CONSTRAINT,
its not like those bits would ever appear on previous hardware.

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH 18/31] perf, core: Add a concept of a weightened sample
  2012-09-28  4:31 ` [PATCH 18/31] perf, core: Add a concept of a weightened sample Andi Kleen
@ 2012-09-28  9:06   ` Stephane Eranian
  2012-09-28 14:57     ` Andi Kleen
  0 siblings, 1 reply; 58+ messages in thread
From: Stephane Eranian @ 2012-09-28  9:06 UTC (permalink / raw)
  To: Andi Kleen
  Cc: LKML, x86, Peter Zijlstra, Arnaldo Carvalho de Melo, Andi Kleen

On Fri, Sep 28, 2012 at 6:31 AM, Andi Kleen <andi@firstfloor.org> wrote:
> From: Andi Kleen <ak@linux.intel.com>
>
> For some events it's useful to weight sample with a hardware
> provided number. This expresses how expensive the action the
> sample represent was.  This allows the profiler to scale
> the samples to be more informative to the programmer.
>
> There is already the period which is used similarly, but it means
> something different, so I chose to not overload it. Instead
> a new sample type for WEIGHT is added.
>
> Can be used for multiple things. Initially it is used for TSX abort costs
> and profiling by memory latencies (so to make expensive load appear higher
> up in the histograms)  The concept is quite generic and can be extended
> to many other kinds of events or architectures, as long as the hardware
> provides suitable auxillary values. In principle it could be also
> used for software tracpoints.
>
> This adds the generic glue. A new optional sample format for a 64bit
> weight value.
>
> Signed-off-by: Andi Kleen <ak@linux.intel.com>

I came to the conclusion that yes we need something like a weight or cost
as a generic way of reporting that in some modes the period is not really
the right measure to evaluate the "cost" of an event.

I was testing my PEBS Load Latency patch this week, I came to that
conclusion. The way perf report sorts samples based on aggregated
periods per IP does not work for PEBS Load Latency (and possibly other
modes). The sorting needs to be based on some cost that may be distinct
from the period. By default, it would be the period, but for PEBS LL that
would be the latency of the load at a specific IP. That would more reflect
was is going on.

I modified my PEBS-LL patchset to  export a PERF_SAMPLE_COST
value instead of PERF_SAMPLE_LATENCY which is more specific. The
idea is similar to your WEIGHT here. By default it would be equal to the
period, except for some modes. Or it could be equal to 1 by default. It
would then be aggregated by IP by perf report as : he->period += period * cost.

At the perf report level, the changes needed are rather limited.

Will post my PEBS-LL patchset on Monday.

> ---
>  include/linux/perf_event.h |    9 +++++++--
>  kernel/events/core.c       |    6 ++++++
>  2 files changed, 13 insertions(+), 2 deletions(-)
>
> diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h
> index 5bc0e8b..c488ae2 100644
> --- a/include/linux/perf_event.h
> +++ b/include/linux/perf_event.h
> @@ -130,8 +130,9 @@ enum perf_event_sample_format {
>         PERF_SAMPLE_STREAM_ID                   = 1U << 9,
>         PERF_SAMPLE_RAW                         = 1U << 10,
>         PERF_SAMPLE_BRANCH_STACK                = 1U << 11,
> +       PERF_SAMPLE_WEIGHT                      = 1U << 12,
>
> -       PERF_SAMPLE_MAX = 1U << 12,             /* non-ABI */
> +       PERF_SAMPLE_MAX = 1U << 13,             /* non-ABI */
>  };
>
>  /*
> @@ -190,8 +191,9 @@ enum perf_event_read_format {
>         PERF_FORMAT_TOTAL_TIME_RUNNING          = 1U << 1,
>         PERF_FORMAT_ID                          = 1U << 2,
>         PERF_FORMAT_GROUP                       = 1U << 3,
> +       PERF_FORMAT_WEIGHT                      = 1U << 4,
>
> -       PERF_FORMAT_MAX = 1U << 4,              /* non-ABI */
> +       PERF_FORMAT_MAX = 1U << 5,              /* non-ABI */
>  };
>
>  #define PERF_ATTR_SIZE_VER0    64      /* sizeof first published struct */
> @@ -533,6 +535,7 @@ enum perf_event_type {
>          *      { u64                   stream_id;} && PERF_SAMPLE_STREAM_ID
>          *      { u32                   cpu, res; } && PERF_SAMPLE_CPU
>          *      { u64                   period;   } && PERF_SAMPLE_PERIOD
> +        *      { u64                   weight;   } && PERF_SAMPLE_WEIGHT
>          *
>          *      { struct read_format    values;   } && PERF_SAMPLE_READ
>          *
> @@ -1144,6 +1147,7 @@ struct perf_sample_data {
>         struct perf_callchain_entry     *callchain;
>         struct perf_raw_record          *raw;
>         struct perf_branch_stack        *br_stack;
> +       u64                             weight;
>  };
>
>  static inline void perf_sample_data_init(struct perf_sample_data *data,
> @@ -1154,6 +1158,7 @@ static inline void perf_sample_data_init(struct perf_sample_data *data,
>         data->raw  = NULL;
>         data->br_stack = NULL;
>         data->period    = period;
> +       data->weight = 0;
>  }
>
>  extern void perf_output_sample(struct perf_output_handle *handle,
> diff --git a/kernel/events/core.c b/kernel/events/core.c
> index 7fee567..74e4ff4 100644
> --- a/kernel/events/core.c
> +++ b/kernel/events/core.c
> @@ -949,6 +949,9 @@ static void perf_event__header_size(struct perf_event *event)
>         if (sample_type & PERF_SAMPLE_PERIOD)
>                 size += sizeof(data->period);
>
> +       if (sample_type & PERF_SAMPLE_WEIGHT)
> +               size += sizeof(data->weight);
> +
>         if (sample_type & PERF_SAMPLE_READ)
>                 size += event->read_size;
>
> @@ -3957,6 +3960,9 @@ void perf_output_sample(struct perf_output_handle *handle,
>         if (sample_type & PERF_SAMPLE_PERIOD)
>                 perf_output_put(handle, data->period);
>
> +       if (sample_type & PERF_SAMPLE_WEIGHT)
> +               perf_output_put(handle, data->weight);
> +
>         if (sample_type & PERF_SAMPLE_READ)
>                 perf_output_read(handle, event);
>
> --
> 1.7.7.6
>

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH 01/31] perf, x86: Add PEBSv2 record support
  2012-09-28  8:54     ` Stephane Eranian
@ 2012-09-28  9:28       ` Peter Zijlstra
  2012-09-28 11:33         ` Stephane Eranian
  0 siblings, 1 reply; 58+ messages in thread
From: Peter Zijlstra @ 2012-09-28  9:28 UTC (permalink / raw)
  To: Stephane Eranian
  Cc: Andi Kleen, LKML, x86, Arnaldo Carvalho de Melo, Andi Kleen

On Fri, 2012-09-28 at 10:54 +0200, Stephane Eranian wrote:
> On Fri, Sep 28, 2012 at 10:43 AM, Peter Zijlstra <a.p.zijlstra@chello.nl> wrote:
> > On Thu, 2012-09-27 at 21:31 -0700, Andi Kleen wrote:
> >> +               if (event->attr.precise_ip > 1 && x86_pmu.intel_cap.pebs_format < 2) {
> >
> > Shouldn't that be: && x86_pmu.intel_cap.pebs_trap, like most other sites
> > instead? Or didn't they flip the trap capability on Haswell?
> 
> On Haswell, you get the event_ip which points to the sampled
> instruction, i.e., the off-by-one
> error can be avoided by using that value instead of pebs.rip. The nice
> side effect is that you
> free the LBR and minimize the overhead (no fixups). Therfore the LBR
> filter can have any
> setting when combined with PEBS, thus we do not need to check for
> compatibility nor force
> any setting for the LBR filter.

Yes I got that, but what good is that trap capability flag if they don't
use it? Them adding a second u64 to the format to report it seems to
suggest their trap capability is pointless, but nowhere has this been
explained.

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH 22/31] perf, core: Define generic hardware transaction events
  2012-09-28  4:31 ` [PATCH 22/31] perf, core: Define generic hardware transaction events Andi Kleen
@ 2012-09-28  9:33   ` Peter Zijlstra
  0 siblings, 0 replies; 58+ messages in thread
From: Peter Zijlstra @ 2012-09-28  9:33 UTC (permalink / raw)
  To: Andi Kleen; +Cc: linux-kernel, x86, eranian, acme, Andi Kleen

On Thu, 2012-09-27 at 21:31 -0700, Andi Kleen wrote:
> From: Andi Kleen <ak@linux.intel.com>
> 
> For tuning and debugging hardware transactional memory it is very
> important to have hardware counter support.
> 
> This patch adds a simple and hopefully generic set of hardware events
> for transactional memory and lock elision.
> 
> It is based on the TSX PMU support because I don't have any
> information on other CPU's HTM support.
> 
> There are start, commit and abort events for transactions and
> for lock elision.
> 
> The abort events are qualified by a generic abort reason that should
> be roughly applicable to a wide range of memory transaction systems:
> 
> capacity for the buffering capacity
> conflict for a dynamic conflict between CPUs
> all      for all aborts. On TSX this can be precisely sampled.
> 
> We need to split the events into general transaction events and lock
> elision events. Architecturs with HTM but no lock elision would only
> use the first set.
> 
> Implementation for Haswell in a followon patch.

I would much prefer sysfs events over yet another weird event class
here. That also solves the problem of not knowing wtf other cpus might
or might not do.

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH 26/31] perf, x86: Support for printing PMU state on spurious PMIs
  2012-09-28  4:31 ` [PATCH 26/31] perf, x86: Support for printing PMU state on spurious PMIs Andi Kleen
@ 2012-09-28  9:36   ` Peter Zijlstra
  2012-09-28 11:39     ` Stephane Eranian
  0 siblings, 1 reply; 58+ messages in thread
From: Peter Zijlstra @ 2012-09-28  9:36 UTC (permalink / raw)
  To: Andi Kleen; +Cc: linux-kernel, x86, eranian, acme, Andi Kleen

On Thu, 2012-09-27 at 21:31 -0700, Andi Kleen wrote:

> +static bool print_spurious_pmi __read_mostly;
> +module_param(print_spurious_pmi, bool, 0644);

Shouldn't this be a per-pmu sysfs attr? 

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH 01/31] perf, x86: Add PEBSv2 record support
  2012-09-28  9:28       ` Peter Zijlstra
@ 2012-09-28 11:33         ` Stephane Eranian
  0 siblings, 0 replies; 58+ messages in thread
From: Stephane Eranian @ 2012-09-28 11:33 UTC (permalink / raw)
  To: Peter Zijlstra
  Cc: Andi Kleen, LKML, x86, Arnaldo Carvalho de Melo, Andi Kleen

On Fri, Sep 28, 2012 at 11:28 AM, Peter Zijlstra <a.p.zijlstra@chello.nl> wrote:
> On Fri, 2012-09-28 at 10:54 +0200, Stephane Eranian wrote:
>> On Fri, Sep 28, 2012 at 10:43 AM, Peter Zijlstra <a.p.zijlstra@chello.nl> wrote:
>> > On Thu, 2012-09-27 at 21:31 -0700, Andi Kleen wrote:
>> >> +               if (event->attr.precise_ip > 1 && x86_pmu.intel_cap.pebs_format < 2) {
>> >
>> > Shouldn't that be: && x86_pmu.intel_cap.pebs_trap, like most other sites
>> > instead? Or didn't they flip the trap capability on Haswell?
>>
>> On Haswell, you get the event_ip which points to the sampled
>> instruction, i.e., the off-by-one
>> error can be avoided by using that value instead of pebs.rip. The nice
>> side effect is that you
>> free the LBR and minimize the overhead (no fixups). Therfore the LBR
>> filter can have any
>> setting when combined with PEBS, thus we do not need to check for
>> compatibility nor force
>> any setting for the LBR filter.
>
> Yes I got that, but what good is that trap capability flag if they don't
> use it? Them adding a second u64 to the format to report it seems to
> suggest their trap capability is pointless, but nowhere has this been
> explained.

I suspect this trap field was only meaningful for P4. Since then, the
implementation has changed and I don't think this flag is relevant anymore.
To be cautious, you could always or this (pebs_fmt > 1 || trap).

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH 04/31] perf, core: Add generic intx/intx_checkpointed counter modifiers
  2012-09-28  9:02   ` Peter Zijlstra
@ 2012-09-28 11:35     ` Stephane Eranian
  2012-09-28 14:53     ` Andi Kleen
  1 sibling, 0 replies; 58+ messages in thread
From: Stephane Eranian @ 2012-09-28 11:35 UTC (permalink / raw)
  To: Peter Zijlstra
  Cc: Andi Kleen, LKML, x86, Arnaldo Carvalho de Melo, Andi Kleen, Jiri Olsa

On Fri, Sep 28, 2012 at 11:02 AM, Peter Zijlstra <a.p.zijlstra@chello.nl> wrote:
> On Thu, 2012-09-27 at 21:31 -0700, Andi Kleen wrote:
>> +                               intx           :  1, /* count inside transaction */
>> +                               intx_checkpointed :  1, /* checkpointed in transaction */
>
> I really hate those names.. what are they called in transactional memory
> literature?
>
> Also do we really need this? Using the event format stuff we could
> equally well do:
>
> {cpu/cycles/, cpu/cycles,intx/, cpu/cycles,intx_checkpointed/}
>
> No need to push those bits through perf_event_attr::flags when you can
> stuff then through perf_event_attr::config, esp. for very hardware
> specific features.

Make sense to promote them if they exist on other arch. If not, then
for now, they
should be in sysfs. Doing this does not preclude future promotions if
there is more
architectures supporting the exact same meaning.

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH 26/31] perf, x86: Support for printing PMU state on spurious PMIs
  2012-09-28  9:36   ` Peter Zijlstra
@ 2012-09-28 11:39     ` Stephane Eranian
  0 siblings, 0 replies; 58+ messages in thread
From: Stephane Eranian @ 2012-09-28 11:39 UTC (permalink / raw)
  To: Peter Zijlstra
  Cc: Andi Kleen, LKML, x86, Arnaldo Carvalho de Melo, Andi Kleen

On Fri, Sep 28, 2012 at 11:36 AM, Peter Zijlstra <a.p.zijlstra@chello.nl> wrote:
> On Thu, 2012-09-27 at 21:31 -0700, Andi Kleen wrote:
>
>> +static bool print_spurious_pmi __read_mostly;
>> +module_param(print_spurious_pmi, bool, 0644);
>
> Shouldn't this be a per-pmu sysfs attr?

agreed.

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH 01/31] perf, x86: Add PEBSv2 record support
  2012-09-28  8:43   ` Peter Zijlstra
  2012-09-28  8:54     ` Stephane Eranian
@ 2012-09-28 14:42     ` Andi Kleen
  1 sibling, 0 replies; 58+ messages in thread
From: Andi Kleen @ 2012-09-28 14:42 UTC (permalink / raw)
  To: Peter Zijlstra; +Cc: Andi Kleen, linux-kernel, x86, eranian, acme, Andi Kleen

On Fri, Sep 28, 2012 at 10:43:04AM +0200, Peter Zijlstra wrote:
> On Thu, 2012-09-27 at 21:31 -0700, Andi Kleen wrote:
> > +               if (event->attr.precise_ip > 1 && x86_pmu.intel_cap.pebs_format < 2) {
> 
> Shouldn't that be: && x86_pmu.intel_cap.pebs_trap, like most other sites
> instead? Or didn't they flip the trap capability on Haswell?

In theory you're right, but trap wouldn't work for TSX aborts. Even if PEBS 
was a trap (it isn't) the trap would abort. Looking at the stack frame I
would get the wrong IP after the abort, not the abort event itself.

So to do the trap check would need to explicitely check for TSX abort
events too, which would be possible but fairly ugly.

If the flag ever changes could revisit this but I don't see it right
now. Also when available there's no good reason not to use EventingRip.

-andi
-- 
ak@linux.intel.com -- Speaking for myself only.

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH 04/31] perf, core: Add generic intx/intx_checkpointed counter modifiers
  2012-09-28  9:02   ` Peter Zijlstra
  2012-09-28 11:35     ` Stephane Eranian
@ 2012-09-28 14:53     ` Andi Kleen
  2012-09-28 15:19       ` Peter Zijlstra
  2012-09-28 15:23       ` Peter Zijlstra
  1 sibling, 2 replies; 58+ messages in thread
From: Andi Kleen @ 2012-09-28 14:53 UTC (permalink / raw)
  To: Peter Zijlstra
  Cc: Andi Kleen, linux-kernel, x86, eranian, acme, Andi Kleen, Jiri Olsa

On Fri, Sep 28, 2012 at 11:02:00AM +0200, Peter Zijlstra wrote:
> On Thu, 2012-09-27 at 21:31 -0700, Andi Kleen wrote:
> > +                               intx           :  1, /* count inside transaction */
> > +                               intx_checkpointed :  1, /* checkpointed in transaction */ 
> 
> I really hate those names.. what are they called in transactional memory
> literature?

Don't know of any other names. The papers I looked at normally don't
bother with PMUs.

At some point I had intx_cp, would that be better?

> Also do we really need this? Using the event format stuff we could
> equally well do:
> 
> {cpu/cycles/, cpu/cycles,intx/, cpu/cycles,intx_checkpointed/}
> 
> No need to push those bits through perf_event_attr::flags when you can
> stuff then through perf_event_attr::config, esp. for very hardware
> specific features.

I can't use config, because the qualifiers are valid for events that
already use config (like offcore). 

So would need a new field. In fact that is what I did, I reused some
unused bits.

If I moved this into sysfs this would imply that the perf stat -T 
code would become Haswell specific. As far as I understand normally
you guys don't want things like that. Would everyone be ok with
having specific code there?

The perf stat -T equations output is fairly important -- it's normally
the first thing to look at for TSX -- so I would like to keep it.

Also as a selfish reason I would prefer something that is short 
to type. The qualifiers are quite common in scripts that do
measurements here. So I would prefer to keep :t and :c as user
interface.  But the internal implementation can be adjusted 
of course.

-Andi
-- 
ak@linux.intel.com -- Speaking for myself only.

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH 18/31] perf, core: Add a concept of a weightened sample
  2012-09-28  9:06   ` Stephane Eranian
@ 2012-09-28 14:57     ` Andi Kleen
  2012-09-28 17:09       ` Stephane Eranian
  0 siblings, 1 reply; 58+ messages in thread
From: Andi Kleen @ 2012-09-28 14:57 UTC (permalink / raw)
  To: Stephane Eranian
  Cc: Andi Kleen, LKML, x86, Peter Zijlstra, Arnaldo Carvalho de Melo,
	Andi Kleen

> I came to the conclusion that yes we need something like a weight or cost
> as a generic way of reporting that in some modes the period is not really
> the right measure to evaluate the "cost" of an event.

I'm not fully sure if you're for or against it. I think
the patch is mostly orthogonal to what you're proposing

My main target is the TSX abort cost, the memory latencies 
I just added as a bonus.

> 
> I was testing my PEBS Load Latency patch this week, I came to that
> conclusion. The way perf report sorts samples based on aggregated
> periods per IP does not work for PEBS Load Latency (and possibly other
> modes). The sorting needs to be based on some cost that may be distinct
> from the period. By default, it would be the period, but for PEBS LL that
> would be the latency of the load at a specific IP. That would more reflect
> was is going on.


I originally folded the weight into nr_events, but in the end it turned
out it's fairly useful to expose both explicitely as sort keys.

In some cases you want the average weight, in others the total weight
(SUM(weight) * nr_events). I haven't tried to mess with the period
so far.

-Andi

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH 02/31] perf, x86: Basic Haswell PMU support
  2012-09-28  9:05   ` Peter Zijlstra
@ 2012-09-28 14:58     ` Andi Kleen
       [not found]       ` <CABPqkBQ90Crh+EpRQq0Y+xUvrj5vzrX_=SpJQyR4p8uFR_Hr=Q@mail.gmail.com>
  0 siblings, 1 reply; 58+ messages in thread
From: Andi Kleen @ 2012-09-28 14:58 UTC (permalink / raw)
  To: Peter Zijlstra; +Cc: Andi Kleen, linux-kernel, x86, eranian, acme, Andi Kleen

On Fri, Sep 28, 2012 at 11:05:45AM +0200, Peter Zijlstra wrote:
> On Thu, 2012-09-27 at 21:31 -0700, Andi Kleen wrote:
> >  /*
> > + * Also filter out TSX bits.
> > + */
> > +#define TSX_FIXED_EVENT_CONSTRAINT(c, n)       \
> > +       EVENT_CONSTRAINT(c, (1ULL << (32+n)),   \
> > +                        X86_RAW_EVENT_MASK|HSW_INTX|HSW_INTX_CHECKPOINTED)
> 
> How volatile are those bits? Will the re-appear in future chips or are
> they prone to get re-assigned different semantics in future chips?

Traditionally these bits have been fairly stable.

> 
> If they're 'stable' we might as well add then to FIXED_EVENT_CONSTRAINT,
> its not like those bits would ever appear on previous hardware.

Ok will do.

-Andi

-- 
ak@linux.intel.com -- Speaking for myself only.

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH 04/31] perf, core: Add generic intx/intx_checkpointed counter modifiers
  2012-09-28 14:53     ` Andi Kleen
@ 2012-09-28 15:19       ` Peter Zijlstra
  2012-09-28 15:29         ` Andi Kleen
  2012-09-28 15:23       ` Peter Zijlstra
  1 sibling, 1 reply; 58+ messages in thread
From: Peter Zijlstra @ 2012-09-28 15:19 UTC (permalink / raw)
  To: Andi Kleen; +Cc: linux-kernel, x86, eranian, acme, Andi Kleen, Jiri Olsa

On Fri, 2012-09-28 at 16:53 +0200, Andi Kleen wrote:
> If I moved this into sysfs this would imply that the perf stat -T 
> code would become Haswell specific. As far as I understand normally
> you guys don't want things like that. Would everyone be ok with
> having specific code there? 

Have a look at /sys/bus/event_source/devices/cpu/format/*, that's
already very hardware specific.

What I suggested is something like:

PMU_FORMAT_ATTR(intx, "config:32");
PMU_FORMAT_ATTR(intx_cp "config:33");

For the HSW+ cpus. That should be enough for userspace to create such
events.

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH 02/31] perf, x86: Basic Haswell PMU support
       [not found]       ` <CABPqkBQ90Crh+EpRQq0Y+xUvrj5vzrX_=SpJQyR4p8uFR_Hr=Q@mail.gmail.com>
@ 2012-09-28 15:21         ` Peter Zijlstra
  2012-09-28 15:23         ` Andi Kleen
  1 sibling, 0 replies; 58+ messages in thread
From: Peter Zijlstra @ 2012-09-28 15:21 UTC (permalink / raw)
  To: Stephane Eranian; +Cc: Andi Kleen, Andi Kleen, LKML, acme, x86

On Fri, 2012-09-28 at 17:14 +0200, Stephane Eranian wrote:
> But then what happens if I pass a raw value that sets those bits on a
> processor without TSX?

We could filter those bits depending on cpu_has_rtm && cpu_has_hle on
event creation.

But fixed event constraints could include superfluous bits just fine,
they'll never appear.

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH 02/31] perf, x86: Basic Haswell PMU support
       [not found]       ` <CABPqkBQ90Crh+EpRQq0Y+xUvrj5vzrX_=SpJQyR4p8uFR_Hr=Q@mail.gmail.com>
  2012-09-28 15:21         ` Peter Zijlstra
@ 2012-09-28 15:23         ` Andi Kleen
  1 sibling, 0 replies; 58+ messages in thread
From: Andi Kleen @ 2012-09-28 15:23 UTC (permalink / raw)
  To: Stephane Eranian; +Cc: Andi Kleen, Andi Kleen, LKML, acme, x86, Peter Zijlstra

On Fri, Sep 28, 2012 at 05:14:18PM +0200, Stephane Eranian wrote:
> But then what happens if I pass a raw value that sets those bits on a
> processor without TSX?

It should be filtered out. It could #GP otherwise. I thought I checked 
that, but will test again.

-Andi
> 
> On Sep 28, 2012 4:58 PM, "Andi Kleen" <andi@firstfloor.org> wrote:

-- 
ak@linux.intel.com -- Speaking for myself only.

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH 04/31] perf, core: Add generic intx/intx_checkpointed counter modifiers
  2012-09-28 14:53     ` Andi Kleen
  2012-09-28 15:19       ` Peter Zijlstra
@ 2012-09-28 15:23       ` Peter Zijlstra
  2012-09-28 15:37         ` Andi Kleen
  1 sibling, 1 reply; 58+ messages in thread
From: Peter Zijlstra @ 2012-09-28 15:23 UTC (permalink / raw)
  To: Andi Kleen; +Cc: linux-kernel, x86, eranian, acme, Andi Kleen, Jiri Olsa

On Fri, 2012-09-28 at 16:53 +0200, Andi Kleen wrote:
> 
> Also as a selfish reason I would prefer something that is short 
> to type. The qualifiers are quite common in scripts that do
> measurements here. So I would prefer to keep :t and :c as user
> interface.  But the internal implementation can be adjusted 
> of course. 

But since its so very specific to HSW consuming such limited resources
as event attribute characters seems like a bad idea.

Maybe we can allow some configuration on the userspace side that would
allow each individual user to be lazy and create shortcuts or aliasses
of some sort ?

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH 04/31] perf, core: Add generic intx/intx_checkpointed counter modifiers
  2012-09-28 15:19       ` Peter Zijlstra
@ 2012-09-28 15:29         ` Andi Kleen
  2012-09-28 15:36           ` Peter Zijlstra
  0 siblings, 1 reply; 58+ messages in thread
From: Andi Kleen @ 2012-09-28 15:29 UTC (permalink / raw)
  To: Peter Zijlstra
  Cc: Andi Kleen, linux-kernel, x86, eranian, acme, Andi Kleen, Jiri Olsa

On Fri, Sep 28, 2012 at 05:19:19PM +0200, Peter Zijlstra wrote:
> On Fri, 2012-09-28 at 16:53 +0200, Andi Kleen wrote:
> > If I moved this into sysfs this would imply that the perf stat -T 
> > code would become Haswell specific. As far as I understand normally
> > you guys don't want things like that. Would everyone be ok with
> > having specific code there? 
> 
> Have a look at /sys/bus/event_source/devices/cpu/format/*, that's
> already very hardware specific.
> 
> What I suggested is something like:
> 
> PMU_FORMAT_ATTR(intx, "config:32");
> PMU_FORMAT_ATTR(intx_cp "config:33");
> 
> For the HSW+ cpus. That should be enough for userspace to create such
> events.

Still would need new fields, but I presume that could be fit in.

perf stat -T uses these qualifiers and computes some derived
metrics. This would become HSW specific code which has to assume
HSW sysfs events.  Is everyone ok with that?

I also still would like the :t, :c shortcuts, but those could be probably
just hardcoded.

-Andi

-- 
ak@linux.intel.com -- Speaking for myself only.

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH 04/31] perf, core: Add generic intx/intx_checkpointed counter modifiers
  2012-09-28 15:29         ` Andi Kleen
@ 2012-09-28 15:36           ` Peter Zijlstra
  0 siblings, 0 replies; 58+ messages in thread
From: Peter Zijlstra @ 2012-09-28 15:36 UTC (permalink / raw)
  To: Andi Kleen; +Cc: linux-kernel, x86, eranian, acme, Andi Kleen, Jiri Olsa

On Fri, 2012-09-28 at 17:29 +0200, Andi Kleen wrote:
> Still would need new fields, but I presume that could be fit in.
> 
Very much so, for all except the P4 PMU the first config is directly
mapped to the perfctl msr.

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH 04/31] perf, core: Add generic intx/intx_checkpointed counter modifiers
  2012-09-28 15:23       ` Peter Zijlstra
@ 2012-09-28 15:37         ` Andi Kleen
  0 siblings, 0 replies; 58+ messages in thread
From: Andi Kleen @ 2012-09-28 15:37 UTC (permalink / raw)
  To: Peter Zijlstra
  Cc: Andi Kleen, linux-kernel, x86, eranian, acme, Andi Kleen, Jiri Olsa

On Fri, Sep 28, 2012 at 05:23:27PM +0200, Peter Zijlstra wrote:
> On Fri, 2012-09-28 at 16:53 +0200, Andi Kleen wrote:
> > 
> > Also as a selfish reason I would prefer something that is short 
> > to type. The qualifiers are quite common in scripts that do
> > measurements here. So I would prefer to keep :t and :c as user
> > interface.  But the internal implementation can be adjusted 
> > of course. 
> 
> But since its so very specific to HSW consuming such limited resources

We still have quite a few letters in the Latin alphabet :)

I assume any CPU with TSX will have something like that. PMU is model 
specific, but it's obviously something that is needed. So I wouldn't 
really call it HSW specific. Something like this will be likely
in many Intel CPUs going forward. 

Also I don't know for sure but it wouldn't surprise me if the other
CPUs with transactions (BG etc.) have something similar.

> 
> Maybe we can allow some configuration on the userspace side that would
> allow each individual user to be lazy and create shortcuts or aliasses
> of some sort ?

That would likely be a logistical nightmare. You could never send
a measurement script to someone else.

-Andi
-- 
ak@linux.intel.com -- Speaking for myself only.

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH 18/31] perf, core: Add a concept of a weightened sample
  2012-09-28 14:57     ` Andi Kleen
@ 2012-09-28 17:09       ` Stephane Eranian
  0 siblings, 0 replies; 58+ messages in thread
From: Stephane Eranian @ 2012-09-28 17:09 UTC (permalink / raw)
  To: Andi Kleen
  Cc: LKML, x86, Peter Zijlstra, Arnaldo Carvalho de Melo, Andi Kleen

On Fri, Sep 28, 2012 at 4:57 PM, Andi Kleen <andi@firstfloor.org> wrote:
>> I came to the conclusion that yes we need something like a weight or cost
>> as a generic way of reporting that in some modes the period is not really
>> the right measure to evaluate the "cost" of an event.
>
> I'm not fully sure if you're for or against it. I think
> the patch is mostly orthogonal to what you're proposing
>
I am for it. It does not have to be specific to TSX or PEBS-LL.
I have one form of it in my PEBS-LL patch. And yes, it appears
as a sort key (for memory sampling mode only right now).

> My main target is the TSX abort cost, the memory latencies
> I just added as a bonus.
>
>>
>> I was testing my PEBS Load Latency patch this week, I came to that
>> conclusion. The way perf report sorts samples based on aggregated
>> periods per IP does not work for PEBS Load Latency (and possibly other
>> modes). The sorting needs to be based on some cost that may be distinct
>> from the period. By default, it would be the period, but for PEBS LL that
>> would be the latency of the load at a specific IP. That would more reflect
>> was is going on.
>
>
> I originally folded the weight into nr_events, but in the end it turned
> out it's fairly useful to expose both explicitely as sort keys.
>
> In some cases you want the average weight, in others the total weight
> (SUM(weight) * nr_events). I haven't tried to mess with the period
> so far.
>
> -Andi

^ permalink raw reply	[flat|nested] 58+ messages in thread

end of thread, other threads:[~2012-09-28 17:09 UTC | newest]

Thread overview: 58+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-09-28  4:31 perf PMU support for Haswell Andi Kleen
2012-09-28  4:31 ` [PATCH 01/31] perf, x86: Add PEBSv2 record support Andi Kleen
2012-09-28  8:43   ` Peter Zijlstra
2012-09-28  8:54     ` Stephane Eranian
2012-09-28  9:28       ` Peter Zijlstra
2012-09-28 11:33         ` Stephane Eranian
2012-09-28 14:42     ` Andi Kleen
2012-09-28  4:31 ` [PATCH 02/31] perf, x86: Basic Haswell PMU support Andi Kleen
2012-09-28  9:05   ` Peter Zijlstra
2012-09-28 14:58     ` Andi Kleen
     [not found]       ` <CABPqkBQ90Crh+EpRQq0Y+xUvrj5vzrX_=SpJQyR4p8uFR_Hr=Q@mail.gmail.com>
2012-09-28 15:21         ` Peter Zijlstra
2012-09-28 15:23         ` Andi Kleen
2012-09-28  4:31 ` [PATCH 03/31] perf, x86: Basic Haswell PEBS support Andi Kleen
2012-09-28  8:50   ` Peter Zijlstra
2012-09-28  4:31 ` [PATCH 04/31] perf, core: Add generic intx/intx_checkpointed counter modifiers Andi Kleen
2012-09-28  9:02   ` Peter Zijlstra
2012-09-28 11:35     ` Stephane Eranian
2012-09-28 14:53     ` Andi Kleen
2012-09-28 15:19       ` Peter Zijlstra
2012-09-28 15:29         ` Andi Kleen
2012-09-28 15:36           ` Peter Zijlstra
2012-09-28 15:23       ` Peter Zijlstra
2012-09-28 15:37         ` Andi Kleen
2012-09-28  4:31 ` [PATCH 05/31] perf, tools: Add :c,:t event modifiers in perf tools Andi Kleen
2012-09-28  4:31 ` [PATCH 06/31] perf, tools: Add intx/intx_checkpoint to perf script and header printing Andi Kleen
2012-09-28  4:31 ` [PATCH 07/31] perf, x86: Implement the :t and :c qualifiers for Haswell Andi Kleen
2012-09-28  4:31 ` [PATCH 08/31] perf, x86: Report PEBS event in a raw format Andi Kleen
2012-09-28  8:54   ` Peter Zijlstra
2012-09-28  8:57     ` Stephane Eranian
2012-09-28  4:31 ` [PATCH 09/31] perf, kvm: Support :t and :c perf modifiers in KVM arch perfmon emulation Andi Kleen
2012-09-28  4:31 ` [PATCH 10/31] perf, x86: Support PERF_SAMPLE_ADDR on Haswell Andi Kleen
2012-09-28  4:31 ` [PATCH 11/31] perf, x86: Support Haswell v4 LBR format Andi Kleen
2012-09-28  4:31 ` [PATCH 12/31] perf, x86: Disable LBR recording for unknown LBR_FMT Andi Kleen
2012-09-28  4:31 ` [PATCH 13/31] perf, x86: Support LBR filtering by INTX/NOTX/ABORT Andi Kleen
2012-09-28  4:31 ` [PATCH 14/31] perf, tools: Add abort,notx,intx branch filter options to perf report -j Andi Kleen
2012-09-28  4:31 ` [PATCH 15/31] perf, tools: Support sorting by intx, abort branch flags Andi Kleen
2012-09-28  4:31 ` [PATCH 16/31] perf, x86: Support full width counting on Haswell Andi Kleen
2012-09-28  4:31 ` [PATCH 17/31] perf, x86: Avoid checkpointed counters causing excessive TSX aborts Andi Kleen
2012-09-28  4:31 ` [PATCH 18/31] perf, core: Add a concept of a weightened sample Andi Kleen
2012-09-28  9:06   ` Stephane Eranian
2012-09-28 14:57     ` Andi Kleen
2012-09-28 17:09       ` Stephane Eranian
2012-09-28  4:31 ` [PATCH 19/31] perf, x86: Support weight samples for PEBS Andi Kleen
2012-09-28  4:31 ` [PATCH 20/31] perf, tools: Add support for weight Andi Kleen
2012-09-28  4:31 ` [PATCH 21/31] perf, tools: Handle XBEGIN like a jump Andi Kleen
2012-09-28  4:31 ` [PATCH 22/31] perf, core: Define generic hardware transaction events Andi Kleen
2012-09-28  9:33   ` Peter Zijlstra
2012-09-28  4:31 ` [PATCH 23/31] perf, tools: Add support for generic transaction events to perf userspace Andi Kleen
2012-09-28  4:31 ` [PATCH 24/31] perf, x86: Add the Haswell implementation of the generic transaction events Andi Kleen
2012-09-28  4:31 ` [PATCH 25/31] perf, tools: Add perf stat --transaction Andi Kleen
2012-09-28  4:31 ` [PATCH 26/31] perf, x86: Support for printing PMU state on spurious PMIs Andi Kleen
2012-09-28  9:36   ` Peter Zijlstra
2012-09-28 11:39     ` Stephane Eranian
2012-09-28  4:31 ` [PATCH 27/31] perf, core: Add generic transaction flags Andi Kleen
2012-09-28  4:31 ` [PATCH 28/31] perf, x86: Add Haswell specific transaction flag reporting Andi Kleen
2012-09-28  4:31 ` [PATCH 29/31] perf, tools: Add support for record transaction flags Andi Kleen
2012-09-28  4:31 ` [PATCH 30/31] perf, tools: Point --sort documentation to --help Andi Kleen
2012-09-28  4:31 ` [PATCH 31/31] perf, tools: Add browser support for transaction flags Andi Kleen

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).