All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/5] PEBS and LBR fixes
@ 2010-03-05 15:39 Peter Zijlstra
  2010-03-05 15:39 ` [PATCH 1/5] perf: Rework the arch CPU-hotplug hooks Peter Zijlstra
                   ` (4 more replies)
  0 siblings, 5 replies; 23+ messages in thread
From: Peter Zijlstra @ 2010-03-05 15:39 UTC (permalink / raw)
  To: mingo, linux-kernel
  Cc: paulus, eranian, robert.richter, fweisbec,
	Arnaldo Carvalho de Melo, Peter Zijlstra

With these patches PEBS also works on my Core2 machines, although
sometimes it fails to generate samples for some reason, so there's more
errata to read.


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

* [PATCH 1/5] perf: Rework the arch CPU-hotplug hooks
  2010-03-05 15:39 [PATCH 0/5] PEBS and LBR fixes Peter Zijlstra
@ 2010-03-05 15:39 ` Peter Zijlstra
  2010-03-10 13:10   ` [tip:perf/urgent] perf: Rework and fix " tip-bot for Peter Zijlstra
  2010-03-05 15:39 ` [PATCH 2/5] perf, x86: Fix silly bug in data store buffer allocation Peter Zijlstra
                   ` (3 subsequent siblings)
  4 siblings, 1 reply; 23+ messages in thread
From: Peter Zijlstra @ 2010-03-05 15:39 UTC (permalink / raw)
  To: mingo, linux-kernel
  Cc: paulus, eranian, robert.richter, fweisbec,
	Arnaldo Carvalho de Melo, Peter Zijlstra, Paul Mundt

[-- Attachment #1: perf-rework-cpuhotplug.patch --]
[-- Type: text/plain, Size: 12140 bytes --]

Remove the hw_perf_event_*() hotplug hooks in favour of per PMU hotplug
notifiers. This has the advantage of reducing the static weak interface
as well as exposing all hotplug actions to the PMU.

Use this to fix x86 hotplug usage where we did things in ONLINE which
should have been done in UP_PREPARE or STARTING.

CC: Paul Mackerras <paulus@samba.org>
CC: Paul Mundt <lethal@linux-sh.org>
Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
---
 arch/powerpc/kernel/perf_event.c          |   21 +++++++++
 arch/sh/kernel/perf_event.c               |   20 ++++++++-
 arch/x86/kernel/cpu/perf_event.c          |   66 ++++++++++++++++++------------
 arch/x86/kernel/cpu/perf_event_amd.c      |   60 +++++++++++----------------
 arch/x86/kernel/cpu/perf_event_intel.c    |    5 +-
 arch/x86/kernel/cpu/perf_event_intel_ds.c |    4 -
 include/linux/perf_event.h                |   16 +++++++
 kernel/perf_event.c                       |   29 -------------
 8 files changed, 127 insertions(+), 94 deletions(-)

Index: linux-2.6/arch/powerpc/kernel/perf_event.c
===================================================================
--- linux-2.6.orig/arch/powerpc/kernel/perf_event.c
+++ linux-2.6/arch/powerpc/kernel/perf_event.c
@@ -1287,7 +1287,7 @@ static void perf_event_interrupt(struct 
 		irq_exit();
 }
 
-void hw_perf_event_setup(int cpu)
+static void power_pmu_setup(int cpu)
 {
 	struct cpu_hw_events *cpuhw = &per_cpu(cpu_hw_events, cpu);
 
@@ -1297,6 +1297,23 @@ void hw_perf_event_setup(int cpu)
 	cpuhw->mmcr[0] = MMCR0_FC;
 }
 
+static int __cpuinit
+power_pmu_notify(struct notifier_block *self, unsigned long action, void *hcpu)
+{
+	unsigned int cpu = (long)hcpu;
+
+	switch (action & ~CPU_TASKS_FROZEN) {
+	case CPU_UP_PREPARE:
+		power_pmu_setup(cpu);
+		break;
+
+	default:
+		break;
+	}
+
+	return NOTIFY_OK;
+}
+
 int register_power_pmu(struct power_pmu *pmu)
 {
 	if (ppmu)
@@ -1314,5 +1331,7 @@ int register_power_pmu(struct power_pmu 
 		freeze_events_kernel = MMCR0_FCHV;
 #endif /* CONFIG_PPC64 */
 
+	perf_cpu_notifier(power_pmu_notifier);
+
 	return 0;
 }
Index: linux-2.6/arch/sh/kernel/perf_event.c
===================================================================
--- linux-2.6.orig/arch/sh/kernel/perf_event.c
+++ linux-2.6/arch/sh/kernel/perf_event.c
@@ -275,13 +275,30 @@ const struct pmu *hw_perf_event_init(str
 	return &pmu;
 }
 
-void hw_perf_event_setup(int cpu)
+static void sh_pmu_setup(int cpu)
 {
 	struct cpu_hw_events *cpuhw = &per_cpu(cpu_hw_events, cpu);
 
 	memset(cpuhw, 0, sizeof(struct cpu_hw_events));
 }
 
+static int __cpuinit
+sh_pmu_notifier(struct notifier_block *self, unsigned long action, void *hcpu)
+{
+	unsigned int cpu = (long)hcpu;
+
+	switch (action & ~CPU_TASKS_FROZEN) {
+	case CPU_UP_PREPARE:
+		sh_pmu_setup(cpu);
+		break;
+
+	default:
+		break;
+	}
+
+	return NOTIFY_OK;
+}
+
 void hw_perf_enable(void)
 {
 	if (!sh_pmu_initialized())
@@ -308,5 +325,6 @@ int register_sh_pmu(struct sh_pmu *pmu)
 
 	WARN_ON(pmu->num_events > MAX_HWEVENTS);
 
+	perf_cpu_notifier(sh_pmu_notifier);
 	return 0;
 }
Index: linux-2.6/arch/x86/kernel/cpu/perf_event.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/cpu/perf_event.c
+++ linux-2.6/arch/x86/kernel/cpu/perf_event.c
@@ -198,6 +198,11 @@ struct x86_pmu {
 						 struct perf_event *event);
 	struct event_constraint *event_constraints;
 
+	void		(*cpu_prepare)(int cpu);
+	void		(*cpu_starting)(int cpu);
+	void		(*cpu_dying)(int cpu);
+	void		(*cpu_dead)(int cpu);
+
 	/*
 	 * Intel Arch Perfmon v2+
 	 */
@@ -1306,6 +1311,39 @@ undo:
 #include "perf_event_intel_ds.c"
 #include "perf_event_intel.c"
 
+static int __cpuinit
+x86_pmu_notifier(struct notifier_block *self, unsigned long action, void *hcpu)
+{
+	unsigned int cpu = (long)hcpu;
+
+	switch (action & ~CPU_TASKS_FROZEN) {
+	case CPU_UP_PREPARE:
+		if (x86_pmu.cpu_prepare)
+			x86_pmu.cpu_prepare(cpu);
+		break;
+
+	case CPU_STARTING:
+		if (x86_pmu.cpu_starting)
+			x86_pmu.cpu_starting(cpu);
+		break;
+
+	case CPU_DYING:
+		if (x86_pmu.cpu_dying)
+			x86_pmu.cpu_dying(cpu);
+		break;
+
+	case CPU_DEAD:
+		if (x86_pmu.cpu_dead)
+			x86_pmu.cpu_dead(cpu);
+		break;
+
+	default:
+		break;
+	}
+
+	return NOTIFY_OK;
+}
+
 static void __init pmu_check_apic(void)
 {
 	if (cpu_has_apic)
@@ -1384,6 +1422,8 @@ void __init init_hw_perf_events(void)
 	pr_info("... max period:             %016Lx\n", x86_pmu.max_period);
 	pr_info("... fixed-purpose events:   %d\n",     x86_pmu.num_events_fixed);
 	pr_info("... event mask:             %016Lx\n", perf_event_mask);
+
+	perf_cpu_notifier(x86_pmu_notifier);
 }
 
 static inline void x86_pmu_read(struct perf_event *event)
@@ -1636,29 +1676,3 @@ struct perf_callchain_entry *perf_callch
 
 	return entry;
 }
-
-void hw_perf_event_setup_online(int cpu)
-{
-	init_debug_store_on_cpu(cpu);
-
-	switch (boot_cpu_data.x86_vendor) {
-	case X86_VENDOR_AMD:
-		amd_pmu_cpu_online(cpu);
-		break;
-	default:
-		return;
-	}
-}
-
-void hw_perf_event_setup_offline(int cpu)
-{
-	init_debug_store_on_cpu(cpu);
-
-	switch (boot_cpu_data.x86_vendor) {
-	case X86_VENDOR_AMD:
-		amd_pmu_cpu_offline(cpu);
-		break;
-	default:
-		return;
-	}
-}
Index: linux-2.6/arch/x86/kernel/cpu/perf_event_amd.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/cpu/perf_event_amd.c
+++ linux-2.6/arch/x86/kernel/cpu/perf_event_amd.c
@@ -271,28 +271,6 @@ done:
 	return &emptyconstraint;
 }
 
-static __initconst struct x86_pmu amd_pmu = {
-	.name			= "AMD",
-	.handle_irq		= x86_pmu_handle_irq,
-	.disable_all		= x86_pmu_disable_all,
-	.enable_all		= x86_pmu_enable_all,
-	.enable			= x86_pmu_enable_event,
-	.disable		= x86_pmu_disable_event,
-	.eventsel		= MSR_K7_EVNTSEL0,
-	.perfctr		= MSR_K7_PERFCTR0,
-	.event_map		= amd_pmu_event_map,
-	.raw_event		= amd_pmu_raw_event,
-	.max_events		= ARRAY_SIZE(amd_perfmon_event_map),
-	.num_events		= 4,
-	.event_bits		= 48,
-	.event_mask		= (1ULL << 48) - 1,
-	.apic			= 1,
-	/* use highest bit to detect overflow */
-	.max_period		= (1ULL << 47) - 1,
-	.get_event_constraints	= amd_get_event_constraints,
-	.put_event_constraints	= amd_put_event_constraints
-};
-
 static struct amd_nb *amd_alloc_nb(int cpu, int nb_id)
 {
 	struct amd_nb *nb;
@@ -378,6 +356,31 @@ static void amd_pmu_cpu_offline(int cpu)
 	raw_spin_unlock(&amd_nb_lock);
 }
 
+static __initconst struct x86_pmu amd_pmu = {
+	.name			= "AMD",
+	.handle_irq		= x86_pmu_handle_irq,
+	.disable_all		= x86_pmu_disable_all,
+	.enable_all		= x86_pmu_enable_all,
+	.enable			= x86_pmu_enable_event,
+	.disable		= x86_pmu_disable_event,
+	.eventsel		= MSR_K7_EVNTSEL0,
+	.perfctr		= MSR_K7_PERFCTR0,
+	.event_map		= amd_pmu_event_map,
+	.raw_event		= amd_pmu_raw_event,
+	.max_events		= ARRAY_SIZE(amd_perfmon_event_map),
+	.num_events		= 4,
+	.event_bits		= 48,
+	.event_mask		= (1ULL << 48) - 1,
+	.apic			= 1,
+	/* use highest bit to detect overflow */
+	.max_period		= (1ULL << 47) - 1,
+	.get_event_constraints	= amd_get_event_constraints,
+	.put_event_constraints	= amd_put_event_constraints,
+
+	.cpu_prepare		= amd_pmu_cpu_online,
+	.cpu_dead		= amd_pmu_cpu_offline,
+};
+
 static __init int amd_pmu_init(void)
 {
 	/* Performance-monitoring supported from K7 and later: */
@@ -390,11 +393,6 @@ static __init int amd_pmu_init(void)
 	memcpy(hw_cache_event_ids, amd_hw_cache_event_ids,
 	       sizeof(hw_cache_event_ids));
 
-	/*
-	 * explicitly initialize the boot cpu, other cpus will get
-	 * the cpu hotplug callbacks from smp_init()
-	 */
-	amd_pmu_cpu_online(smp_processor_id());
 	return 0;
 }
 
@@ -405,12 +403,4 @@ static int amd_pmu_init(void)
 	return 0;
 }
 
-static void amd_pmu_cpu_online(int cpu)
-{
-}
-
-static void amd_pmu_cpu_offline(int cpu)
-{
-}
-
 #endif
Index: linux-2.6/arch/x86/kernel/cpu/perf_event_intel.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/cpu/perf_event_intel.c
+++ linux-2.6/arch/x86/kernel/cpu/perf_event_intel.c
@@ -794,7 +794,10 @@ static __initconst struct x86_pmu intel_
 	 * the generic event period:
 	 */
 	.max_period		= (1ULL << 31) - 1,
-	.get_event_constraints	= intel_get_event_constraints
+	.get_event_constraints	= intel_get_event_constraints,
+
+	.cpu_starting		= init_debug_store_on_cpu,
+	.cpu_dying		= fini_debug_store_on_cpu,
 };
 
 static __init int intel_pmu_init(void)
Index: linux-2.6/arch/x86/kernel/cpu/perf_event_intel_ds.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/cpu/perf_event_intel_ds.c
+++ linux-2.6/arch/x86/kernel/cpu/perf_event_intel_ds.c
@@ -63,7 +63,7 @@ struct debug_store {
 	u64	pebs_event_reset[MAX_PEBS_EVENTS];
 };
 
-static inline void init_debug_store_on_cpu(int cpu)
+static void init_debug_store_on_cpu(int cpu)
 {
 	struct debug_store *ds = per_cpu(cpu_hw_events, cpu).ds;
 
@@ -75,7 +75,7 @@ static inline void init_debug_store_on_c
 		     (u32)((u64)(unsigned long)ds >> 32));
 }
 
-static inline void fini_debug_store_on_cpu(int cpu)
+static void fini_debug_store_on_cpu(int cpu)
 {
 	if (!per_cpu(cpu_hw_events, cpu).ds)
 		return;
Index: linux-2.6/include/linux/perf_event.h
===================================================================
--- linux-2.6.orig/include/linux/perf_event.h
+++ linux-2.6/include/linux/perf_event.h
@@ -961,5 +961,21 @@ static inline void perf_event_disable(st
 #define perf_output_put(handle, x) \
 	perf_output_copy((handle), &(x), sizeof(x))
 
+/*
+ * This has to have a higher priority than migration_notifier in sched.c.
+ */
+#define perf_cpu_notifier(fn) 					\
+do {								\
+	static struct notifier_block fn##_nb __cpuinitdata =	\
+		{ .notifier_call = fn, .priority = 20 };	\
+	fn(&fn##_nb, (unsigned long)CPU_UP_PREPARE,		\
+		(void *)(unsigned long)smp_processor_id());	\
+	fn(&fn##_nb, (unsigned long)CPU_STARTING,		\
+		(void *)(unsigned long)smp_processor_id());	\
+	fn(&fn##_nb, (unsigned long)CPU_ONLINE,			\
+		(void *)(unsigned long)smp_processor_id());	\
+	register_cpu_notifier(&fn##_nb);			\
+} while (0)
+
 #endif /* __KERNEL__ */
 #endif /* _LINUX_PERF_EVENT_H */
Index: linux-2.6/kernel/perf_event.c
===================================================================
--- linux-2.6.orig/kernel/perf_event.c
+++ linux-2.6/kernel/perf_event.c
@@ -81,10 +81,6 @@ extern __weak const struct pmu *hw_perf_
 void __weak hw_perf_disable(void)		{ barrier(); }
 void __weak hw_perf_enable(void)		{ barrier(); }
 
-void __weak hw_perf_event_setup(int cpu)	{ barrier(); }
-void __weak hw_perf_event_setup_online(int cpu)	{ barrier(); }
-void __weak hw_perf_event_setup_offline(int cpu)	{ barrier(); }
-
 int __weak
 hw_perf_group_sched_in(struct perf_event *group_leader,
 	       struct perf_cpu_context *cpuctx,
@@ -5404,8 +5400,6 @@ static void __cpuinit perf_event_init_cp
 	spin_lock(&perf_resource_lock);
 	cpuctx->max_pertask = perf_max_events - perf_reserved_percpu;
 	spin_unlock(&perf_resource_lock);
-
-	hw_perf_event_setup(cpu);
 }
 
 #ifdef CONFIG_HOTPLUG_CPU
@@ -5445,20 +5439,11 @@ perf_cpu_notify(struct notifier_block *s
 		perf_event_init_cpu(cpu);
 		break;
 
-	case CPU_ONLINE:
-	case CPU_ONLINE_FROZEN:
-		hw_perf_event_setup_online(cpu);
-		break;
-
 	case CPU_DOWN_PREPARE:
 	case CPU_DOWN_PREPARE_FROZEN:
 		perf_event_exit_cpu(cpu);
 		break;
 
-	case CPU_DEAD:
-		hw_perf_event_setup_offline(cpu);
-		break;
-
 	default:
 		break;
 	}
@@ -5466,21 +5451,9 @@ perf_cpu_notify(struct notifier_block *s
 	return NOTIFY_OK;
 }
 
-/*
- * This has to have a higher priority than migration_notifier in sched.c.
- */
-static struct notifier_block __cpuinitdata perf_cpu_nb = {
-	.notifier_call		= perf_cpu_notify,
-	.priority		= 20,
-};
-
 void __init perf_event_init(void)
 {
-	perf_cpu_notify(&perf_cpu_nb, (unsigned long)CPU_UP_PREPARE,
-			(void *)(long)smp_processor_id());
-	perf_cpu_notify(&perf_cpu_nb, (unsigned long)CPU_ONLINE,
-			(void *)(long)smp_processor_id());
-	register_cpu_notifier(&perf_cpu_nb);
+	perf_cpu_notifier(perf_cpu_notify);
 }
 
 static ssize_t perf_show_reserve_percpu(struct sysdev_class *class, char *buf)

-- 


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

* [PATCH 2/5] perf, x86: Fix silly bug in data store buffer allocation
  2010-03-05 15:39 [PATCH 0/5] PEBS and LBR fixes Peter Zijlstra
  2010-03-05 15:39 ` [PATCH 1/5] perf: Rework the arch CPU-hotplug hooks Peter Zijlstra
@ 2010-03-05 15:39 ` Peter Zijlstra
  2010-03-10 13:20   ` [tip:perf/pebs] " tip-bot for Peter Zijlstra
  2010-03-05 15:39 ` [PATCH 3/5] perf, x86: Disable PEBS on clowertown chips Peter Zijlstra
                   ` (2 subsequent siblings)
  4 siblings, 1 reply; 23+ messages in thread
From: Peter Zijlstra @ 2010-03-05 15:39 UTC (permalink / raw)
  To: mingo, linux-kernel
  Cc: paulus, eranian, robert.richter, fweisbec,
	Arnaldo Carvalho de Melo, Peter Zijlstra

[-- Attachment #1: perf-fixup-intel-ds.patch --]
[-- Type: text/plain, Size: 762 bytes --]

Fix up the ds allocation error path, where we could free @buffer
before we used it.

Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
---
 arch/x86/kernel/cpu/perf_event_intel_ds.c |    4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

Index: linux-2.6/arch/x86/kernel/cpu/perf_event_intel_ds.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/cpu/perf_event_intel_ds.c
+++ linux-2.6/arch/x86/kernel/cpu/perf_event_intel_ds.c
@@ -127,10 +127,8 @@ static int reserve_ds_buffers(void)
 
 		err = -ENOMEM;
 		ds = kzalloc(sizeof(*ds), GFP_KERNEL);
-		if (unlikely(!ds)) {
-			kfree(buffer);
+		if (unlikely(!ds))
 			break;
-		}
 		per_cpu(cpu_hw_events, cpu).ds = ds;
 
 		if (x86_pmu.bts) {

-- 


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

* [PATCH 3/5] perf, x86: Disable PEBS on clowertown chips
  2010-03-05 15:39 [PATCH 0/5] PEBS and LBR fixes Peter Zijlstra
  2010-03-05 15:39 ` [PATCH 1/5] perf: Rework the arch CPU-hotplug hooks Peter Zijlstra
  2010-03-05 15:39 ` [PATCH 2/5] perf, x86: Fix silly bug in data store buffer allocation Peter Zijlstra
@ 2010-03-05 15:39 ` Peter Zijlstra
  2010-03-05 18:58   ` Stephane Eranian
  2010-03-10 13:21   ` [tip:perf/pebs] perf, x86: Disable PEBS on clovertown chips tip-bot for Peter Zijlstra
  2010-03-05 15:39 ` [PATCH 4/5] perf, x86: Clear the LBRs on init Peter Zijlstra
  2010-03-05 15:39 ` [PATCH 5/5] perf, x86: Robustify PEBS fixup Peter Zijlstra
  4 siblings, 2 replies; 23+ messages in thread
From: Peter Zijlstra @ 2010-03-05 15:39 UTC (permalink / raw)
  To: mingo, linux-kernel
  Cc: paulus, eranian, robert.richter, fweisbec,
	Arnaldo Carvalho de Melo, Peter Zijlstra

[-- Attachment #1: pebs-errata.patch --]
[-- Type: text/plain, Size: 2822 bytes --]

This CPU has just too many handycaps to be really useful.

Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
---
 arch/x86/kernel/cpu/perf_event.c       |    4 ++++
 arch/x86/kernel/cpu/perf_event_intel.c |   27 +++++++++++++++++++++++++++
 2 files changed, 31 insertions(+)

Index: linux-2.6/arch/x86/kernel/cpu/perf_event.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/cpu/perf_event.c
+++ linux-2.6/arch/x86/kernel/cpu/perf_event.c
@@ -197,6 +197,7 @@ struct x86_pmu {
 	void		(*put_event_constraints)(struct cpu_hw_events *cpuc,
 						 struct perf_event *event);
 	struct event_constraint *event_constraints;
+	void		(*quirks)(void);
 
 	void		(*cpu_prepare)(int cpu);
 	void		(*cpu_starting)(int cpu);
@@ -1380,6 +1381,9 @@ void __init init_hw_perf_events(void)
 
 	pr_cont("%s PMU driver.\n", x86_pmu.name);
 
+	if (x86_pmu.quirks)
+		x86_pmu.quirks();
+
 	if (x86_pmu.num_events > X86_PMC_MAX_GENERIC) {
 		WARN(1, KERN_ERR "hw perf events %d > max(%d), clipping!",
 		     x86_pmu.num_events, X86_PMC_MAX_GENERIC);
Index: linux-2.6/arch/x86/kernel/cpu/perf_event_intel.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/cpu/perf_event_intel.c
+++ linux-2.6/arch/x86/kernel/cpu/perf_event_intel.c
@@ -800,6 +800,32 @@ static __initconst struct x86_pmu intel_
 	.cpu_dying		= fini_debug_store_on_cpu,
 };
 
+static void intel_clowertown_quirks(void)
+{
+	/*
+	 * PEBS is unreliable due to:
+	 *
+	 *   AJ67  - PEBS may experience CPL leaks
+	 *   AJ68  - PEBS PMI may be delayed by one event
+	 *   AJ69  - GLOBAL_STATUS[62] will only be set when DEBUGCTL[12]
+	 *   AJ106 - FREEZE_LBRS_ON_PMI doesn't work in combination with PEBS
+	 *
+	 * AJ67 could be worked around by restricting the OS/USR flags.
+	 * AJ69 could be worked around by setting PMU_FREEZE_ON_PMI.
+	 *
+	 * AJ106 could possibly be worked around by not allowing LBR
+	 *       usage from PEBS, including the fixup.
+	 * AJ68  could possibly be worked around by always programming
+	 * 	 a pebs_event_reset[0] value and coping with the lost events.
+	 *
+	 * But taken together it might just make sense to not enable PEBS on
+	 * these chips.
+	 */
+	printk(KERN_WARNING "PEBS disabled due to CPU errata.\n");
+	x86_pmu.pebs = 0;
+	x86_pmu.pebs_constraints = NULL;
+}
+
 static __init int intel_pmu_init(void)
 {
 	union cpuid10_edx edx;
@@ -864,6 +890,7 @@ static __init int intel_pmu_init(void)
 		break;
 
 	case 15: /* original 65 nm celeron/pentium/core2/xeon, "Merom"/"Conroe" */
+		x86_pmu.quirks = intel_clowertown_quirks;
 	case 22: /* single-core 65 nm celeron/core2solo "Merom-L"/"Conroe-L" */
 	case 23: /* current 45 nm celeron/core2/xeon "Penryn"/"Wolfdale" */
 	case 29: /* six-core 45 nm xeon "Dunnington" */

-- 


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

* [PATCH 4/5] perf, x86: Clear the LBRs on init
  2010-03-05 15:39 [PATCH 0/5] PEBS and LBR fixes Peter Zijlstra
                   ` (2 preceding siblings ...)
  2010-03-05 15:39 ` [PATCH 3/5] perf, x86: Disable PEBS on clowertown chips Peter Zijlstra
@ 2010-03-05 15:39 ` Peter Zijlstra
  2010-03-10 13:21   ` [tip:perf/pebs] " tip-bot for Peter Zijlstra
  2010-03-05 15:39 ` [PATCH 5/5] perf, x86: Robustify PEBS fixup Peter Zijlstra
  4 siblings, 1 reply; 23+ messages in thread
From: Peter Zijlstra @ 2010-03-05 15:39 UTC (permalink / raw)
  To: mingo, linux-kernel
  Cc: paulus, eranian, robert.richter, fweisbec,
	Arnaldo Carvalho de Melo, Peter Zijlstra

[-- Attachment #1: lbr-errata-aak136.patch --]
[-- Type: text/plain, Size: 1916 bytes --]

Some CPUs have errata where the LBR is not cleared on Power-On. So
always clear the LBRs before use.

Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
---
 arch/x86/kernel/cpu/perf_event_intel.c     |   18 ++++++++++++++++--
 arch/x86/kernel/cpu/perf_event_intel_lbr.c |    3 +++
 2 files changed, 19 insertions(+), 2 deletions(-)

Index: linux-2.6/arch/x86/kernel/cpu/perf_event_intel.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/cpu/perf_event_intel.c
+++ linux-2.6/arch/x86/kernel/cpu/perf_event_intel.c
@@ -775,6 +775,20 @@ static __initconst struct x86_pmu core_p
 	.event_constraints	= intel_core_event_constraints,
 };
 
+static void intel_pmu_cpu_starting(int cpu)
+{
+	init_debug_store_on_cpu(cpu);
+	/*
+	 * Deal with CPUs that don't clear their LBRs on power-up.
+	 */
+	intel_pmu_lbr_reset();
+}
+
+static void intel_pmu_cpu_dying(int cpu)
+{
+	fini_debug_store_on_cpu(cpu);
+}
+
 static __initconst struct x86_pmu intel_pmu = {
 	.name			= "Intel",
 	.handle_irq		= intel_pmu_handle_irq,
@@ -796,8 +810,8 @@ static __initconst struct x86_pmu intel_
 	.max_period		= (1ULL << 31) - 1,
 	.get_event_constraints	= intel_get_event_constraints,
 
-	.cpu_starting		= init_debug_store_on_cpu,
-	.cpu_dying		= fini_debug_store_on_cpu,
+	.cpu_starting		= intel_pmu_cpu_starting,
+	.cpu_dying		= intel_pmu_cpu_dying,
 };
 
 static void intel_clowertown_quirks(void)
Index: linux-2.6/arch/x86/kernel/cpu/perf_event_intel_lbr.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/cpu/perf_event_intel_lbr.c
+++ linux-2.6/arch/x86/kernel/cpu/perf_event_intel_lbr.c
@@ -53,6 +53,9 @@ static void intel_pmu_lbr_reset_64(void)
 
 static void intel_pmu_lbr_reset(void)
 {
+	if (!x86_pmu.lbr_nr)
+		return;
+
 	if (x86_pmu.intel_cap.lbr_format == LBR_FORMAT_32)
 		intel_pmu_lbr_reset_32();
 	else

-- 


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

* [PATCH 5/5] perf, x86: Robustify PEBS fixup
  2010-03-05 15:39 [PATCH 0/5] PEBS and LBR fixes Peter Zijlstra
                   ` (3 preceding siblings ...)
  2010-03-05 15:39 ` [PATCH 4/5] perf, x86: Clear the LBRs on init Peter Zijlstra
@ 2010-03-05 15:39 ` Peter Zijlstra
  2010-03-10 13:21   ` [tip:perf/pebs] " tip-bot for Peter Zijlstra
  4 siblings, 1 reply; 23+ messages in thread
From: Peter Zijlstra @ 2010-03-05 15:39 UTC (permalink / raw)
  To: mingo, linux-kernel
  Cc: paulus, eranian, robert.richter, fweisbec,
	Arnaldo Carvalho de Melo, Peter Zijlstra

[-- Attachment #1: pebs-robustify-fixup.patch --]
[-- Type: text/plain, Size: 1650 bytes --]

It turns out the LBR is massively unreliable on certain CPUs, so code
the fixup a little more defensive to avoid crashing the kernel.

Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
---
 arch/x86/kernel/cpu/perf_event_intel_ds.c |   21 +++++++++++++++++++--
 1 file changed, 19 insertions(+), 2 deletions(-)

Index: linux-2.6/arch/x86/kernel/cpu/perf_event_intel_ds.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/cpu/perf_event_intel_ds.c
+++ linux-2.6/arch/x86/kernel/cpu/perf_event_intel_ds.c
@@ -399,10 +399,23 @@ static int intel_pmu_pebs_fixup_ip(struc
 	if (!x86_pmu.intel_cap.pebs_trap)
 		return 1;
 
+	/*
+	 * No LBR entry, no basic block, no rewinding
+	 */
 	if (!cpuc->lbr_stack.nr || !from || !to)
 		return 0;
 
-	if (ip < to)
+	/*
+	 * Basic blocks should never cross user/kernel boundaries
+	 */
+	if (kernel_ip(ip) != kernel_ip(to))
+		return 0;
+
+	/*
+	 * unsigned math, either ip is before the start (impossible) or
+	 * the basic block is larger than 1 page (sanity)
+	 */
+	if ((ip - to) > PAGE_SIZE)
 		return 0;
 
 	/*
@@ -420,7 +433,7 @@ static int intel_pmu_pebs_fixup_ip(struc
 
 		old_to = to;
 		if (!kernel_ip(ip)) {
-			int bytes, size = min_t(int, MAX_INSN_SIZE, ip - to);
+			int bytes, size = MAX_INSN_SIZE;
 
 			bytes = copy_from_user_nmi(buf, (void __user *)to, size);
 			if (bytes != size)
@@ -440,6 +453,10 @@ static int intel_pmu_pebs_fixup_ip(struc
 		return 1;
 	}
 
+	/*
+	 * Even though we decoded the basic block, the instruction stream
+	 * never matched the given IP, either the TO or the IP got corrupted.
+	 */
 	return 0;
 }
 

-- 


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

* Re: [PATCH 3/5] perf, x86: Disable PEBS on clowertown chips
  2010-03-05 15:39 ` [PATCH 3/5] perf, x86: Disable PEBS on clowertown chips Peter Zijlstra
@ 2010-03-05 18:58   ` Stephane Eranian
  2010-03-05 19:15     ` Peter Zijlstra
  2010-03-10 13:21   ` [tip:perf/pebs] perf, x86: Disable PEBS on clovertown chips tip-bot for Peter Zijlstra
  1 sibling, 1 reply; 23+ messages in thread
From: Stephane Eranian @ 2010-03-05 18:58 UTC (permalink / raw)
  To: Peter Zijlstra
  Cc: mingo, linux-kernel, paulus, robert.richter, fweisbec,
	Arnaldo Carvalho de Melo

On Fri, Mar 5, 2010 at 7:39 AM, Peter Zijlstra <a.p.zijlstra@chello.nl> wrote:
> This CPU has just too many handycaps to be really useful.
>
> Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
> ---
>  arch/x86/kernel/cpu/perf_event.c       |    4 ++++
>  arch/x86/kernel/cpu/perf_event_intel.c |   27 +++++++++++++++++++++++++++
>  2 files changed, 31 insertions(+)
>
> Index: linux-2.6/arch/x86/kernel/cpu/perf_event.c
> ===================================================================
> --- linux-2.6.orig/arch/x86/kernel/cpu/perf_event.c
> +++ linux-2.6/arch/x86/kernel/cpu/perf_event.c
> @@ -197,6 +197,7 @@ struct x86_pmu {
>        void            (*put_event_constraints)(struct cpu_hw_events *cpuc,
>                                                 struct perf_event *event);
>        struct event_constraint *event_constraints;
> +       void            (*quirks)(void);
>
>        void            (*cpu_prepare)(int cpu);
>        void            (*cpu_starting)(int cpu);
> @@ -1380,6 +1381,9 @@ void __init init_hw_perf_events(void)
>
>        pr_cont("%s PMU driver.\n", x86_pmu.name);
>
> +       if (x86_pmu.quirks)
> +               x86_pmu.quirks();
> +
>        if (x86_pmu.num_events > X86_PMC_MAX_GENERIC) {
>                WARN(1, KERN_ERR "hw perf events %d > max(%d), clipping!",
>                     x86_pmu.num_events, X86_PMC_MAX_GENERIC);
> Index: linux-2.6/arch/x86/kernel/cpu/perf_event_intel.c
> ===================================================================
> --- linux-2.6.orig/arch/x86/kernel/cpu/perf_event_intel.c
> +++ linux-2.6/arch/x86/kernel/cpu/perf_event_intel.c
> @@ -800,6 +800,32 @@ static __initconst struct x86_pmu intel_
>        .cpu_dying              = fini_debug_store_on_cpu,
>  };
>
> +static void intel_clowertown_quirks(void)
> +{
> +       /*
> +        * PEBS is unreliable due to:
> +        *
> +        *   AJ67  - PEBS may experience CPL leaks
> +        *   AJ68  - PEBS PMI may be delayed by one event
> +        *   AJ69  - GLOBAL_STATUS[62] will only be set when DEBUGCTL[12]
> +        *   AJ106 - FREEZE_LBRS_ON_PMI doesn't work in combination with PEBS
> +        *
> +        * AJ67 could be worked around by restricting the OS/USR flags.
> +        * AJ69 could be worked around by setting PMU_FREEZE_ON_PMI.
> +        *
> +        * AJ106 could possibly be worked around by not allowing LBR
> +        *       usage from PEBS, including the fixup.
> +        * AJ68  could possibly be worked around by always programming
> +        *       a pebs_event_reset[0] value and coping with the lost events.
> +        *
> +        * But taken together it might just make sense to not enable PEBS on
> +        * these chips.
> +        */
> +       printk(KERN_WARNING "PEBS disabled due to CPU errata.\n");
> +       x86_pmu.pebs = 0;
> +       x86_pmu.pebs_constraints = NULL;
> +}
> +
>  static __init int intel_pmu_init(void)
>  {
>        union cpuid10_edx edx;
> @@ -864,6 +890,7 @@ static __init int intel_pmu_init(void)
>                break;
>
>        case 15: /* original 65 nm celeron/pentium/core2/xeon, "Merom"/"Conroe" */
> +               x86_pmu.quirks = intel_clowertown_quirks;

That's too coarse grain!
It is more subtle than this. Some of the errata are marked as Plan
fix. They seem to be
fixed in later models. Your looking at the E5xxx series errata but the
E7xxx do not have
the same problems.

As for CPL leaking, you get that also with regular sampling when you
execute near
the user/kernel boundary given you have skid. Either the kernel or the
user has to
drop samples.

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

* Re: [PATCH 3/5] perf, x86: Disable PEBS on clowertown chips
  2010-03-05 18:58   ` Stephane Eranian
@ 2010-03-05 19:15     ` Peter Zijlstra
  2010-03-05 19:28       ` Stephane Eranian
  2010-03-05 21:05       ` Peter Zijlstra
  0 siblings, 2 replies; 23+ messages in thread
From: Peter Zijlstra @ 2010-03-05 19:15 UTC (permalink / raw)
  To: Stephane Eranian
  Cc: mingo, linux-kernel, paulus, robert.richter, fweisbec,
	Arnaldo Carvalho de Melo

On Fri, 2010-03-05 at 10:58 -0800, Stephane Eranian wrote:
> >        case 15: /* original 65 nm celeron/pentium/core2/xeon, "Merom"/"Conroe" */
> > +               x86_pmu.quirks = intel_clowertown_quirks;
> 
> That's too coarse grain!
> It is more subtle than this. Some of the errata are marked as Plan
> fix. They seem to be
> fixed in later models. Your looking at the E5xxx series errata but the
> E7xxx do not have
> the same problems. 

OK, I'll look at those errata again and try to come up with a stepping
test for this errata.


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

* Re: [PATCH 3/5] perf, x86: Disable PEBS on clowertown chips
  2010-03-05 19:15     ` Peter Zijlstra
@ 2010-03-05 19:28       ` Stephane Eranian
  2010-03-05 19:37         ` Peter Zijlstra
  2010-03-05 21:05       ` Peter Zijlstra
  1 sibling, 1 reply; 23+ messages in thread
From: Stephane Eranian @ 2010-03-05 19:28 UTC (permalink / raw)
  To: Peter Zijlstra
  Cc: mingo, linux-kernel, paulus, robert.richter, fweisbec,
	Arnaldo Carvalho de Melo

On Fri, Mar 5, 2010 at 11:15 AM, Peter Zijlstra <peterz@infradead.org> wrote:
> On Fri, 2010-03-05 at 10:58 -0800, Stephane Eranian wrote:
>> >        case 15: /* original 65 nm celeron/pentium/core2/xeon, "Merom"/"Conroe" */
>> > +               x86_pmu.quirks = intel_clowertown_quirks;
>>
>> That's too coarse grain!
>> It is more subtle than this. Some of the errata are marked as Plan
>> fix. They seem to be
>> fixed in later models. Your looking at the E5xxx series errata but the
>> E7xxx do not have
>> the same problems.
>
> OK, I'll look at those errata again and try to come up with a stepping
> test for this errata.
>
There is erratum which you need to implement the workaround for and
this is AAJ91 on Nehalem. It does happen.

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

* Re: [PATCH 3/5] perf, x86: Disable PEBS on clowertown chips
  2010-03-05 19:28       ` Stephane Eranian
@ 2010-03-05 19:37         ` Peter Zijlstra
  0 siblings, 0 replies; 23+ messages in thread
From: Peter Zijlstra @ 2010-03-05 19:37 UTC (permalink / raw)
  To: Stephane Eranian
  Cc: mingo, linux-kernel, paulus, robert.richter, fweisbec,
	Arnaldo Carvalho de Melo

On Fri, 2010-03-05 at 11:28 -0800, Stephane Eranian wrote:
> On Fri, Mar 5, 2010 at 11:15 AM, Peter Zijlstra <peterz@infradead.org> wrote:
> > On Fri, 2010-03-05 at 10:58 -0800, Stephane Eranian wrote:
> >> >        case 15: /* original 65 nm celeron/pentium/core2/xeon, "Merom"/"Conroe" */
> >> > +               x86_pmu.quirks = intel_clowertown_quirks;
> >>
> >> That's too coarse grain!
> >> It is more subtle than this. Some of the errata are marked as Plan
> >> fix. They seem to be
> >> fixed in later models. Your looking at the E5xxx series errata but the
> >> E7xxx do not have
> >> the same problems.
> >
> > OK, I'll look at those errata again and try to come up with a stepping
> > test for this errata.
> >
> There is erratum which you need to implement the workaround for and
> this is AAJ91 on Nehalem. It does happen.

Yes, I found that one too today. Its on my todo list.


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

* Re: [PATCH 3/5] perf, x86: Disable PEBS on clowertown chips
  2010-03-05 19:15     ` Peter Zijlstra
  2010-03-05 19:28       ` Stephane Eranian
@ 2010-03-05 21:05       ` Peter Zijlstra
  2010-03-05 21:22         ` Stephane Eranian
  1 sibling, 1 reply; 23+ messages in thread
From: Peter Zijlstra @ 2010-03-05 21:05 UTC (permalink / raw)
  To: Stephane Eranian
  Cc: mingo, linux-kernel, paulus, robert.richter, fweisbec,
	Arnaldo Carvalho de Melo

On Fri, 2010-03-05 at 20:15 +0100, Peter Zijlstra wrote:
> On Fri, 2010-03-05 at 10:58 -0800, Stephane Eranian wrote:
> > >        case 15: /* original 65 nm celeron/pentium/core2/xeon, "Merom"/"Conroe" */
> > > +               x86_pmu.quirks = intel_clowertown_quirks;
> > 
> > That's too coarse grain!
> > It is more subtle than this. Some of the errata are marked as Plan
> > fix. They seem to be
> > fixed in later models. Your looking at the E5xxx series errata but the
> > E7xxx do not have
> > the same problems. 
> 
> OK, I'll look at those errata again and try to come up with a stepping
> test for this errata. 

The two serious ones, AJ106 and AJ68 are no fix and are listed as such
in all errata I can find, including the 7[23]00 series.

I checked the 65nm Core2Duo, Xeon 5200 and Xeon 7[23]00 spec updates.
Going by that it seems the full model 15 family is broken and I'll leave
the patch as is.




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

* Re: [PATCH 3/5] perf, x86: Disable PEBS on clowertown chips
  2010-03-05 21:05       ` Peter Zijlstra
@ 2010-03-05 21:22         ` Stephane Eranian
  2010-03-05 21:35           ` Peter Zijlstra
  0 siblings, 1 reply; 23+ messages in thread
From: Stephane Eranian @ 2010-03-05 21:22 UTC (permalink / raw)
  To: Peter Zijlstra
  Cc: mingo, linux-kernel, paulus, robert.richter, fweisbec,
	Arnaldo Carvalho de Melo

On Fri, Mar 5, 2010 at 1:05 PM, Peter Zijlstra <peterz@infradead.org> wrote:
> On Fri, 2010-03-05 at 20:15 +0100, Peter Zijlstra wrote:
>> On Fri, 2010-03-05 at 10:58 -0800, Stephane Eranian wrote:
>> > >        case 15: /* original 65 nm celeron/pentium/core2/xeon, "Merom"/"Conroe" */
>> > > +               x86_pmu.quirks = intel_clowertown_quirks;
>> >
>> > That's too coarse grain!
>> > It is more subtle than this. Some of the errata are marked as Plan
>> > fix. They seem to be
>> > fixed in later models. Your looking at the E5xxx series errata but the
>> > E7xxx do not have
>> > the same problems.
>>
>> OK, I'll look at those errata again and try to come up with a stepping
>> test for this errata.
>
> The two serious ones, AJ106 and AJ68 are no fix and are listed as such
> in all errata I can find, including the 7[23]00 series.
>
Not E74xx. I think it would be fine to drop LBR with PEBS as the work-around
to AJ106.

> I checked the 65nm Core2Duo, Xeon 5200 and Xeon 7[23]00 spec updates.
> Going by that it seems the full model 15 family is broken and I'll leave
> the patch as is.

But the E74xx are okay and you are excluding them. Worst case you should
provide an override.

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

* Re: [PATCH 3/5] perf, x86: Disable PEBS on clowertown chips
  2010-03-05 21:22         ` Stephane Eranian
@ 2010-03-05 21:35           ` Peter Zijlstra
  2010-03-05 21:38             ` Stephane Eranian
  0 siblings, 1 reply; 23+ messages in thread
From: Peter Zijlstra @ 2010-03-05 21:35 UTC (permalink / raw)
  To: Stephane Eranian
  Cc: mingo, linux-kernel, paulus, robert.richter, fweisbec,
	Arnaldo Carvalho de Melo

On Fri, 2010-03-05 at 13:22 -0800, Stephane Eranian wrote:
> > The two serious ones, AJ106 and AJ68 are no fix and are listed as such
> > in all errata I can find, including the 7[23]00 series.
> >
> Not E74xx. I think it would be fine to drop LBR with PEBS as the work-around
> to AJ106.
> 
> > I checked the 65nm Core2Duo, Xeon 5200 and Xeon 7[23]00 spec updates.
> > Going by that it seems the full model 15 family is broken and I'll leave
> > the patch as is.
> 
> But the E74xx are okay and you are excluding them. Worst case you should
> provide an override.

>From what I can tell E74xx is model 29, which would be just fine with
this patch, this patch only marks model 15 as broken.




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

* Re: [PATCH 3/5] perf, x86: Disable PEBS on clowertown chips
  2010-03-05 21:35           ` Peter Zijlstra
@ 2010-03-05 21:38             ` Stephane Eranian
  2010-03-05 21:43               ` Peter Zijlstra
  0 siblings, 1 reply; 23+ messages in thread
From: Stephane Eranian @ 2010-03-05 21:38 UTC (permalink / raw)
  To: Peter Zijlstra
  Cc: mingo, linux-kernel, paulus, robert.richter, fweisbec,
	Arnaldo Carvalho de Melo

On Fri, Mar 5, 2010 at 1:35 PM, Peter Zijlstra <peterz@infradead.org> wrote:
> On Fri, 2010-03-05 at 13:22 -0800, Stephane Eranian wrote:
>> > The two serious ones, AJ106 and AJ68 are no fix and are listed as such
>> > in all errata I can find, including the 7[23]00 series.
>> >
>> Not E74xx. I think it would be fine to drop LBR with PEBS as the work-around
>> to AJ106.
>>
>> > I checked the 65nm Core2Duo, Xeon 5200 and Xeon 7[23]00 spec updates.
>> > Going by that it seems the full model 15 family is broken and I'll leave
>> > the patch as is.
>>
>> But the E74xx are okay and you are excluding them. Worst case you should
>> provide an override.
>
> >From what I can tell E74xx is model 29, which would be just fine with
> this patch, this patch only marks model 15 as broken.
>
True, my bad.
So it would be a matter to provide some ways of disabling LBR with PEBS
on model 15.

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

* Re: [PATCH 3/5] perf, x86: Disable PEBS on clowertown chips
  2010-03-05 21:38             ` Stephane Eranian
@ 2010-03-05 21:43               ` Peter Zijlstra
  2010-03-05 21:57                 ` Stephane Eranian
  0 siblings, 1 reply; 23+ messages in thread
From: Peter Zijlstra @ 2010-03-05 21:43 UTC (permalink / raw)
  To: Stephane Eranian
  Cc: mingo, linux-kernel, paulus, robert.richter, fweisbec,
	Arnaldo Carvalho de Melo

On Fri, 2010-03-05 at 13:38 -0800, Stephane Eranian wrote:
> On Fri, Mar 5, 2010 at 1:35 PM, Peter Zijlstra <peterz@infradead.org> wrote:
> > On Fri, 2010-03-05 at 13:22 -0800, Stephane Eranian wrote:
> >> > The two serious ones, AJ106 and AJ68 are no fix and are listed as such
> >> > in all errata I can find, including the 7[23]00 series.
> >> >
> >> Not E74xx. I think it would be fine to drop LBR with PEBS as the work-around
> >> to AJ106.
> >>
> >> > I checked the 65nm Core2Duo, Xeon 5200 and Xeon 7[23]00 spec updates.
> >> > Going by that it seems the full model 15 family is broken and I'll leave
> >> > the patch as is.
> >>
> >> But the E74xx are okay and you are excluding them. Worst case you should
> >> provide an override.
> >
> > >From what I can tell E74xx is model 29, which would be just fine with
> > this patch, this patch only marks model 15 as broken.
> >
> True, my bad.
> So it would be a matter to provide some ways of disabling LBR with PEBS
> on model 15.

And some way of dealing with the flaky PEBS PMI, which requires we
program the pebs_event_reset thing otherwise there won't be a next PEBS
record to re-trigger the PMI.

If it would have stated it always did the threshold comparison first and
then the index increment, so that we'd always trigger on the second
record we could simply program half the period and always take two and
ignore the first, but it says _MAY_, so its a race and there's no
reliable solution.

It might all be possible but I don't see it being worth the effort.


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

* Re: [PATCH 3/5] perf, x86: Disable PEBS on clowertown chips
  2010-03-05 21:43               ` Peter Zijlstra
@ 2010-03-05 21:57                 ` Stephane Eranian
  2010-03-05 22:25                   ` Peter Zijlstra
  0 siblings, 1 reply; 23+ messages in thread
From: Stephane Eranian @ 2010-03-05 21:57 UTC (permalink / raw)
  To: Peter Zijlstra
  Cc: mingo, linux-kernel, paulus, robert.richter, fweisbec,
	Arnaldo Carvalho de Melo

On Fri, Mar 5, 2010 at 1:43 PM, Peter Zijlstra <peterz@infradead.org> wrote:
> On Fri, 2010-03-05 at 13:38 -0800, Stephane Eranian wrote:
>> On Fri, Mar 5, 2010 at 1:35 PM, Peter Zijlstra <peterz@infradead.org> wrote:
>> > On Fri, 2010-03-05 at 13:22 -0800, Stephane Eranian wrote:
>> >> > The two serious ones, AJ106 and AJ68 are no fix and are listed as such
>> >> > in all errata I can find, including the 7[23]00 series.
>> >> >
>> >> Not E74xx. I think it would be fine to drop LBR with PEBS as the work-around
>> >> to AJ106.
>> >>
>> >> > I checked the 65nm Core2Duo, Xeon 5200 and Xeon 7[23]00 spec updates.
>> >> > Going by that it seems the full model 15 family is broken and I'll leave
>> >> > the patch as is.
>> >>
>> >> But the E74xx are okay and you are excluding them. Worst case you should
>> >> provide an override.
>> >
>> > >From what I can tell E74xx is model 29, which would be just fine with
>> > this patch, this patch only marks model 15 as broken.
>> >
>> True, my bad.
>> So it would be a matter to provide some ways of disabling LBR with PEBS
>> on model 15.
>
> And some way of dealing with the flaky PEBS PMI, which requires we
> program the pebs_event_reset thing otherwise there won't be a next PEBS
> record to re-trigger the PMI.
>
> If it would have stated it always did the threshold comparison first and
> then the index increment, so that we'd always trigger on the second
> record we could simply program half the period and always take two and
> ignore the first, but it says _MAY_, so its a race and there's no
> reliable solution.
>
> It might all be possible but I don't see it being worth the effort.
>
There are lots of model15 out there, like the Q6xxx series.

When I read AJ68, my understanding is that it's not that you do not
get the interrupt. It will be delayed by one event. The buffer will become
full. You won't overrun the buffer, you will get the interrupt at the next
event. On interrupt, you have to reset the PEBS position pointer anyway.
There is already a disconnect between the sampling period and the actual
instruction sampled. That's not making the situation that much worse, unless
I am missing something.

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

* Re: [PATCH 3/5] perf, x86: Disable PEBS on clowertown chips
  2010-03-05 21:57                 ` Stephane Eranian
@ 2010-03-05 22:25                   ` Peter Zijlstra
  2010-03-05 22:33                     ` Stephane Eranian
  0 siblings, 1 reply; 23+ messages in thread
From: Peter Zijlstra @ 2010-03-05 22:25 UTC (permalink / raw)
  To: Stephane Eranian
  Cc: mingo, linux-kernel, paulus, robert.richter, fweisbec,
	Arnaldo Carvalho de Melo

On Fri, 2010-03-05 at 13:57 -0800, Stephane Eranian wrote:

> When I read AJ68, my understanding is that it's not that you do not
> get the interrupt. It will be delayed by one event. The buffer will become
> full. You won't overrun the buffer, you will get the interrupt at the next
> event. On interrupt, you have to reset the PEBS position pointer anyway.
> There is already a disconnect between the sampling period and the actual
> instruction sampled. That's not making the situation that much worse, unless
> I am missing something.

The current code doesn't use the buffering at all, it uses single-shot
PEBS by keeping pebs_event_reset 0 and setting a threshold of a single
entry, so if due to AJ68 we miss a PMI it will never come.

I guess we can fudge something, but at what point does the whole thing
stop being useful?

It would end up being something with fuzzy period and fuzzy location,
which is a loss-loss situation if you ask me.




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

* Re: [PATCH 3/5] perf, x86: Disable PEBS on clowertown chips
  2010-03-05 22:25                   ` Peter Zijlstra
@ 2010-03-05 22:33                     ` Stephane Eranian
  0 siblings, 0 replies; 23+ messages in thread
From: Stephane Eranian @ 2010-03-05 22:33 UTC (permalink / raw)
  To: Peter Zijlstra
  Cc: mingo, linux-kernel, paulus, robert.richter, fweisbec,
	Arnaldo Carvalho de Melo

On Fri, Mar 5, 2010 at 2:25 PM, Peter Zijlstra <peterz@infradead.org> wrote:
> On Fri, 2010-03-05 at 13:57 -0800, Stephane Eranian wrote:
>
>> When I read AJ68, my understanding is that it's not that you do not
>> get the interrupt. It will be delayed by one event. The buffer will become
>> full. You won't overrun the buffer, you will get the interrupt at the next
>> event. On interrupt, you have to reset the PEBS position pointer anyway.
>> There is already a disconnect between the sampling period and the actual
>> instruction sampled. That's not making the situation that much worse, unless
>> I am missing something.
>
> The current code doesn't use the buffering at all, it uses single-shot
> PEBS by keeping pebs_event_reset 0 and setting a threshold of a single
> entry, so if due to AJ68 we miss a PMI it will never come.
>
What stops PEBS is that it crosses the end of the buffer. The buffer
is one-deep,
threshold = buffer end, you get a single sample. reset has nothing to
do with this.

AJ68 does not say you miss a PMI, it says the PMI comes at the next
event. I suspect they mean the next observed event, and not necessarily
the next recorded event. But I can check on that.


> I guess we can fudge something, but at what point does the whole thing
> stop being useful?

What matters is that you get a valid sample.

>
> It would end up being something with fuzzy period and fuzzy location,
> which is a loss-loss situation if you ask me.
>
The period is already fuzzy to begin with. Recall our discussion a couple
of weeks back.

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

* [tip:perf/urgent] perf: Rework and fix the arch CPU-hotplug hooks
  2010-03-05 15:39 ` [PATCH 1/5] perf: Rework the arch CPU-hotplug hooks Peter Zijlstra
@ 2010-03-10 13:10   ` tip-bot for Peter Zijlstra
  0 siblings, 0 replies; 23+ messages in thread
From: tip-bot for Peter Zijlstra @ 2010-03-10 13:10 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: linux-kernel, hpa, mingo, acme, a.p.zijlstra, lethal, tglx, mingo

Commit-ID:  3f6da3905398826d85731247e7fbcf53400c18bd
Gitweb:     http://git.kernel.org/tip/3f6da3905398826d85731247e7fbcf53400c18bd
Author:     Peter Zijlstra <a.p.zijlstra@chello.nl>
AuthorDate: Fri, 5 Mar 2010 13:01:18 +0100
Committer:  Ingo Molnar <mingo@elte.hu>
CommitDate: Wed, 10 Mar 2010 13:22:24 +0100

perf: Rework and fix the arch CPU-hotplug hooks

Remove the hw_perf_event_*() hotplug hooks in favour of per PMU hotplug
notifiers. This has the advantage of reducing the static weak interface
as well as exposing all hotplug actions to the PMU.

Use this to fix x86 hotplug usage where we did things in ONLINE which
should have been done in UP_PREPARE or STARTING.

Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Paul Mundt <lethal@linux-sh.org>
Cc: paulus@samba.org
Cc: eranian@google.com
Cc: robert.richter@amd.com
Cc: fweisbec@gmail.com
Cc: Arnaldo Carvalho de Melo <acme@infradead.org>
LKML-Reference: <20100305154128.736225361@chello.nl>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
---
 arch/powerpc/kernel/perf_event.c       |   21 +++++++++-
 arch/sh/kernel/perf_event.c            |   20 +++++++++-
 arch/x86/kernel/cpu/perf_event.c       |   70 +++++++++++++++++++-------------
 arch/x86/kernel/cpu/perf_event_amd.c   |   60 +++++++++++----------------
 arch/x86/kernel/cpu/perf_event_intel.c |    5 ++-
 include/linux/perf_event.h             |   16 +++++++
 kernel/perf_event.c                    |   15 -------
 7 files changed, 126 insertions(+), 81 deletions(-)

diff --git a/arch/powerpc/kernel/perf_event.c b/arch/powerpc/kernel/perf_event.c
index 5120bd4..fbe101d 100644
--- a/arch/powerpc/kernel/perf_event.c
+++ b/arch/powerpc/kernel/perf_event.c
@@ -1287,7 +1287,7 @@ static void perf_event_interrupt(struct pt_regs *regs)
 		irq_exit();
 }
 
-void hw_perf_event_setup(int cpu)
+static void power_pmu_setup(int cpu)
 {
 	struct cpu_hw_events *cpuhw = &per_cpu(cpu_hw_events, cpu);
 
@@ -1297,6 +1297,23 @@ void hw_perf_event_setup(int cpu)
 	cpuhw->mmcr[0] = MMCR0_FC;
 }
 
+static int __cpuinit
+power_pmu_notify(struct notifier_block *self, unsigned long action, void *hcpu)
+{
+	unsigned int cpu = (long)hcpu;
+
+	switch (action & ~CPU_TASKS_FROZEN) {
+	case CPU_UP_PREPARE:
+		power_pmu_setup(cpu);
+		break;
+
+	default:
+		break;
+	}
+
+	return NOTIFY_OK;
+}
+
 int register_power_pmu(struct power_pmu *pmu)
 {
 	if (ppmu)
@@ -1314,5 +1331,7 @@ int register_power_pmu(struct power_pmu *pmu)
 		freeze_events_kernel = MMCR0_FCHV;
 #endif /* CONFIG_PPC64 */
 
+	perf_cpu_notifier(power_pmu_notifier);
+
 	return 0;
 }
diff --git a/arch/sh/kernel/perf_event.c b/arch/sh/kernel/perf_event.c
index 7ff0943..9f253e9 100644
--- a/arch/sh/kernel/perf_event.c
+++ b/arch/sh/kernel/perf_event.c
@@ -275,13 +275,30 @@ const struct pmu *hw_perf_event_init(struct perf_event *event)
 	return &pmu;
 }
 
-void hw_perf_event_setup(int cpu)
+static void sh_pmu_setup(int cpu)
 {
 	struct cpu_hw_events *cpuhw = &per_cpu(cpu_hw_events, cpu);
 
 	memset(cpuhw, 0, sizeof(struct cpu_hw_events));
 }
 
+static int __cpuinit
+sh_pmu_notifier(struct notifier_block *self, unsigned long action, void *hcpu)
+{
+	unsigned int cpu = (long)hcpu;
+
+	switch (action & ~CPU_TASKS_FROZEN) {
+	case CPU_UP_PREPARE:
+		sh_pmu_setup(cpu);
+		break;
+
+	default:
+		break;
+	}
+
+	return NOTIFY_OK;
+}
+
 void hw_perf_enable(void)
 {
 	if (!sh_pmu_initialized())
@@ -308,5 +325,6 @@ int register_sh_pmu(struct sh_pmu *pmu)
 
 	WARN_ON(pmu->num_events > MAX_HWEVENTS);
 
+	perf_cpu_notifier(sh_pmu_notifier);
 	return 0;
 }
diff --git a/arch/x86/kernel/cpu/perf_event.c b/arch/x86/kernel/cpu/perf_event.c
index 42aafd1..585d560 100644
--- a/arch/x86/kernel/cpu/perf_event.c
+++ b/arch/x86/kernel/cpu/perf_event.c
@@ -157,6 +157,11 @@ struct x86_pmu {
 	void		(*put_event_constraints)(struct cpu_hw_events *cpuc,
 						 struct perf_event *event);
 	struct event_constraint *event_constraints;
+
+	void		(*cpu_prepare)(int cpu);
+	void		(*cpu_starting)(int cpu);
+	void		(*cpu_dying)(int cpu);
+	void		(*cpu_dead)(int cpu);
 };
 
 static struct x86_pmu x86_pmu __read_mostly;
@@ -293,7 +298,7 @@ static inline bool bts_available(void)
 	return x86_pmu.enable_bts != NULL;
 }
 
-static inline void init_debug_store_on_cpu(int cpu)
+static void init_debug_store_on_cpu(int cpu)
 {
 	struct debug_store *ds = per_cpu(cpu_hw_events, cpu).ds;
 
@@ -305,7 +310,7 @@ static inline void init_debug_store_on_cpu(int cpu)
 		     (u32)((u64)(unsigned long)ds >> 32));
 }
 
-static inline void fini_debug_store_on_cpu(int cpu)
+static void fini_debug_store_on_cpu(int cpu)
 {
 	if (!per_cpu(cpu_hw_events, cpu).ds)
 		return;
@@ -1337,6 +1342,39 @@ undo:
 #include "perf_event_p6.c"
 #include "perf_event_intel.c"
 
+static int __cpuinit
+x86_pmu_notifier(struct notifier_block *self, unsigned long action, void *hcpu)
+{
+	unsigned int cpu = (long)hcpu;
+
+	switch (action & ~CPU_TASKS_FROZEN) {
+	case CPU_UP_PREPARE:
+		if (x86_pmu.cpu_prepare)
+			x86_pmu.cpu_prepare(cpu);
+		break;
+
+	case CPU_STARTING:
+		if (x86_pmu.cpu_starting)
+			x86_pmu.cpu_starting(cpu);
+		break;
+
+	case CPU_DYING:
+		if (x86_pmu.cpu_dying)
+			x86_pmu.cpu_dying(cpu);
+		break;
+
+	case CPU_DEAD:
+		if (x86_pmu.cpu_dead)
+			x86_pmu.cpu_dead(cpu);
+		break;
+
+	default:
+		break;
+	}
+
+	return NOTIFY_OK;
+}
+
 static void __init pmu_check_apic(void)
 {
 	if (cpu_has_apic)
@@ -1415,6 +1453,8 @@ void __init init_hw_perf_events(void)
 	pr_info("... max period:             %016Lx\n", x86_pmu.max_period);
 	pr_info("... fixed-purpose events:   %d\n",     x86_pmu.num_events_fixed);
 	pr_info("... event mask:             %016Lx\n", perf_event_mask);
+
+	perf_cpu_notifier(x86_pmu_notifier);
 }
 
 static inline void x86_pmu_read(struct perf_event *event)
@@ -1674,29 +1714,3 @@ struct perf_callchain_entry *perf_callchain(struct pt_regs *regs)
 
 	return entry;
 }
-
-void hw_perf_event_setup_online(int cpu)
-{
-	init_debug_store_on_cpu(cpu);
-
-	switch (boot_cpu_data.x86_vendor) {
-	case X86_VENDOR_AMD:
-		amd_pmu_cpu_online(cpu);
-		break;
-	default:
-		return;
-	}
-}
-
-void hw_perf_event_setup_offline(int cpu)
-{
-	init_debug_store_on_cpu(cpu);
-
-	switch (boot_cpu_data.x86_vendor) {
-	case X86_VENDOR_AMD:
-		amd_pmu_cpu_offline(cpu);
-		break;
-	default:
-		return;
-	}
-}
diff --git a/arch/x86/kernel/cpu/perf_event_amd.c b/arch/x86/kernel/cpu/perf_event_amd.c
index 8f3dbfd..014528b 100644
--- a/arch/x86/kernel/cpu/perf_event_amd.c
+++ b/arch/x86/kernel/cpu/perf_event_amd.c
@@ -271,28 +271,6 @@ done:
 	return &emptyconstraint;
 }
 
-static __initconst struct x86_pmu amd_pmu = {
-	.name			= "AMD",
-	.handle_irq		= x86_pmu_handle_irq,
-	.disable_all		= x86_pmu_disable_all,
-	.enable_all		= x86_pmu_enable_all,
-	.enable			= x86_pmu_enable_event,
-	.disable		= x86_pmu_disable_event,
-	.eventsel		= MSR_K7_EVNTSEL0,
-	.perfctr		= MSR_K7_PERFCTR0,
-	.event_map		= amd_pmu_event_map,
-	.raw_event		= amd_pmu_raw_event,
-	.max_events		= ARRAY_SIZE(amd_perfmon_event_map),
-	.num_events		= 4,
-	.event_bits		= 48,
-	.event_mask		= (1ULL << 48) - 1,
-	.apic			= 1,
-	/* use highest bit to detect overflow */
-	.max_period		= (1ULL << 47) - 1,
-	.get_event_constraints	= amd_get_event_constraints,
-	.put_event_constraints	= amd_put_event_constraints
-};
-
 static struct amd_nb *amd_alloc_nb(int cpu, int nb_id)
 {
 	struct amd_nb *nb;
@@ -378,6 +356,31 @@ static void amd_pmu_cpu_offline(int cpu)
 	raw_spin_unlock(&amd_nb_lock);
 }
 
+static __initconst struct x86_pmu amd_pmu = {
+	.name			= "AMD",
+	.handle_irq		= x86_pmu_handle_irq,
+	.disable_all		= x86_pmu_disable_all,
+	.enable_all		= x86_pmu_enable_all,
+	.enable			= x86_pmu_enable_event,
+	.disable		= x86_pmu_disable_event,
+	.eventsel		= MSR_K7_EVNTSEL0,
+	.perfctr		= MSR_K7_PERFCTR0,
+	.event_map		= amd_pmu_event_map,
+	.raw_event		= amd_pmu_raw_event,
+	.max_events		= ARRAY_SIZE(amd_perfmon_event_map),
+	.num_events		= 4,
+	.event_bits		= 48,
+	.event_mask		= (1ULL << 48) - 1,
+	.apic			= 1,
+	/* use highest bit to detect overflow */
+	.max_period		= (1ULL << 47) - 1,
+	.get_event_constraints	= amd_get_event_constraints,
+	.put_event_constraints	= amd_put_event_constraints,
+
+	.cpu_prepare		= amd_pmu_cpu_online,
+	.cpu_dead		= amd_pmu_cpu_offline,
+};
+
 static __init int amd_pmu_init(void)
 {
 	/* Performance-monitoring supported from K7 and later: */
@@ -390,11 +393,6 @@ static __init int amd_pmu_init(void)
 	memcpy(hw_cache_event_ids, amd_hw_cache_event_ids,
 	       sizeof(hw_cache_event_ids));
 
-	/*
-	 * explicitly initialize the boot cpu, other cpus will get
-	 * the cpu hotplug callbacks from smp_init()
-	 */
-	amd_pmu_cpu_online(smp_processor_id());
 	return 0;
 }
 
@@ -405,12 +403,4 @@ static int amd_pmu_init(void)
 	return 0;
 }
 
-static void amd_pmu_cpu_online(int cpu)
-{
-}
-
-static void amd_pmu_cpu_offline(int cpu)
-{
-}
-
 #endif
diff --git a/arch/x86/kernel/cpu/perf_event_intel.c b/arch/x86/kernel/cpu/perf_event_intel.c
index 44b60c8..12e811a 100644
--- a/arch/x86/kernel/cpu/perf_event_intel.c
+++ b/arch/x86/kernel/cpu/perf_event_intel.c
@@ -870,7 +870,10 @@ static __initconst struct x86_pmu intel_pmu = {
 	.max_period		= (1ULL << 31) - 1,
 	.enable_bts		= intel_pmu_enable_bts,
 	.disable_bts		= intel_pmu_disable_bts,
-	.get_event_constraints	= intel_get_event_constraints
+	.get_event_constraints	= intel_get_event_constraints,
+
+	.cpu_starting		= init_debug_store_on_cpu,
+	.cpu_dying		= fini_debug_store_on_cpu,
 };
 
 static __init int intel_pmu_init(void)
diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h
index 6f8cd7d..80acbf3 100644
--- a/include/linux/perf_event.h
+++ b/include/linux/perf_event.h
@@ -936,5 +936,21 @@ static inline void perf_event_disable(struct perf_event *event)		{ }
 #define perf_output_put(handle, x) \
 	perf_output_copy((handle), &(x), sizeof(x))
 
+/*
+ * This has to have a higher priority than migration_notifier in sched.c.
+ */
+#define perf_cpu_notifier(fn)					\
+do {								\
+	static struct notifier_block fn##_nb __cpuinitdata =	\
+		{ .notifier_call = fn, .priority = 20 };	\
+	fn(&fn##_nb, (unsigned long)CPU_UP_PREPARE,		\
+		(void *)(unsigned long)smp_processor_id());	\
+	fn(&fn##_nb, (unsigned long)CPU_STARTING,		\
+		(void *)(unsigned long)smp_processor_id());	\
+	fn(&fn##_nb, (unsigned long)CPU_ONLINE,			\
+		(void *)(unsigned long)smp_processor_id());	\
+	register_cpu_notifier(&fn##_nb);			\
+} while (0)
+
 #endif /* __KERNEL__ */
 #endif /* _LINUX_PERF_EVENT_H */
diff --git a/kernel/perf_event.c b/kernel/perf_event.c
index 4393b9e..73329de 100644
--- a/kernel/perf_event.c
+++ b/kernel/perf_event.c
@@ -81,10 +81,6 @@ extern __weak const struct pmu *hw_perf_event_init(struct perf_event *event)
 void __weak hw_perf_disable(void)		{ barrier(); }
 void __weak hw_perf_enable(void)		{ barrier(); }
 
-void __weak hw_perf_event_setup(int cpu)	{ barrier(); }
-void __weak hw_perf_event_setup_online(int cpu)	{ barrier(); }
-void __weak hw_perf_event_setup_offline(int cpu)	{ barrier(); }
-
 int __weak
 hw_perf_group_sched_in(struct perf_event *group_leader,
 	       struct perf_cpu_context *cpuctx,
@@ -5382,8 +5378,6 @@ static void __cpuinit perf_event_init_cpu(int cpu)
 	spin_lock(&perf_resource_lock);
 	cpuctx->max_pertask = perf_max_events - perf_reserved_percpu;
 	spin_unlock(&perf_resource_lock);
-
-	hw_perf_event_setup(cpu);
 }
 
 #ifdef CONFIG_HOTPLUG_CPU
@@ -5423,20 +5417,11 @@ perf_cpu_notify(struct notifier_block *self, unsigned long action, void *hcpu)
 		perf_event_init_cpu(cpu);
 		break;
 
-	case CPU_ONLINE:
-	case CPU_ONLINE_FROZEN:
-		hw_perf_event_setup_online(cpu);
-		break;
-
 	case CPU_DOWN_PREPARE:
 	case CPU_DOWN_PREPARE_FROZEN:
 		perf_event_exit_cpu(cpu);
 		break;
 
-	case CPU_DEAD:
-		hw_perf_event_setup_offline(cpu);
-		break;
-
 	default:
 		break;
 	}

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

* [tip:perf/pebs] perf, x86: Fix silly bug in data store buffer allocation
  2010-03-05 15:39 ` [PATCH 2/5] perf, x86: Fix silly bug in data store buffer allocation Peter Zijlstra
@ 2010-03-10 13:20   ` tip-bot for Peter Zijlstra
  0 siblings, 0 replies; 23+ messages in thread
From: tip-bot for Peter Zijlstra @ 2010-03-10 13:20 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: linux-kernel, hpa, mingo, acme, a.p.zijlstra, tglx, mingo

Commit-ID:  3adaebd69557615c1bf0365ce5e32d93ac7d82af
Gitweb:     http://git.kernel.org/tip/3adaebd69557615c1bf0365ce5e32d93ac7d82af
Author:     Peter Zijlstra <a.p.zijlstra@chello.nl>
AuthorDate: Fri, 5 Mar 2010 12:09:29 +0100
Committer:  Ingo Molnar <mingo@elte.hu>
CommitDate: Wed, 10 Mar 2010 13:23:34 +0100

perf, x86: Fix silly bug in data store buffer allocation

Fix up the ds allocation error path, where we could free @buffer before
we used it.

Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Arnaldo Carvalho de Melo <acme@infradead.org>
Cc: paulus@samba.org
Cc: eranian@google.com
Cc: robert.richter@amd.com
Cc: fweisbec@gmail.com
LKML-Reference: <20100305154128.813452402@chello.nl>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
---
 arch/x86/kernel/cpu/perf_event_intel_ds.c |    4 +---
 1 files changed, 1 insertions(+), 3 deletions(-)

diff --git a/arch/x86/kernel/cpu/perf_event_intel_ds.c b/arch/x86/kernel/cpu/perf_event_intel_ds.c
index 72453ac..a67fff1 100644
--- a/arch/x86/kernel/cpu/perf_event_intel_ds.c
+++ b/arch/x86/kernel/cpu/perf_event_intel_ds.c
@@ -127,10 +127,8 @@ static int reserve_ds_buffers(void)
 
 		err = -ENOMEM;
 		ds = kzalloc(sizeof(*ds), GFP_KERNEL);
-		if (unlikely(!ds)) {
-			kfree(buffer);
+		if (unlikely(!ds))
 			break;
-		}
 		per_cpu(cpu_hw_events, cpu).ds = ds;
 
 		if (x86_pmu.bts) {

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

* [tip:perf/pebs] perf, x86: Disable PEBS on clovertown chips
  2010-03-05 15:39 ` [PATCH 3/5] perf, x86: Disable PEBS on clowertown chips Peter Zijlstra
  2010-03-05 18:58   ` Stephane Eranian
@ 2010-03-10 13:21   ` tip-bot for Peter Zijlstra
  1 sibling, 0 replies; 23+ messages in thread
From: tip-bot for Peter Zijlstra @ 2010-03-10 13:21 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: linux-kernel, hpa, mingo, acme, a.p.zijlstra, tglx, mingo

Commit-ID:  3c44780b220e876b01e39d4028cd6f4205fbf5d6
Gitweb:     http://git.kernel.org/tip/3c44780b220e876b01e39d4028cd6f4205fbf5d6
Author:     Peter Zijlstra <a.p.zijlstra@chello.nl>
AuthorDate: Thu, 4 Mar 2010 21:49:01 +0100
Committer:  Ingo Molnar <mingo@elte.hu>
CommitDate: Wed, 10 Mar 2010 13:23:35 +0100

perf, x86: Disable PEBS on clovertown chips

This CPU has just too many handycaps to be really useful.

Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Arnaldo Carvalho de Melo <acme@infradead.org>
Cc: paulus@samba.org
Cc: eranian@google.com
Cc: robert.richter@amd.com
Cc: fweisbec@gmail.com
LKML-Reference: <20100305154128.890278662@chello.nl>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
---
 arch/x86/kernel/cpu/perf_event.c       |    4 ++++
 arch/x86/kernel/cpu/perf_event_intel.c |   27 +++++++++++++++++++++++++++
 2 files changed, 31 insertions(+), 0 deletions(-)

diff --git a/arch/x86/kernel/cpu/perf_event.c b/arch/x86/kernel/cpu/perf_event.c
index 7b5430b..335ee1d 100644
--- a/arch/x86/kernel/cpu/perf_event.c
+++ b/arch/x86/kernel/cpu/perf_event.c
@@ -197,6 +197,7 @@ struct x86_pmu {
 	void		(*put_event_constraints)(struct cpu_hw_events *cpuc,
 						 struct perf_event *event);
 	struct event_constraint *event_constraints;
+	void		(*quirks)(void);
 
 	void		(*cpu_prepare)(int cpu);
 	void		(*cpu_starting)(int cpu);
@@ -1373,6 +1374,9 @@ void __init init_hw_perf_events(void)
 
 	pr_cont("%s PMU driver.\n", x86_pmu.name);
 
+	if (x86_pmu.quirks)
+		x86_pmu.quirks();
+
 	if (x86_pmu.num_events > X86_PMC_MAX_GENERIC) {
 		WARN(1, KERN_ERR "hw perf events %d > max(%d), clipping!",
 		     x86_pmu.num_events, X86_PMC_MAX_GENERIC);
diff --git a/arch/x86/kernel/cpu/perf_event_intel.c b/arch/x86/kernel/cpu/perf_event_intel.c
index 246c072..224c952 100644
--- a/arch/x86/kernel/cpu/perf_event_intel.c
+++ b/arch/x86/kernel/cpu/perf_event_intel.c
@@ -792,6 +792,32 @@ static __initconst struct x86_pmu intel_pmu = {
 	.cpu_dying		= fini_debug_store_on_cpu,
 };
 
+static void intel_clovertown_quirks(void)
+{
+	/*
+	 * PEBS is unreliable due to:
+	 *
+	 *   AJ67  - PEBS may experience CPL leaks
+	 *   AJ68  - PEBS PMI may be delayed by one event
+	 *   AJ69  - GLOBAL_STATUS[62] will only be set when DEBUGCTL[12]
+	 *   AJ106 - FREEZE_LBRS_ON_PMI doesn't work in combination with PEBS
+	 *
+	 * AJ67 could be worked around by restricting the OS/USR flags.
+	 * AJ69 could be worked around by setting PMU_FREEZE_ON_PMI.
+	 *
+	 * AJ106 could possibly be worked around by not allowing LBR
+	 *       usage from PEBS, including the fixup.
+	 * AJ68  could possibly be worked around by always programming
+	 * 	 a pebs_event_reset[0] value and coping with the lost events.
+	 *
+	 * But taken together it might just make sense to not enable PEBS on
+	 * these chips.
+	 */
+	printk(KERN_WARNING "PEBS disabled due to CPU errata.\n");
+	x86_pmu.pebs = 0;
+	x86_pmu.pebs_constraints = NULL;
+}
+
 static __init int intel_pmu_init(void)
 {
 	union cpuid10_edx edx;
@@ -856,6 +882,7 @@ static __init int intel_pmu_init(void)
 		break;
 
 	case 15: /* original 65 nm celeron/pentium/core2/xeon, "Merom"/"Conroe" */
+		x86_pmu.quirks = intel_clovertown_quirks;
 	case 22: /* single-core 65 nm celeron/core2solo "Merom-L"/"Conroe-L" */
 	case 23: /* current 45 nm celeron/core2/xeon "Penryn"/"Wolfdale" */
 	case 29: /* six-core 45 nm xeon "Dunnington" */

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

* [tip:perf/pebs] perf, x86: Clear the LBRs on init
  2010-03-05 15:39 ` [PATCH 4/5] perf, x86: Clear the LBRs on init Peter Zijlstra
@ 2010-03-10 13:21   ` tip-bot for Peter Zijlstra
  0 siblings, 0 replies; 23+ messages in thread
From: tip-bot for Peter Zijlstra @ 2010-03-10 13:21 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: linux-kernel, hpa, mingo, acme, a.p.zijlstra, tglx, mingo

Commit-ID:  74846d35b24b6efd61bb88a0a750b6bb257e6e78
Gitweb:     http://git.kernel.org/tip/74846d35b24b6efd61bb88a0a750b6bb257e6e78
Author:     Peter Zijlstra <a.p.zijlstra@chello.nl>
AuthorDate: Fri, 5 Mar 2010 13:49:35 +0100
Committer:  Ingo Molnar <mingo@elte.hu>
CommitDate: Wed, 10 Mar 2010 13:23:35 +0100

perf, x86: Clear the LBRs on init

Some CPUs have errata where the LBR is not cleared on Power-On. So always
clear the LBRs before use.

Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Arnaldo Carvalho de Melo <acme@infradead.org>
Cc: paulus@samba.org
Cc: eranian@google.com
Cc: robert.richter@amd.com
Cc: fweisbec@gmail.com
LKML-Reference: <20100305154128.966563424@chello.nl>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
---
 arch/x86/kernel/cpu/perf_event_intel.c     |   18 ++++++++++++++++--
 arch/x86/kernel/cpu/perf_event_intel_lbr.c |    3 +++
 2 files changed, 19 insertions(+), 2 deletions(-)

diff --git a/arch/x86/kernel/cpu/perf_event_intel.c b/arch/x86/kernel/cpu/perf_event_intel.c
index 224c952..c135ed7 100644
--- a/arch/x86/kernel/cpu/perf_event_intel.c
+++ b/arch/x86/kernel/cpu/perf_event_intel.c
@@ -767,6 +767,20 @@ static __initconst struct x86_pmu core_pmu = {
 	.event_constraints	= intel_core_event_constraints,
 };
 
+static void intel_pmu_cpu_starting(int cpu)
+{
+	init_debug_store_on_cpu(cpu);
+	/*
+	 * Deal with CPUs that don't clear their LBRs on power-up.
+	 */
+	intel_pmu_lbr_reset();
+}
+
+static void intel_pmu_cpu_dying(int cpu)
+{
+	fini_debug_store_on_cpu(cpu);
+}
+
 static __initconst struct x86_pmu intel_pmu = {
 	.name			= "Intel",
 	.handle_irq		= intel_pmu_handle_irq,
@@ -788,8 +802,8 @@ static __initconst struct x86_pmu intel_pmu = {
 	.max_period		= (1ULL << 31) - 1,
 	.get_event_constraints	= intel_get_event_constraints,
 
-	.cpu_starting		= init_debug_store_on_cpu,
-	.cpu_dying		= fini_debug_store_on_cpu,
+	.cpu_starting		= intel_pmu_cpu_starting,
+	.cpu_dying		= intel_pmu_cpu_dying,
 };
 
 static void intel_clovertown_quirks(void)
diff --git a/arch/x86/kernel/cpu/perf_event_intel_lbr.c b/arch/x86/kernel/cpu/perf_event_intel_lbr.c
index 4f3a124..dcec765 100644
--- a/arch/x86/kernel/cpu/perf_event_intel_lbr.c
+++ b/arch/x86/kernel/cpu/perf_event_intel_lbr.c
@@ -53,6 +53,9 @@ static void intel_pmu_lbr_reset_64(void)
 
 static void intel_pmu_lbr_reset(void)
 {
+	if (!x86_pmu.lbr_nr)
+		return;
+
 	if (x86_pmu.intel_cap.lbr_format == LBR_FORMAT_32)
 		intel_pmu_lbr_reset_32();
 	else

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

* [tip:perf/pebs] perf, x86: Robustify PEBS fixup
  2010-03-05 15:39 ` [PATCH 5/5] perf, x86: Robustify PEBS fixup Peter Zijlstra
@ 2010-03-10 13:21   ` tip-bot for Peter Zijlstra
  0 siblings, 0 replies; 23+ messages in thread
From: tip-bot for Peter Zijlstra @ 2010-03-10 13:21 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: linux-kernel, hpa, mingo, acme, a.p.zijlstra, tglx, mingo

Commit-ID:  a562b1871f7f7d2f3a835c3c1e07fa58d473cfb7
Gitweb:     http://git.kernel.org/tip/a562b1871f7f7d2f3a835c3c1e07fa58d473cfb7
Author:     Peter Zijlstra <a.p.zijlstra@chello.nl>
AuthorDate: Fri, 5 Mar 2010 16:29:14 +0100
Committer:  Ingo Molnar <mingo@elte.hu>
CommitDate: Wed, 10 Mar 2010 13:23:35 +0100

perf, x86: Robustify PEBS fixup

It turns out the LBR is massively unreliable on certain CPUs, so code the
fixup a little more defensive to avoid crashing the kernel.

Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Arnaldo Carvalho de Melo <acme@infradead.org>
Cc: paulus@samba.org
Cc: eranian@google.com
Cc: robert.richter@amd.com
Cc: fweisbec@gmail.com
LKML-Reference: <20100305154129.042271287@chello.nl>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
---
 arch/x86/kernel/cpu/perf_event_intel_ds.c |   21 +++++++++++++++++++--
 1 files changed, 19 insertions(+), 2 deletions(-)

diff --git a/arch/x86/kernel/cpu/perf_event_intel_ds.c b/arch/x86/kernel/cpu/perf_event_intel_ds.c
index a67fff1..e7ac517 100644
--- a/arch/x86/kernel/cpu/perf_event_intel_ds.c
+++ b/arch/x86/kernel/cpu/perf_event_intel_ds.c
@@ -399,10 +399,23 @@ static int intel_pmu_pebs_fixup_ip(struct pt_regs *regs)
 	if (!x86_pmu.intel_cap.pebs_trap)
 		return 1;
 
+	/*
+	 * No LBR entry, no basic block, no rewinding
+	 */
 	if (!cpuc->lbr_stack.nr || !from || !to)
 		return 0;
 
-	if (ip < to)
+	/*
+	 * Basic blocks should never cross user/kernel boundaries
+	 */
+	if (kernel_ip(ip) != kernel_ip(to))
+		return 0;
+
+	/*
+	 * unsigned math, either ip is before the start (impossible) or
+	 * the basic block is larger than 1 page (sanity)
+	 */
+	if ((ip - to) > PAGE_SIZE)
 		return 0;
 
 	/*
@@ -420,7 +433,7 @@ static int intel_pmu_pebs_fixup_ip(struct pt_regs *regs)
 
 		old_to = to;
 		if (!kernel_ip(ip)) {
-			int bytes, size = min_t(int, MAX_INSN_SIZE, ip - to);
+			int bytes, size = MAX_INSN_SIZE;
 
 			bytes = copy_from_user_nmi(buf, (void __user *)to, size);
 			if (bytes != size)
@@ -440,6 +453,10 @@ static int intel_pmu_pebs_fixup_ip(struct pt_regs *regs)
 		return 1;
 	}
 
+	/*
+	 * Even though we decoded the basic block, the instruction stream
+	 * never matched the given IP, either the TO or the IP got corrupted.
+	 */
 	return 0;
 }
 

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

end of thread, other threads:[~2010-03-10 13:22 UTC | newest]

Thread overview: 23+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-03-05 15:39 [PATCH 0/5] PEBS and LBR fixes Peter Zijlstra
2010-03-05 15:39 ` [PATCH 1/5] perf: Rework the arch CPU-hotplug hooks Peter Zijlstra
2010-03-10 13:10   ` [tip:perf/urgent] perf: Rework and fix " tip-bot for Peter Zijlstra
2010-03-05 15:39 ` [PATCH 2/5] perf, x86: Fix silly bug in data store buffer allocation Peter Zijlstra
2010-03-10 13:20   ` [tip:perf/pebs] " tip-bot for Peter Zijlstra
2010-03-05 15:39 ` [PATCH 3/5] perf, x86: Disable PEBS on clowertown chips Peter Zijlstra
2010-03-05 18:58   ` Stephane Eranian
2010-03-05 19:15     ` Peter Zijlstra
2010-03-05 19:28       ` Stephane Eranian
2010-03-05 19:37         ` Peter Zijlstra
2010-03-05 21:05       ` Peter Zijlstra
2010-03-05 21:22         ` Stephane Eranian
2010-03-05 21:35           ` Peter Zijlstra
2010-03-05 21:38             ` Stephane Eranian
2010-03-05 21:43               ` Peter Zijlstra
2010-03-05 21:57                 ` Stephane Eranian
2010-03-05 22:25                   ` Peter Zijlstra
2010-03-05 22:33                     ` Stephane Eranian
2010-03-10 13:21   ` [tip:perf/pebs] perf, x86: Disable PEBS on clovertown chips tip-bot for Peter Zijlstra
2010-03-05 15:39 ` [PATCH 4/5] perf, x86: Clear the LBRs on init Peter Zijlstra
2010-03-10 13:21   ` [tip:perf/pebs] " tip-bot for Peter Zijlstra
2010-03-05 15:39 ` [PATCH 5/5] perf, x86: Robustify PEBS fixup Peter Zijlstra
2010-03-10 13:21   ` [tip:perf/pebs] " tip-bot for Peter Zijlstra

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.