public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH] perfcounters: IRQ and NMI support on AMD CPUs
@ 2009-03-05 17:20 Peter Zijlstra
  2009-03-05 17:25 ` Ingo Molnar
                   ` (2 more replies)
  0 siblings, 3 replies; 16+ messages in thread
From: Peter Zijlstra @ 2009-03-05 17:20 UTC (permalink / raw)
  To: Ingo Molnar; +Cc: Jaswinder Singh Rajput, Paul Mackerras, lkml

Subject: perfcounters: IRQ and NMI support on AMD CPUs
From: Peter Zijlstra <a.p.zijlstra@chello.nl>
Date: Thu Mar 05 18:08:27 CET 2009

The below completes the K7+ performance counter support.

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

Index: linux-2.6/arch/x86/kernel/cpu/perf_counter.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/cpu/perf_counter.c
+++ linux-2.6/arch/x86/kernel/cpu/perf_counter.c
@@ -28,6 +28,7 @@ static bool perf_counters_initialized __
 static int nr_counters_generic __read_mostly;
 static u64 perf_counter_mask __read_mostly;
 static u64 counter_value_mask __read_mostly;
+static int counter_value_bits __read_mostly;
 
 static int nr_counters_fixed __read_mostly;
 
@@ -35,7 +36,9 @@ struct cpu_hw_counters {
 	struct perf_counter	*counters[X86_PMC_IDX_MAX];
 	unsigned long		used[BITS_TO_LONGS(X86_PMC_IDX_MAX)];
 	unsigned long		interrupts;
-	u64			global_enable;
+	u64			throttle_ctrl;
+	u64			active_mask;
+	int			enabled;
 };
 
 /*
@@ -43,21 +46,28 @@ struct cpu_hw_counters {
  */
 struct pmc_x86_ops {
 	u64		(*save_disable_all)(void);
-	void		(*restore_all)(u64 ctrl);
+	void		(*restore_all)(u64);
+	u64		(*get_status)(u64);
+	void		(*ack_status)(u64);
+	void		(*enable)(int, u64);
+	void		(*disable)(int, u64);
 	unsigned	eventsel;
 	unsigned	perfctr;
-	int		(*event_map)(int event);
+	u64		(*event_map)(int);
+	u64		(*raw_event)(u64);
 	int		max_events;
 };
 
 static struct pmc_x86_ops *pmc_ops;
 
-static DEFINE_PER_CPU(struct cpu_hw_counters, cpu_hw_counters);
+static DEFINE_PER_CPU(struct cpu_hw_counters, cpu_hw_counters) = {
+	.enabled = 1,
+};
 
 /*
  * Intel PerfMon v3. Used on Core2 and later.
  */
-static const int intel_perfmon_event_map[] =
+static const u64 intel_perfmon_event_map[] =
 {
   [PERF_COUNT_CPU_CYCLES]		= 0x003c,
   [PERF_COUNT_INSTRUCTIONS]		= 0x00c0,
@@ -68,15 +78,29 @@ static const int intel_perfmon_event_map
   [PERF_COUNT_BUS_CYCLES]		= 0x013c,
 };
 
-static int pmc_intel_event_map(int event)
+static u64 pmc_intel_event_map(int event)
 {
 	return intel_perfmon_event_map[event];
 }
 
+static u64 pmc_intel_raw_event(u64 event)
+{
+#define CORE_EVNTSEL_EVENT_MASK		0x000000FF
+#define CORE_EVNTSEL_UNIT_MASK		0x0000FF00
+#define CORE_EVNTSEL_COUNTER_MASK	0xFF000000
+
+#define CORE_EVNTSEL_MASK 		\
+	(CORE_EVNTSEL_EVENT_MASK |	\
+	 CORE_EVNTSEL_UNIT_MASK  |	\
+	 CORE_EVNTSEL_COUNTER_MASK)
+
+	return event & CORE_EVNTSEL_MASK;
+}
+
 /*
  * AMD Performance Monitor K7 and later.
  */
-static const int amd_perfmon_event_map[] =
+static const u64 amd_perfmon_event_map[] =
 {
   [PERF_COUNT_CPU_CYCLES]		= 0x0076,
   [PERF_COUNT_INSTRUCTIONS]		= 0x00c0,
@@ -86,11 +110,25 @@ static const int amd_perfmon_event_map[]
   [PERF_COUNT_BRANCH_MISSES]		= 0x00c5,
 };
 
-static int pmc_amd_event_map(int event)
+static u64 pmc_amd_event_map(int event)
 {
 	return amd_perfmon_event_map[event];
 }
 
+static u64 pmc_amd_raw_event(u64 event)
+{
+#define K7_EVNTSEL_EVENT_MASK	0x7000000FF
+#define K7_EVNTSEL_UNIT_MASK	0x00000FF00
+#define K7_EVNTSEL_COUNTER_MASK	0x0FF000000
+
+#define K7_EVNTSEL_MASK			\
+	(K7_EVNTSEL_EVENT_MASK |	\
+	 K7_EVNTSEL_UNIT_MASK  |	\
+	 K7_EVNTSEL_COUNTER_MASK)
+
+	return event & K7_EVNTSEL_MASK;
+}
+
 /*
  * Propagate counter elapsed time into the generic counter.
  * Can only be executed on the CPU where the counter is active.
@@ -179,7 +217,7 @@ static int __hw_perf_counter_init(struct
 	 * Raw event type provide the config in the event structure
 	 */
 	if (hw_event->raw) {
-		hwc->config |= hw_event->type;
+		hwc->config |= pmc_ops->raw_event(hw_event->type);
 	} else {
 		if (hw_event->type >= pmc_ops->max_events)
 			return -EINVAL;
@@ -205,18 +243,24 @@ static u64 pmc_intel_save_disable_all(vo
 
 static u64 pmc_amd_save_disable_all(void)
 {
-	int idx;
-	u64 val, ctrl = 0;
+	struct cpu_hw_counters *cpuc = &__get_cpu_var(cpu_hw_counters);
+	int enabled, idx;
+
+	enabled = cpuc->enabled;
+	cpuc->enabled = 0;
+	barrier();
 
 	for (idx = 0; idx < nr_counters_generic; idx++) {
+		u64 val;
+
 		rdmsrl(MSR_K7_EVNTSEL0 + idx, val);
-		if (val & ARCH_PERFMON_EVENTSEL0_ENABLE)
-			ctrl |= (1 << idx);
-		val &= ~ARCH_PERFMON_EVENTSEL0_ENABLE;
-		wrmsrl(MSR_K7_EVNTSEL0 + idx, val);
+		if (val & ARCH_PERFMON_EVENTSEL0_ENABLE) {
+			val &= ~ARCH_PERFMON_EVENTSEL0_ENABLE;
+			wrmsrl(MSR_K7_EVNTSEL0 + idx, val);
+		}
 	}
 
-	return ctrl;
+	return enabled;
 }
 
 u64 hw_perf_save_disable(void)
@@ -226,6 +270,9 @@ u64 hw_perf_save_disable(void)
 
 	return pmc_ops->save_disable_all();
 }
+/*
+ * Exported because of ACPI idle
+ */
 EXPORT_SYMBOL_GPL(hw_perf_save_disable);
 
 static void pmc_intel_restore_all(u64 ctrl)
@@ -235,11 +282,18 @@ static void pmc_intel_restore_all(u64 ct
 
 static void pmc_amd_restore_all(u64 ctrl)
 {
-	u64 val;
+	struct cpu_hw_counters *cpuc = &__get_cpu_var(cpu_hw_counters);
 	int idx;
 
+	cpuc->enabled = ctrl;
+	barrier();
+	if (!ctrl)
+		return;
+
 	for (idx = 0; idx < nr_counters_generic; idx++) {
-		if (ctrl & (1 << idx)) {
+		if (test_bit(idx, (unsigned long *)&cpuc->active_mask)) {
+			u64 val;
+
 			rdmsrl(MSR_K7_EVNTSEL0 + idx, val);
 			val |= ARCH_PERFMON_EVENTSEL0_ENABLE;
 			wrmsrl(MSR_K7_EVNTSEL0 + idx, val);
@@ -254,8 +308,112 @@ void hw_perf_restore(u64 ctrl)
 
 	pmc_ops->restore_all(ctrl);
 }
+/*
+ * Exported because of ACPI idle
+ */
 EXPORT_SYMBOL_GPL(hw_perf_restore);
 
+static u64 pmc_intel_get_status(u64 mask)
+{
+	u64 status;
+
+	rdmsrl(MSR_CORE_PERF_GLOBAL_STATUS, status);
+
+	return status;
+}
+
+static u64 pmc_amd_get_status(u64 mask)
+{
+	u64 status = 0;
+	int idx;
+
+	for (idx = 0; idx < nr_counters_generic; idx++) {
+		s64 val;
+
+		if (!(mask & (1 << idx)))
+			continue;
+
+		rdmsrl(MSR_K7_PERFCTR0 + idx, val);
+		val <<= (64 - counter_value_bits);
+		if (val >= 0)
+			status |= (1 << idx);
+	}
+
+	return status;
+}
+
+static u64 hw_perf_get_status(u64 mask)
+{
+	if (unlikely(!perf_counters_initialized))
+		return 0;
+
+	return pmc_ops->get_status(mask);
+}
+
+static void pmc_intel_ack_status(u64 ack)
+{
+	wrmsrl(MSR_CORE_PERF_GLOBAL_OVF_CTRL, ack);
+}
+
+static void pmc_amd_ack_status(u64 ack)
+{
+}
+
+static void hw_perf_ack_status(u64 ack)
+{
+	if (unlikely(!perf_counters_initialized))
+		return;
+
+	pmc_ops->ack_status(ack);
+}
+
+static void pmc_intel_enable(int idx, u64 config)
+{
+	wrmsrl(MSR_ARCH_PERFMON_EVENTSEL0 + idx,
+			config | ARCH_PERFMON_EVENTSEL0_ENABLE);
+}
+
+static void pmc_amd_enable(int idx, u64 config)
+{
+	struct cpu_hw_counters *cpuc = &__get_cpu_var(cpu_hw_counters);
+
+	set_bit(idx, (unsigned long *)&cpuc->active_mask);
+	if (cpuc->enabled)
+		config |= ARCH_PERFMON_EVENTSEL0_ENABLE;
+
+	wrmsrl(MSR_K7_EVNTSEL0 + idx, config);
+}
+
+static void hw_perf_enable(int idx, u64 config)
+{
+	if (unlikely(!perf_counters_initialized))
+		return;
+
+	pmc_ops->enable(idx, config);
+}
+
+static void pmc_intel_disable(int idx, u64 config)
+{
+	wrmsrl(MSR_ARCH_PERFMON_EVENTSEL0 + idx, config);
+}
+
+static void pmc_amd_disable(int idx, u64 config)
+{
+	struct cpu_hw_counters *cpuc = &__get_cpu_var(cpu_hw_counters);
+
+	clear_bit(idx, (unsigned long *)&cpuc->active_mask);
+	wrmsrl(MSR_K7_EVNTSEL0 + idx, config);
+
+}
+
+static void hw_perf_disable(int idx, u64 config)
+{
+	if (unlikely(!perf_counters_initialized))
+		return;
+
+	pmc_ops->disable(idx, config);
+}
+
 static inline void
 __pmc_fixed_disable(struct perf_counter *counter,
 		    struct hw_perf_counter *hwc, unsigned int __idx)
@@ -278,7 +436,7 @@ __pmc_generic_disable(struct perf_counte
 	if (unlikely(hwc->config_base == MSR_ARCH_PERFMON_FIXED_CTR_CTRL))
 		__pmc_fixed_disable(counter, hwc, idx);
 	else
-		wrmsr_safe(hwc->config_base + idx, hwc->config, 0);
+		hw_perf_disable(idx, hwc->config);
 }
 
 static DEFINE_PER_CPU(u64, prev_left[X86_PMC_IDX_MAX]);
@@ -354,8 +512,7 @@ __pmc_generic_enable(struct perf_counter
 	if (unlikely(hwc->config_base == MSR_ARCH_PERFMON_FIXED_CTR_CTRL))
 		__pmc_fixed_enable(counter, hwc, idx);
 	else
-		wrmsr(hwc->config_base + idx,
-		      hwc->config | ARCH_PERFMON_EVENTSEL0_ENABLE, 0);
+		hw_perf_enable(idx, hwc->config);
 }
 
 static int
@@ -567,22 +724,20 @@ perf_handle_group(struct perf_counter *s
  * This handler is triggered by the local APIC, so the APIC IRQ handling
  * rules apply:
  */
-static void __smp_perf_counter_interrupt(struct pt_regs *regs, int nmi)
+static int __smp_perf_counter_interrupt(struct pt_regs *regs, int nmi)
 {
 	int bit, cpu = smp_processor_id();
 	u64 ack, status;
 	struct cpu_hw_counters *cpuc = &per_cpu(cpu_hw_counters, cpu);
+	int ret = 0;
 
-	rdmsrl(MSR_CORE_PERF_GLOBAL_CTRL, cpuc->global_enable);
+	cpuc->throttle_ctrl = hw_perf_save_disable();
 
-	/* Disable counters globally */
-	wrmsrl(MSR_CORE_PERF_GLOBAL_CTRL, 0);
-	ack_APIC_irq();
-
-	rdmsrl(MSR_CORE_PERF_GLOBAL_STATUS, status);
+	status = hw_perf_get_status(cpuc->throttle_ctrl);
 	if (!status)
 		goto out;
 
+	ret = 1;
 again:
 	inc_irq_stat(apic_perf_irqs);
 	ack = status;
@@ -618,12 +773,12 @@ again:
 		}
 	}
 
-	wrmsrl(MSR_CORE_PERF_GLOBAL_OVF_CTRL, ack);
+	hw_perf_ack_status(ack);
 
 	/*
 	 * Repeat if there is more work to be done:
 	 */
-	rdmsrl(MSR_CORE_PERF_GLOBAL_STATUS, status);
+	status = hw_perf_get_status(cpuc->throttle_ctrl);
 	if (status)
 		goto again;
 out:
@@ -631,32 +786,27 @@ out:
 	 * Restore - do not reenable when global enable is off or throttled:
 	 */
 	if (++cpuc->interrupts < PERFMON_MAX_INTERRUPTS)
-		wrmsrl(MSR_CORE_PERF_GLOBAL_CTRL, cpuc->global_enable);
+		hw_perf_restore(cpuc->throttle_ctrl);
+
+	return ret;
 }
 
 void perf_counter_unthrottle(void)
 {
 	struct cpu_hw_counters *cpuc;
-	u64 global_enable;
 
 	if (!cpu_has(&boot_cpu_data, X86_FEATURE_ARCH_PERFMON))
 		return;
 
-	if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD)
-		return;
-
 	if (unlikely(!perf_counters_initialized))
 		return;
 
-	cpuc = &per_cpu(cpu_hw_counters, smp_processor_id());
+	cpuc = &__get_cpu_var(cpu_hw_counters);
 	if (cpuc->interrupts >= PERFMON_MAX_INTERRUPTS) {
 		if (printk_ratelimit())
 			printk(KERN_WARNING "PERFMON: max interrupts exceeded!\n");
-		wrmsrl(MSR_CORE_PERF_GLOBAL_CTRL, cpuc->global_enable);
+		hw_perf_restore(cpuc->throttle_ctrl);
 	}
-	rdmsrl(MSR_CORE_PERF_GLOBAL_CTRL, global_enable);
-	if (unlikely(cpuc->global_enable && !global_enable))
-		wrmsrl(MSR_CORE_PERF_GLOBAL_CTRL, cpuc->global_enable);
 	cpuc->interrupts = 0;
 }
 
@@ -664,8 +814,8 @@ void smp_perf_counter_interrupt(struct p
 {
 	irq_enter();
 	apic_write(APIC_LVTPC, LOCAL_PERF_VECTOR);
+	ack_APIC_irq();
 	__smp_perf_counter_interrupt(regs, 0);
-
 	irq_exit();
 }
 
@@ -722,16 +872,23 @@ perf_counter_nmi_handler(struct notifier
 {
 	struct die_args *args = __args;
 	struct pt_regs *regs;
+	int ret;
+
+	switch (cmd) {
+	case DIE_NMI:
+	case DIE_NMI_IPI:
+		break;
 
-	if (likely(cmd != DIE_NMI_IPI))
+	default:
 		return NOTIFY_DONE;
+	}
 
 	regs = args->regs;
 
 	apic_write(APIC_LVTPC, APIC_DM_NMI);
-	__smp_perf_counter_interrupt(regs, 1);
+	ret = __smp_perf_counter_interrupt(regs, 1);
 
-	return NOTIFY_STOP;
+	return ret ? NOTIFY_STOP : NOTIFY_OK;
 }
 
 static __read_mostly struct notifier_block perf_counter_nmi_notifier = {
@@ -743,18 +900,28 @@ static __read_mostly struct notifier_blo
 static struct pmc_x86_ops pmc_intel_ops = {
 	.save_disable_all	= pmc_intel_save_disable_all,
 	.restore_all		= pmc_intel_restore_all,
+	.get_status		= pmc_intel_get_status,
+	.ack_status		= pmc_intel_ack_status,
+	.enable			= pmc_intel_enable,
+	.disable		= pmc_intel_disable,
 	.eventsel		= MSR_ARCH_PERFMON_EVENTSEL0,
 	.perfctr		= MSR_ARCH_PERFMON_PERFCTR0,
 	.event_map		= pmc_intel_event_map,
+	.raw_event		= pmc_intel_raw_event,
 	.max_events		= ARRAY_SIZE(intel_perfmon_event_map),
 };
 
 static struct pmc_x86_ops pmc_amd_ops = {
 	.save_disable_all	= pmc_amd_save_disable_all,
 	.restore_all		= pmc_amd_restore_all,
+	.get_status		= pmc_amd_get_status,
+	.ack_status		= pmc_amd_ack_status,
+	.enable			= pmc_amd_enable,
+	.disable		= pmc_amd_disable,
 	.eventsel		= MSR_K7_EVNTSEL0,
 	.perfctr		= MSR_K7_PERFCTR0,
 	.event_map		= pmc_amd_event_map,
+	.raw_event		= pmc_amd_raw_event,
 	.max_events		= ARRAY_SIZE(amd_perfmon_event_map),
 };
 
@@ -787,8 +954,25 @@ static struct pmc_x86_ops *pmc_intel_ini
 
 static struct pmc_x86_ops *pmc_amd_init(void)
 {
+	u64 old;
+	int bits;
+
 	nr_counters_generic = 4;
 	nr_counters_fixed = 0;
+	counter_value_mask = ~0ULL;
+
+	rdmsrl(MSR_K7_PERFCTR0, old);
+	wrmsrl(MSR_K7_PERFCTR0, counter_value_mask);
+	/*
+	 * read the truncated mask
+	 */
+	rdmsrl(MSR_K7_PERFCTR0, counter_value_mask);
+	wrmsrl(MSR_K7_PERFCTR0, old);
+
+	bits = 32 + fls(counter_value_mask >> 32);
+	if (bits == 32)
+		bits = fls((u32)counter_value_mask);
+	counter_value_bits = bits;
 
 	pr_info("AMD Performance Monitoring support detected.\n");
 



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

* Re: [PATCH] perfcounters: IRQ and NMI support on AMD CPUs
  2009-03-05 17:20 [PATCH] perfcounters: IRQ and NMI support on AMD CPUs Peter Zijlstra
@ 2009-03-05 17:25 ` Ingo Molnar
  2009-03-05 17:27 ` [tip:perfcounters/core] " Peter Zijlstra
  2009-03-05 18:32 ` [PATCH] " Jaswinder Singh Rajput
  2 siblings, 0 replies; 16+ messages in thread
From: Ingo Molnar @ 2009-03-05 17:25 UTC (permalink / raw)
  To: Peter Zijlstra; +Cc: Jaswinder Singh Rajput, Paul Mackerras, lkml


* Peter Zijlstra <peterz@infradead.org> wrote:

> Subject: perfcounters: IRQ and NMI support on AMD CPUs
> From: Peter Zijlstra <a.p.zijlstra@chello.nl>
> Date: Thu Mar 05 18:08:27 CET 2009
> 
> The below completes the K7+ performance counter support.
> 
> Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
> ---
>  arch/x86/kernel/cpu/perf_counter.c |  272 +++++++++++++++++++++++++++++++------
>  1 file changed, 228 insertions(+), 44 deletions(-)

Great work, thanks Peter! I've applied it to 
tip:perfcounters/core and tip:master.

	Ingo

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

* [tip:perfcounters/core] perfcounters: IRQ and NMI support on AMD CPUs
  2009-03-05 17:20 [PATCH] perfcounters: IRQ and NMI support on AMD CPUs Peter Zijlstra
  2009-03-05 17:25 ` Ingo Molnar
@ 2009-03-05 17:27 ` Peter Zijlstra
  2009-03-12  1:44   ` Robert Richter
  2009-03-05 18:32 ` [PATCH] " Jaswinder Singh Rajput
  2 siblings, 1 reply; 16+ messages in thread
From: Peter Zijlstra @ 2009-03-05 17:27 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: linux-kernel, paulus, hpa, mingo, a.p.zijlstra, jaswinder, tglx,
	mingo

Commit-ID:  b0f3f28e0f14eb335f67bfaae33ce8b8d74fd58b
Gitweb:     http://git.kernel.org/tip/b0f3f28e0f14eb335f67bfaae33ce8b8d74fd58b
Author:     "Peter Zijlstra" <a.p.zijlstra@chello.nl>
AuthorDate: Thu, 5 Mar 2009 18:08:27 +0100
Commit:     Ingo Molnar <mingo@elte.hu>
CommitDate: Thu, 5 Mar 2009 18:25:16 +0100

perfcounters: IRQ and NMI support on AMD CPUs

The below completes the K7+ performance counter support:

 - IRQ support
 - NMI support

KernelTop output works now as well.

Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Jaswinder Singh Rajput <jaswinder@kernel.org>
Cc: Paul Mackerras <paulus@samba.org>
LKML-Reference: <1236273633.5187.286.camel@laptop>
Signed-off-by: Ingo Molnar <mingo@elte.hu>


---
 arch/x86/kernel/cpu/perf_counter.c |  272 ++++++++++++++++++++++++++++++------
 1 files changed, 228 insertions(+), 44 deletions(-)

diff --git a/arch/x86/kernel/cpu/perf_counter.c b/arch/x86/kernel/cpu/perf_counter.c
index 3b65f19..6ebe9ab 100644
--- a/arch/x86/kernel/cpu/perf_counter.c
+++ b/arch/x86/kernel/cpu/perf_counter.c
@@ -28,6 +28,7 @@ static bool perf_counters_initialized __read_mostly;
 static int nr_counters_generic __read_mostly;
 static u64 perf_counter_mask __read_mostly;
 static u64 counter_value_mask __read_mostly;
+static int counter_value_bits __read_mostly;
 
 static int nr_counters_fixed __read_mostly;
 
@@ -35,7 +36,9 @@ struct cpu_hw_counters {
 	struct perf_counter	*counters[X86_PMC_IDX_MAX];
 	unsigned long		used[BITS_TO_LONGS(X86_PMC_IDX_MAX)];
 	unsigned long		interrupts;
-	u64			global_enable;
+	u64			throttle_ctrl;
+	u64			active_mask;
+	int			enabled;
 };
 
 /*
@@ -43,21 +46,28 @@ struct cpu_hw_counters {
  */
 struct pmc_x86_ops {
 	u64		(*save_disable_all)(void);
-	void		(*restore_all)(u64 ctrl);
+	void		(*restore_all)(u64);
+	u64		(*get_status)(u64);
+	void		(*ack_status)(u64);
+	void		(*enable)(int, u64);
+	void		(*disable)(int, u64);
 	unsigned	eventsel;
 	unsigned	perfctr;
-	int		(*event_map)(int event);
+	u64		(*event_map)(int);
+	u64		(*raw_event)(u64);
 	int		max_events;
 };
 
 static struct pmc_x86_ops *pmc_ops;
 
-static DEFINE_PER_CPU(struct cpu_hw_counters, cpu_hw_counters);
+static DEFINE_PER_CPU(struct cpu_hw_counters, cpu_hw_counters) = {
+	.enabled = 1,
+};
 
 /*
  * Intel PerfMon v3. Used on Core2 and later.
  */
-static const int intel_perfmon_event_map[] =
+static const u64 intel_perfmon_event_map[] =
 {
   [PERF_COUNT_CPU_CYCLES]		= 0x003c,
   [PERF_COUNT_INSTRUCTIONS]		= 0x00c0,
@@ -68,15 +78,29 @@ static const int intel_perfmon_event_map[] =
   [PERF_COUNT_BUS_CYCLES]		= 0x013c,
 };
 
-static int pmc_intel_event_map(int event)
+static u64 pmc_intel_event_map(int event)
 {
 	return intel_perfmon_event_map[event];
 }
 
+static u64 pmc_intel_raw_event(u64 event)
+{
+#define CORE_EVNTSEL_EVENT_MASK		0x000000FF
+#define CORE_EVNTSEL_UNIT_MASK		0x0000FF00
+#define CORE_EVNTSEL_COUNTER_MASK	0xFF000000
+
+#define CORE_EVNTSEL_MASK 		\
+	(CORE_EVNTSEL_EVENT_MASK |	\
+	 CORE_EVNTSEL_UNIT_MASK  |	\
+	 CORE_EVNTSEL_COUNTER_MASK)
+
+	return event & CORE_EVNTSEL_MASK;
+}
+
 /*
  * AMD Performance Monitor K7 and later.
  */
-static const int amd_perfmon_event_map[] =
+static const u64 amd_perfmon_event_map[] =
 {
   [PERF_COUNT_CPU_CYCLES]		= 0x0076,
   [PERF_COUNT_INSTRUCTIONS]		= 0x00c0,
@@ -86,11 +110,25 @@ static const int amd_perfmon_event_map[] =
   [PERF_COUNT_BRANCH_MISSES]		= 0x00c5,
 };
 
-static int pmc_amd_event_map(int event)
+static u64 pmc_amd_event_map(int event)
 {
 	return amd_perfmon_event_map[event];
 }
 
+static u64 pmc_amd_raw_event(u64 event)
+{
+#define K7_EVNTSEL_EVENT_MASK	0x7000000FF
+#define K7_EVNTSEL_UNIT_MASK	0x00000FF00
+#define K7_EVNTSEL_COUNTER_MASK	0x0FF000000
+
+#define K7_EVNTSEL_MASK			\
+	(K7_EVNTSEL_EVENT_MASK |	\
+	 K7_EVNTSEL_UNIT_MASK  |	\
+	 K7_EVNTSEL_COUNTER_MASK)
+
+	return event & K7_EVNTSEL_MASK;
+}
+
 /*
  * Propagate counter elapsed time into the generic counter.
  * Can only be executed on the CPU where the counter is active.
@@ -179,7 +217,7 @@ static int __hw_perf_counter_init(struct perf_counter *counter)
 	 * Raw event type provide the config in the event structure
 	 */
 	if (hw_event->raw) {
-		hwc->config |= hw_event->type;
+		hwc->config |= pmc_ops->raw_event(hw_event->type);
 	} else {
 		if (hw_event->type >= pmc_ops->max_events)
 			return -EINVAL;
@@ -205,18 +243,24 @@ static u64 pmc_intel_save_disable_all(void)
 
 static u64 pmc_amd_save_disable_all(void)
 {
-	int idx;
-	u64 val, ctrl = 0;
+	struct cpu_hw_counters *cpuc = &__get_cpu_var(cpu_hw_counters);
+	int enabled, idx;
+
+	enabled = cpuc->enabled;
+	cpuc->enabled = 0;
+	barrier();
 
 	for (idx = 0; idx < nr_counters_generic; idx++) {
+		u64 val;
+
 		rdmsrl(MSR_K7_EVNTSEL0 + idx, val);
-		if (val & ARCH_PERFMON_EVENTSEL0_ENABLE)
-			ctrl |= (1 << idx);
-		val &= ~ARCH_PERFMON_EVENTSEL0_ENABLE;
-		wrmsrl(MSR_K7_EVNTSEL0 + idx, val);
+		if (val & ARCH_PERFMON_EVENTSEL0_ENABLE) {
+			val &= ~ARCH_PERFMON_EVENTSEL0_ENABLE;
+			wrmsrl(MSR_K7_EVNTSEL0 + idx, val);
+		}
 	}
 
-	return ctrl;
+	return enabled;
 }
 
 u64 hw_perf_save_disable(void)
@@ -226,6 +270,9 @@ u64 hw_perf_save_disable(void)
 
 	return pmc_ops->save_disable_all();
 }
+/*
+ * Exported because of ACPI idle
+ */
 EXPORT_SYMBOL_GPL(hw_perf_save_disable);
 
 static void pmc_intel_restore_all(u64 ctrl)
@@ -235,11 +282,18 @@ static void pmc_intel_restore_all(u64 ctrl)
 
 static void pmc_amd_restore_all(u64 ctrl)
 {
-	u64 val;
+	struct cpu_hw_counters *cpuc = &__get_cpu_var(cpu_hw_counters);
 	int idx;
 
+	cpuc->enabled = ctrl;
+	barrier();
+	if (!ctrl)
+		return;
+
 	for (idx = 0; idx < nr_counters_generic; idx++) {
-		if (ctrl & (1 << idx)) {
+		if (test_bit(idx, (unsigned long *)&cpuc->active_mask)) {
+			u64 val;
+
 			rdmsrl(MSR_K7_EVNTSEL0 + idx, val);
 			val |= ARCH_PERFMON_EVENTSEL0_ENABLE;
 			wrmsrl(MSR_K7_EVNTSEL0 + idx, val);
@@ -254,8 +308,112 @@ void hw_perf_restore(u64 ctrl)
 
 	pmc_ops->restore_all(ctrl);
 }
+/*
+ * Exported because of ACPI idle
+ */
 EXPORT_SYMBOL_GPL(hw_perf_restore);
 
+static u64 pmc_intel_get_status(u64 mask)
+{
+	u64 status;
+
+	rdmsrl(MSR_CORE_PERF_GLOBAL_STATUS, status);
+
+	return status;
+}
+
+static u64 pmc_amd_get_status(u64 mask)
+{
+	u64 status = 0;
+	int idx;
+
+	for (idx = 0; idx < nr_counters_generic; idx++) {
+		s64 val;
+
+		if (!(mask & (1 << idx)))
+			continue;
+
+		rdmsrl(MSR_K7_PERFCTR0 + idx, val);
+		val <<= (64 - counter_value_bits);
+		if (val >= 0)
+			status |= (1 << idx);
+	}
+
+	return status;
+}
+
+static u64 hw_perf_get_status(u64 mask)
+{
+	if (unlikely(!perf_counters_initialized))
+		return 0;
+
+	return pmc_ops->get_status(mask);
+}
+
+static void pmc_intel_ack_status(u64 ack)
+{
+	wrmsrl(MSR_CORE_PERF_GLOBAL_OVF_CTRL, ack);
+}
+
+static void pmc_amd_ack_status(u64 ack)
+{
+}
+
+static void hw_perf_ack_status(u64 ack)
+{
+	if (unlikely(!perf_counters_initialized))
+		return;
+
+	pmc_ops->ack_status(ack);
+}
+
+static void pmc_intel_enable(int idx, u64 config)
+{
+	wrmsrl(MSR_ARCH_PERFMON_EVENTSEL0 + idx,
+			config | ARCH_PERFMON_EVENTSEL0_ENABLE);
+}
+
+static void pmc_amd_enable(int idx, u64 config)
+{
+	struct cpu_hw_counters *cpuc = &__get_cpu_var(cpu_hw_counters);
+
+	set_bit(idx, (unsigned long *)&cpuc->active_mask);
+	if (cpuc->enabled)
+		config |= ARCH_PERFMON_EVENTSEL0_ENABLE;
+
+	wrmsrl(MSR_K7_EVNTSEL0 + idx, config);
+}
+
+static void hw_perf_enable(int idx, u64 config)
+{
+	if (unlikely(!perf_counters_initialized))
+		return;
+
+	pmc_ops->enable(idx, config);
+}
+
+static void pmc_intel_disable(int idx, u64 config)
+{
+	wrmsrl(MSR_ARCH_PERFMON_EVENTSEL0 + idx, config);
+}
+
+static void pmc_amd_disable(int idx, u64 config)
+{
+	struct cpu_hw_counters *cpuc = &__get_cpu_var(cpu_hw_counters);
+
+	clear_bit(idx, (unsigned long *)&cpuc->active_mask);
+	wrmsrl(MSR_K7_EVNTSEL0 + idx, config);
+
+}
+
+static void hw_perf_disable(int idx, u64 config)
+{
+	if (unlikely(!perf_counters_initialized))
+		return;
+
+	pmc_ops->disable(idx, config);
+}
+
 static inline void
 __pmc_fixed_disable(struct perf_counter *counter,
 		    struct hw_perf_counter *hwc, unsigned int __idx)
@@ -278,7 +436,7 @@ __pmc_generic_disable(struct perf_counter *counter,
 	if (unlikely(hwc->config_base == MSR_ARCH_PERFMON_FIXED_CTR_CTRL))
 		__pmc_fixed_disable(counter, hwc, idx);
 	else
-		wrmsr_safe(hwc->config_base + idx, hwc->config, 0);
+		hw_perf_disable(idx, hwc->config);
 }
 
 static DEFINE_PER_CPU(u64, prev_left[X86_PMC_IDX_MAX]);
@@ -354,8 +512,7 @@ __pmc_generic_enable(struct perf_counter *counter,
 	if (unlikely(hwc->config_base == MSR_ARCH_PERFMON_FIXED_CTR_CTRL))
 		__pmc_fixed_enable(counter, hwc, idx);
 	else
-		wrmsr(hwc->config_base + idx,
-		      hwc->config | ARCH_PERFMON_EVENTSEL0_ENABLE, 0);
+		hw_perf_enable(idx, hwc->config);
 }
 
 static int
@@ -567,22 +724,20 @@ perf_handle_group(struct perf_counter *sibling, u64 *status, u64 *overflown)
  * This handler is triggered by the local APIC, so the APIC IRQ handling
  * rules apply:
  */
-static void __smp_perf_counter_interrupt(struct pt_regs *regs, int nmi)
+static int __smp_perf_counter_interrupt(struct pt_regs *regs, int nmi)
 {
 	int bit, cpu = smp_processor_id();
 	u64 ack, status;
 	struct cpu_hw_counters *cpuc = &per_cpu(cpu_hw_counters, cpu);
+	int ret = 0;
 
-	rdmsrl(MSR_CORE_PERF_GLOBAL_CTRL, cpuc->global_enable);
-
-	/* Disable counters globally */
-	wrmsrl(MSR_CORE_PERF_GLOBAL_CTRL, 0);
-	ack_APIC_irq();
+	cpuc->throttle_ctrl = hw_perf_save_disable();
 
-	rdmsrl(MSR_CORE_PERF_GLOBAL_STATUS, status);
+	status = hw_perf_get_status(cpuc->throttle_ctrl);
 	if (!status)
 		goto out;
 
+	ret = 1;
 again:
 	inc_irq_stat(apic_perf_irqs);
 	ack = status;
@@ -618,12 +773,12 @@ again:
 		}
 	}
 
-	wrmsrl(MSR_CORE_PERF_GLOBAL_OVF_CTRL, ack);
+	hw_perf_ack_status(ack);
 
 	/*
 	 * Repeat if there is more work to be done:
 	 */
-	rdmsrl(MSR_CORE_PERF_GLOBAL_STATUS, status);
+	status = hw_perf_get_status(cpuc->throttle_ctrl);
 	if (status)
 		goto again;
 out:
@@ -631,32 +786,27 @@ out:
 	 * Restore - do not reenable when global enable is off or throttled:
 	 */
 	if (++cpuc->interrupts < PERFMON_MAX_INTERRUPTS)
-		wrmsrl(MSR_CORE_PERF_GLOBAL_CTRL, cpuc->global_enable);
+		hw_perf_restore(cpuc->throttle_ctrl);
+
+	return ret;
 }
 
 void perf_counter_unthrottle(void)
 {
 	struct cpu_hw_counters *cpuc;
-	u64 global_enable;
 
 	if (!cpu_has(&boot_cpu_data, X86_FEATURE_ARCH_PERFMON))
 		return;
 
-	if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD)
-		return;
-
 	if (unlikely(!perf_counters_initialized))
 		return;
 
-	cpuc = &per_cpu(cpu_hw_counters, smp_processor_id());
+	cpuc = &__get_cpu_var(cpu_hw_counters);
 	if (cpuc->interrupts >= PERFMON_MAX_INTERRUPTS) {
 		if (printk_ratelimit())
 			printk(KERN_WARNING "PERFMON: max interrupts exceeded!\n");
-		wrmsrl(MSR_CORE_PERF_GLOBAL_CTRL, cpuc->global_enable);
+		hw_perf_restore(cpuc->throttle_ctrl);
 	}
-	rdmsrl(MSR_CORE_PERF_GLOBAL_CTRL, global_enable);
-	if (unlikely(cpuc->global_enable && !global_enable))
-		wrmsrl(MSR_CORE_PERF_GLOBAL_CTRL, cpuc->global_enable);
 	cpuc->interrupts = 0;
 }
 
@@ -664,8 +814,8 @@ void smp_perf_counter_interrupt(struct pt_regs *regs)
 {
 	irq_enter();
 	apic_write(APIC_LVTPC, LOCAL_PERF_VECTOR);
+	ack_APIC_irq();
 	__smp_perf_counter_interrupt(regs, 0);
-
 	irq_exit();
 }
 
@@ -722,16 +872,23 @@ perf_counter_nmi_handler(struct notifier_block *self,
 {
 	struct die_args *args = __args;
 	struct pt_regs *regs;
+	int ret;
+
+	switch (cmd) {
+	case DIE_NMI:
+	case DIE_NMI_IPI:
+		break;
 
-	if (likely(cmd != DIE_NMI_IPI))
+	default:
 		return NOTIFY_DONE;
+	}
 
 	regs = args->regs;
 
 	apic_write(APIC_LVTPC, APIC_DM_NMI);
-	__smp_perf_counter_interrupt(regs, 1);
+	ret = __smp_perf_counter_interrupt(regs, 1);
 
-	return NOTIFY_STOP;
+	return ret ? NOTIFY_STOP : NOTIFY_OK;
 }
 
 static __read_mostly struct notifier_block perf_counter_nmi_notifier = {
@@ -743,18 +900,28 @@ static __read_mostly struct notifier_block perf_counter_nmi_notifier = {
 static struct pmc_x86_ops pmc_intel_ops = {
 	.save_disable_all	= pmc_intel_save_disable_all,
 	.restore_all		= pmc_intel_restore_all,
+	.get_status		= pmc_intel_get_status,
+	.ack_status		= pmc_intel_ack_status,
+	.enable			= pmc_intel_enable,
+	.disable		= pmc_intel_disable,
 	.eventsel		= MSR_ARCH_PERFMON_EVENTSEL0,
 	.perfctr		= MSR_ARCH_PERFMON_PERFCTR0,
 	.event_map		= pmc_intel_event_map,
+	.raw_event		= pmc_intel_raw_event,
 	.max_events		= ARRAY_SIZE(intel_perfmon_event_map),
 };
 
 static struct pmc_x86_ops pmc_amd_ops = {
 	.save_disable_all	= pmc_amd_save_disable_all,
 	.restore_all		= pmc_amd_restore_all,
+	.get_status		= pmc_amd_get_status,
+	.ack_status		= pmc_amd_ack_status,
+	.enable			= pmc_amd_enable,
+	.disable		= pmc_amd_disable,
 	.eventsel		= MSR_K7_EVNTSEL0,
 	.perfctr		= MSR_K7_PERFCTR0,
 	.event_map		= pmc_amd_event_map,
+	.raw_event		= pmc_amd_raw_event,
 	.max_events		= ARRAY_SIZE(amd_perfmon_event_map),
 };
 
@@ -787,8 +954,25 @@ static struct pmc_x86_ops *pmc_intel_init(void)
 
 static struct pmc_x86_ops *pmc_amd_init(void)
 {
+	u64 old;
+	int bits;
+
 	nr_counters_generic = 4;
 	nr_counters_fixed = 0;
+	counter_value_mask = ~0ULL;
+
+	rdmsrl(MSR_K7_PERFCTR0, old);
+	wrmsrl(MSR_K7_PERFCTR0, counter_value_mask);
+	/*
+	 * read the truncated mask
+	 */
+	rdmsrl(MSR_K7_PERFCTR0, counter_value_mask);
+	wrmsrl(MSR_K7_PERFCTR0, old);
+
+	bits = 32 + fls(counter_value_mask >> 32);
+	if (bits == 32)
+		bits = fls((u32)counter_value_mask);
+	counter_value_bits = bits;
 
 	pr_info("AMD Performance Monitoring support detected.\n");
 

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

* Re: [PATCH] perfcounters: IRQ and NMI support on AMD CPUs
  2009-03-05 17:20 [PATCH] perfcounters: IRQ and NMI support on AMD CPUs Peter Zijlstra
  2009-03-05 17:25 ` Ingo Molnar
  2009-03-05 17:27 ` [tip:perfcounters/core] " Peter Zijlstra
@ 2009-03-05 18:32 ` Jaswinder Singh Rajput
  2009-03-05 18:45   ` Peter Zijlstra
  2 siblings, 1 reply; 16+ messages in thread
From: Jaswinder Singh Rajput @ 2009-03-05 18:32 UTC (permalink / raw)
  To: Peter Zijlstra; +Cc: Ingo Molnar, Paul Mackerras, lkml

Hello Peter,

Ahh, so that day you was getting triple fault in this ?

On Thu, 2009-03-05 at 18:20 +0100, Peter Zijlstra wrote:
> Subject: perfcounters: IRQ and NMI support on AMD CPUs
> From: Peter Zijlstra <a.p.zijlstra@chello.nl>
> Date: Thu Mar 05 18:08:27 CET 2009
> 
> The below completes the K7+ performance counter support.
> 
> Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
> ---
>  arch/x86/kernel/cpu/perf_counter.c |  272 +++++++++++++++++++++++++++++++------
>  1 file changed, 228 insertions(+), 44 deletions(-)
> 

It was in my TODO list, but I am glad that you finished it :-)

Any how with this patch on my 64 bit AMD box I am getting:

[jaswinder@hpdv5 perfcounters]$ ./perfstat -e 0,1,2,3 ls > /dev/null 

 Performance counter stats for 'ls':

perfstat: perfstat.c:415: main: Assertion `res == sizeof(single_count)'
failed.
Aborted
[jaswinder@hpdv5 perfcounters]$ 

[root@hpdv5 perfcounters]# ./kerneltop 
KernelTop refresh period: 2 seconds
kerneltop: kerneltop.c:883: main: Assertion `res == sizeof(ip)' failed.
Aborted
[root@hpdv5 perfcounters]#

Thanks,
--
JSR



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

* Re: [PATCH] perfcounters: IRQ and NMI support on AMD CPUs
  2009-03-05 18:32 ` [PATCH] " Jaswinder Singh Rajput
@ 2009-03-05 18:45   ` Peter Zijlstra
  2009-03-05 18:56     ` Jaswinder Singh Rajput
  0 siblings, 1 reply; 16+ messages in thread
From: Peter Zijlstra @ 2009-03-05 18:45 UTC (permalink / raw)
  To: Jaswinder Singh Rajput; +Cc: Ingo Molnar, Paul Mackerras, lkml

On Fri, 2009-03-06 at 00:02 +0530, Jaswinder Singh Rajput wrote:
> Hello Peter,
> 
> Ahh, so that day you was getting triple fault in this ?
> 
> On Thu, 2009-03-05 at 18:20 +0100, Peter Zijlstra wrote:
> > Subject: perfcounters: IRQ and NMI support on AMD CPUs
> > From: Peter Zijlstra <a.p.zijlstra@chello.nl>
> > Date: Thu Mar 05 18:08:27 CET 2009
> > 
> > The below completes the K7+ performance counter support.
> > 
> > Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
> > ---
> >  arch/x86/kernel/cpu/perf_counter.c |  272 +++++++++++++++++++++++++++++++------
> >  1 file changed, 228 insertions(+), 44 deletions(-)
> > 
> 
> It was in my TODO list, but I am glad that you finished it :-)
> 
> Any how with this patch on my 64 bit AMD box I am getting:
> 
> [jaswinder@hpdv5 perfcounters]$ ./perfstat -e 0,1,2,3 ls > /dev/null 
> 
>  Performance counter stats for 'ls':
> 
> perfstat: perfstat.c:415: main: Assertion `res == sizeof(single_count)'
> failed.
> Aborted
> [jaswinder@hpdv5 perfcounters]$ 
> 
> [root@hpdv5 perfcounters]# ./kerneltop 
> KernelTop refresh period: 2 seconds
> kerneltop: kerneltop.c:883: main: Assertion `res == sizeof(ip)' failed.
> Aborted
> [root@hpdv5 perfcounters]#

Ah, I think you will need a fresh copy of both utilities, Paul recently
changed the ABI.

http://people.redhat.com/mingo/perfcounters/

Contains the latest IIRC


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

* Re: [PATCH] perfcounters: IRQ and NMI support on AMD CPUs
  2009-03-05 18:45   ` Peter Zijlstra
@ 2009-03-05 18:56     ` Jaswinder Singh Rajput
  2009-03-05 19:07       ` Peter Zijlstra
  2009-03-05 19:34       ` Peter Zijlstra
  0 siblings, 2 replies; 16+ messages in thread
From: Jaswinder Singh Rajput @ 2009-03-05 18:56 UTC (permalink / raw)
  To: Peter Zijlstra; +Cc: Ingo Molnar, Paul Mackerras, lkml

On Thu, 2009-03-05 at 19:45 +0100, Peter Zijlstra wrote:
> On Fri, 2009-03-06 at 00:02 +0530, Jaswinder Singh Rajput wrote:
> > 
> > Any how with this patch on my 64 bit AMD box I am getting:
> > 
> > [jaswinder@hpdv5 perfcounters]$ ./perfstat -e 0,1,2,3 ls > /dev/null 
> > 
> >  Performance counter stats for 'ls':
> > 
> > perfstat: perfstat.c:415: main: Assertion `res == sizeof(single_count)'
> > failed.
> > Aborted
> > [jaswinder@hpdv5 perfcounters]$ 
> > 
> > [root@hpdv5 perfcounters]# ./kerneltop 
> > KernelTop refresh period: 2 seconds
> > kerneltop: kerneltop.c:883: main: Assertion `res == sizeof(ip)' failed.
> > Aborted
> > [root@hpdv5 perfcounters]#
> 
> Ah, I think you will need a fresh copy of both utilities, Paul recently
> changed the ABI.
> 
> http://people.redhat.com/mingo/perfcounters/
> 
> Contains the latest IIRC
> 

With fresh copy, perfstat is working.

But kerneltop is still not working and I am not getting any NMI Interrupts.

[root@hpdv5 new]# ./kerneltop -e 3 -c 100 -e 2

------------------------------------------------------------------------------
 KernelTop:       0 irqs/sec  kernel:nan% [NMI, cache-misses/cache-refs],  (all, 2 CPUs)
------------------------------------------------------------------------------

  weight     events         RIP          kernel function
  ______     ______   ________________   _______________


--
JSR


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

* Re: [PATCH] perfcounters: IRQ and NMI support on AMD CPUs
  2009-03-05 18:56     ` Jaswinder Singh Rajput
@ 2009-03-05 19:07       ` Peter Zijlstra
  2009-03-05 19:37         ` Jaswinder Singh Rajput
  2009-03-05 19:34       ` Peter Zijlstra
  1 sibling, 1 reply; 16+ messages in thread
From: Peter Zijlstra @ 2009-03-05 19:07 UTC (permalink / raw)
  To: Jaswinder Singh Rajput; +Cc: Ingo Molnar, Paul Mackerras, lkml

On Fri, 2009-03-06 at 00:26 +0530, Jaswinder Singh Rajput wrote:
> On Thu, 2009-03-05 at 19:45 +0100, Peter Zijlstra wrote:
> > On Fri, 2009-03-06 at 00:02 +0530, Jaswinder Singh Rajput wrote:
> > > 
> > > Any how with this patch on my 64 bit AMD box I am getting:
> > > 
> > > [jaswinder@hpdv5 perfcounters]$ ./perfstat -e 0,1,2,3 ls > /dev/null 
> > > 
> > >  Performance counter stats for 'ls':
> > > 
> > > perfstat: perfstat.c:415: main: Assertion `res == sizeof(single_count)'
> > > failed.
> > > Aborted
> > > [jaswinder@hpdv5 perfcounters]$ 
> > > 
> > > [root@hpdv5 perfcounters]# ./kerneltop 
> > > KernelTop refresh period: 2 seconds
> > > kerneltop: kerneltop.c:883: main: Assertion `res == sizeof(ip)' failed.
> > > Aborted
> > > [root@hpdv5 perfcounters]#
> > 
> > Ah, I think you will need a fresh copy of both utilities, Paul recently
> > changed the ABI.
> > 
> > http://people.redhat.com/mingo/perfcounters/
> > 
> > Contains the latest IIRC
> > 
> 
> With fresh copy, perfstat is working.
> 
> But kerneltop is still not working and I am not getting any NMI Interrupts.

What does your dmegs look like?

Mine read like:

[    0.012002] AMD Performance Monitoring support detected.
[    0.013002] ... num counters:    4
[    0.014001] ... value mask:      0000ffffffffffff
[    0.015001] ... fixed counters:  0
[    0.016001] ... counter mask:    000000000000000f

and its generating IRQs:

CNT:     168612     166040   Performance counter interrupts



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

* Re: [PATCH] perfcounters: IRQ and NMI support on AMD CPUs
  2009-03-05 18:56     ` Jaswinder Singh Rajput
  2009-03-05 19:07       ` Peter Zijlstra
@ 2009-03-05 19:34       ` Peter Zijlstra
  2009-03-05 19:41         ` Ingo Molnar
  1 sibling, 1 reply; 16+ messages in thread
From: Peter Zijlstra @ 2009-03-05 19:34 UTC (permalink / raw)
  To: Jaswinder Singh Rajput; +Cc: Ingo Molnar, Paul Mackerras, lkml

On Fri, 2009-03-06 at 00:26 +0530, Jaswinder Singh Rajput wrote:

> But kerneltop is still not working and I am not getting any NMI Interrupts.

Does the below work for you?

The BKGD suggests its 48 for all existing machines (it certainly is for
mine).

Index: linux-2.6/arch/x86/kernel/cpu/perf_counter.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/cpu/perf_counter.c
+++ linux-2.6/arch/x86/kernel/cpu/perf_counter.c
@@ -959,20 +959,8 @@ static struct pmc_x86_ops *pmc_amd_init(
 
 	nr_counters_generic = 4;
 	nr_counters_fixed = 0;
-	counter_value_mask = ~0ULL;
-
-	rdmsrl(MSR_K7_PERFCTR0, old);
-	wrmsrl(MSR_K7_PERFCTR0, counter_value_mask);
-	/*
-	 * read the truncated mask
-	 */
-	rdmsrl(MSR_K7_PERFCTR0, counter_value_mask);
-	wrmsrl(MSR_K7_PERFCTR0, old);
-
-	bits = 32 + fls(counter_value_mask >> 32);
-	if (bits == 32)
-		bits = fls((u32)counter_value_mask);
-	counter_value_bits = bits;
+	counter_value_mask = 0x0000FFFFFFFFFFFFULL;
+	counter_value_bits = 48;
 
 	pr_info("AMD Performance Monitoring support detected.\n");
 



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

* Re: [PATCH] perfcounters: IRQ and NMI support on AMD CPUs
  2009-03-05 19:07       ` Peter Zijlstra
@ 2009-03-05 19:37         ` Jaswinder Singh Rajput
  0 siblings, 0 replies; 16+ messages in thread
From: Jaswinder Singh Rajput @ 2009-03-05 19:37 UTC (permalink / raw)
  To: Peter Zijlstra; +Cc: Ingo Molnar, Paul Mackerras, lkml

On Thu, 2009-03-05 at 20:07 +0100, Peter Zijlstra wrote:
> On Fri, 2009-03-06 at 00:26 +0530, Jaswinder Singh Rajput wrote:
> > 
> > With fresh copy, perfstat is working.
> > 
> > But kerneltop is still not working and I am not getting any NMI Interrupts.
> 
> What does your dmegs look like?
> 
> Mine read like:
> 
> [    0.012002] AMD Performance Monitoring support detected.
> [    0.013002] ... num counters:    4
> [    0.014001] ... value mask:      0000ffffffffffff
> [    0.015001] ... fixed counters:  0
> [    0.016001] ... counter mask:    000000000000000f
> 

[    0.010998] AMD Performance Monitoring support detected.
[    0.011006] ... num counters:    4
[    0.011301] ... value mask:      0000000000000086
[    0.011581] ... fixed counters:  0
[    0.011808] ... counter mask:    000000000000000f
[    0.011998] ACPI: Core revision 20081204

> and its generating IRQs:
> 
> CNT:     168612     166040   Performance counter interrupts
> 

NMI:          0          0   Non-maskable interrupts
LOC:        213     980394   Local timer interrupts
CNT:          0          0   Performance counter interrupts
RES:     125349     123542   Rescheduling interrupts

--
JSR


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

* Re: [PATCH] perfcounters: IRQ and NMI support on AMD CPUs
  2009-03-05 19:34       ` Peter Zijlstra
@ 2009-03-05 19:41         ` Ingo Molnar
  2009-03-05 20:01           ` Jaswinder Singh Rajput
  0 siblings, 1 reply; 16+ messages in thread
From: Ingo Molnar @ 2009-03-05 19:41 UTC (permalink / raw)
  To: Peter Zijlstra; +Cc: Jaswinder Singh Rajput, Paul Mackerras, lkml


* Peter Zijlstra <peterz@infradead.org> wrote:

> On Fri, 2009-03-06 at 00:26 +0530, Jaswinder Singh Rajput wrote:
> 
> > But kerneltop is still not working and I am not getting any NMI Interrupts.
> 
> Does the below work for you?
> 
> The BKGD suggests its 48 for all existing machines (it 
> certainly is for mine).

Yeah, this did the trick on AMD/Barcelona!

NMI:      11310      14932      11729      12705      11207      
13454      13378      10714      14526      11986      10973      
10765      12669      12093      13430       9661   Non-maskable 
interrupts

KernelTop works just fine:

------------------------------------------------------------------------------
 KernelTop:    1019 irqs/sec  kernel:27.9% [NMI, 1000000 CPU 
cycles],  (all, 16 CPUs)
------------------------------------------------------------------------------

             events         RIP          kernel function
  ______     ______   ________________   _______________

            5260.00 - ffffffff8037e420 : clear_page_c
            1065.00 - ffffffff805811a0 : page_fault
             699.00 - ffffffff8037e690 : copy_user_generic_string!
             669.00 - ffffffff80294ed8 : get_page_from_freelist
             575.00 - ffffffff804cd033 : acpi_pm_read
             551.00 - ffffffff8025fd1b : generic_exec_single
             416.00 - ffffffff80580c9c : _spin_lock
             413.00 - ffffffff802a32ad : unmap_vmas
             392.00 - ffffffff80580fc2 : _spin_lock_irqsave

Thanks!

	Ingo

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

* Re: [PATCH] perfcounters: IRQ and NMI support on AMD CPUs
  2009-03-05 19:41         ` Ingo Molnar
@ 2009-03-05 20:01           ` Jaswinder Singh Rajput
  2009-03-06  6:37             ` Mike Galbraith
  0 siblings, 1 reply; 16+ messages in thread
From: Jaswinder Singh Rajput @ 2009-03-05 20:01 UTC (permalink / raw)
  To: Ingo Molnar; +Cc: Peter Zijlstra, Paul Mackerras, lkml

On Thu, 2009-03-05 at 20:41 +0100, Ingo Molnar wrote:
> * Peter Zijlstra <peterz@infradead.org> wrote:
> 
> > On Fri, 2009-03-06 at 00:26 +0530, Jaswinder Singh Rajput wrote:
> > 
> > > But kerneltop is still not working and I am not getting any NMI Interrupts.
> > 
> > Does the below work for you?
> > 
> > The BKGD suggests its 48 for all existing machines (it 
> > certainly is for mine).
> 
> Yeah, this did the trick on AMD/Barcelona!
> 

Nice.

but on my AMD box I got interrupts and NMI for some time:

NMI:        100    1108209   Non-maskable interrupts
LOC:        213     192815   Local timer interrupts
CNT:        100    1108206   Performance counter interrupts
RES:      21132      20397   Rescheduling interrupts

but kerneltop does not show anything, it only shows # irqs/sec for some
time and then irqs also become 0.

Here is demg:

kerneltop 
[  196.677297] Uhhuh. NMI received for unknown reason 00 on CPU 1.
[  196.677297] Do you have a strange power saving mode enabled?
[  196.677297] Dazed and confused, but trying to continue
[  198.854293] PERFMON: max interrupts exceeded!
[  198.865302] PERFMON: max interrupts exceeded!
[  198.866304] PERFMON: max interrupts exceeded!
[  206.066271] PERFMON: max interrupts exceeded!
[  206.067304] PERFMON: max interrupts exceeded!
[  206.068265] PERFMON: max interrupts exceeded!
[  211.176291] PERFMON: max interrupts exceeded!
[  211.177302] PERFMON: max interrupts exceeded!
[  211.235304] PERFMON: max interrupts exceeded!
[  211.236296] PERFMON: max interrupts exceeded!
[  214.245302] PERFMON: max interrupts exceeded!
[  225.257276] PERFMON: max interrupts exceeded!
[  225.258271] PERFMON: max interrupts exceeded!
[  297.385301] PERFMON: max interrupts exceeded!
[  297.386290] PERFMON: max interrupts exceeded!
[  310.405304] PERFMON: max interrupts exceeded!
[  392.677261] Uhhuh. NMI received for unknown reason 00 on CPU 1.
[  392.677261] Do you have a strange power saving mode enabled?
[  392.677261] Dazed and confused, but trying to continue
[  394.837275] PERFMON: max interrupts exceeded!
[  394.848268] PERFMON: max interrupts exceeded!
[  394.849266] PERFMON: max interrupts exceeded!
[  396.891309] PERFMON: max interrupts exceeded!
[  396.892294] PERFMON: max interrupts exceeded!
[  397.415302] PERFMON: max interrupts exceeded!
[  397.594299] PERFMON: max interrupts exceeded!
[  398.395302] PERFMON: max interrupts exceeded!
[  398.919304] PERFMON: max interrupts exceeded!
[  403.839309] __ratelimit: 1 callbacks suppressed
[  403.839319] PERFMON: max interrupts exceeded!
[  403.840302] PERFMON: max interrupts exceeded!
[  403.841298] PERFMON: max interrupts exceeded!
[  403.842297] PERFMON: max interrupts exceeded!
[  403.843267] PERFMON: max interrupts exceeded!
[  403.853303] PERFMON: max interrupts exceeded!
[  403.854290] PERFMON: max interrupts exceeded!
[  403.855301] PERFMON: max interrupts exceeded!
[  403.857301] PERFMON: max interrupts exceeded!
[  403.858304] PERFMON: max interrupts exceeded!
[  409.097310] __ratelimit: 13 callbacks suppressed
[  409.097321] PERFMON: max interrupts exceeded!
[  409.098299] PERFMON: max interrupts exceeded!
[  411.138303] PERFMON: max interrupts exceeded!
[  413.177301] PERFMON: max interrupts exceeded!
[  413.178289] PERFMON: max interrupts exceeded!
[  414.442311] PERFMON: max interrupts exceeded!
[  415.217304] PERFMON: max interrupts exceeded!
[  415.218291] PERFMON: max interrupts exceeded!
[  417.257307] PERFMON: max interrupts exceeded!
[  417.258294] PERFMON: max interrupts exceeded!
[  418.585295] PERFMON: max interrupts exceeded!
[  418.600293] PERFMON: max interrupts exceeded!
[  427.436301] PERFMON: max interrupts exceeded!
[  427.437307] PERFMON: max interrupts exceeded!
[  429.477269] PERFMON: max interrupts exceeded!
[  429.479264] PERFMON: max interrupts exceeded!
[  431.514269] PERFMON: max interrupts exceeded!
[  431.516294] PERFMON: max interrupts exceeded!
[  433.557303] PERFMON: max interrupts exceeded!
[  433.558290] PERFMON: max interrupts exceeded!
[  435.585305] PERFMON: max interrupts exceeded!
[  435.586291] PERFMON: max interrupts exceeded!
[  435.620276] PERFMON: max interrupts exceeded!
[  437.619294] PERFMON: max interrupts exceeded!
[  437.620295] PERFMON: max interrupts exceeded!
[  437.621289] PERFMON: max interrupts exceeded!
[  437.622290] PERFMON: max interrupts exceeded!
[  439.637302] PERFMON: max interrupts exceeded!
[  439.638291] PERFMON: max interrupts exceeded!
[  439.645301] PERFMON: max interrupts exceeded!
[  439.646298] PERFMON: max interrupts exceeded!
[  441.684302] PERFMON: max interrupts exceeded!
[  441.685298] PERFMON: max interrupts exceeded!
[  456.974308] PERFMON: max interrupts exceeded!
[  466.542303] PERFMON: max interrupts exceeded!
[  468.924294] PERFMON: max interrupts exceeded!
[  471.246282] PERFMON: max interrupts exceeded!
[  471.257269] PERFMON: max interrupts exceeded!
[  471.258268] PERFMON: max interrupts exceeded!
[  473.295297] PERFMON: max interrupts exceeded!
[  473.296301] PERFMON: max interrupts exceeded!
[  475.312292] PERFMON: max interrupts exceeded!
[  475.323302] PERFMON: max interrupts exceeded!
[  475.324302] PERFMON: max interrupts exceeded!
[  477.346303] PERFMON: max interrupts exceeded!
[  477.347300] PERFMON: max interrupts exceeded!
[  479.381303] PERFMON: max interrupts exceeded!
[  480.685269] PERFMON: max interrupts exceeded!
[  480.686270] PERFMON: max interrupts exceeded!
[  481.405307] PERFMON: max interrupts exceeded!
[  483.425304] PERFMON: max interrupts exceeded!
[  483.426291] PERFMON: max interrupts exceeded!
[  485.461306] PERFMON: max interrupts exceeded!
[  485.462293] PERFMON: max interrupts exceeded!
[  487.499304] PERFMON: max interrupts exceeded!
[  487.500290] PERFMON: max interrupts exceeded!
[  489.524279] PERFMON: max interrupts exceeded!
[  491.546304] PERFMON: max interrupts exceeded!
[  491.547292] PERFMON: max interrupts exceeded!
[  491.548285] PERFMON: max interrupts exceeded!
[  493.581307] PERFMON: max interrupts exceeded!
[  493.582301] PERFMON: max interrupts exceeded!
[  495.605303] PERFMON: max interrupts exceeded!
[  495.606311] PERFMON: max interrupts exceeded!
[  497.641303] PERFMON: max interrupts exceeded!
[  499.665303] PERFMON: max interrupts exceeded!
[  499.666325] PERFMON: max interrupts exceeded!
[  501.699295] PERFMON: max interrupts exceeded!
[  501.700301] PERFMON: max interrupts exceeded!
[  503.715304] PERFMON: max interrupts exceeded!
[  503.716292] PERFMON: max interrupts exceeded!
[  503.717309] PERFMON: max interrupts exceeded!
[  503.725302] PERFMON: max interrupts exceeded!
[  505.748271] PERFMON: max interrupts exceeded!
[  505.749382] PERFMON: max interrupts exceeded!
[  507.782304] PERFMON: max interrupts exceeded!
[  507.783291] PERFMON: max interrupts exceeded!
[  509.804303] PERFMON: max interrupts exceeded!
[  509.805302] PERFMON: max interrupts exceeded!
[  511.840303] PERFMON: max interrupts exceeded!
[  511.841299] PERFMON: max interrupts exceeded!
[  515.565261] Uhhuh. NMI received for unknown reason 00 on CPU 1.
[  515.565261] Do you have a strange power saving mode enabled?
[  515.565261] Dazed and confused, but trying to continue
[  515.569284] PERFMON: max interrupts exceeded!
[  515.570372] PERFMON: max interrupts exceeded!
[  515.571355] PERFMON: max interrupts exceeded!
[  515.574304] PERFMON: max interrupts exceeded!
[  515.575287] PERFMON: max interrupts exceeded!
[  515.576283] PERFMON: max interrupts exceeded!
[  515.577289] PERFMON: max interrupts exceeded!
[  515.579318] PERFMON: max interrupts exceeded!
[  516.948088] __ratelimit: 113 callbacks suppressed
[  516.948118] PERFMON: max interrupts exceeded!
[  516.951315] PERFMON: max interrupts exceeded!
[  516.952298] PERFMON: max interrupts exceeded!
[  516.953315] PERFMON: max interrupts exceeded!
[  516.954406] PERFMON: max interrupts exceeded!
[  516.955390] PERFMON: max interrupts exceeded!
[  516.956336] PERFMON: max interrupts exceeded!
[  516.957277] PERFMON: max interrupts exceeded!
[  516.958285] PERFMON: max interrupts exceeded!
[  516.959313] PERFMON: max interrupts exceeded!
[  522.039265] __ratelimit: 248 callbacks suppressed
[  522.039294] PERFMON: max interrupts exceeded!
[  522.040321] PERFMON: max interrupts exceeded!
[  522.042299] PERFMON: max interrupts exceeded!
[  522.043287] PERFMON: max interrupts exceeded!
[  522.044277] PERFMON: max interrupts exceeded!
[  522.045299] PERFMON: max interrupts exceeded!
[  522.048017] PERFMON: max interrupts exceeded!
[  522.148095] PERFMON: max interrupts exceeded!
[  522.149279] PERFMON: max interrupts exceeded!
[  522.151350] PERFMON: max interrupts exceeded!
[  527.043304] __ratelimit: 1024 callbacks suppressed
[  527.043314] PERFMON: max interrupts exceeded!
[  527.044303] PERFMON: max interrupts exceeded!
[  527.045298] PERFMON: max interrupts exceeded!
[  527.046291] PERFMON: max interrupts exceeded!
[  527.047271] PERFMON: max interrupts exceeded!
[  527.048276] PERFMON: max interrupts exceeded!
[  527.049303] PERFMON: max interrupts exceeded!
[  527.052303] PERFMON: max interrupts exceeded!
[  527.053566] PERFMON: max interrupts exceeded!
[  527.054304] PERFMON: max interrupts exceeded!
[  532.049312] __ratelimit: 2191 callbacks suppressed
[  532.049321] PERFMON: max interrupts exceeded!
[  532.050303] PERFMON: max interrupts exceeded!
[  532.052298] PERFMON: max interrupts exceeded!
[  532.053305] PERFMON: max interrupts exceeded!
[  532.065291] PERFMON: max interrupts exceeded!
[  532.067263] PERFMON: max interrupts exceeded!
[  532.069299] PERFMON: max interrupts exceeded!
[  532.071300] PERFMON: max interrupts exceeded!
[  532.073311] PERFMON: max interrupts exceeded!
[  532.075302] PERFMON: max interrupts exceeded!
[  537.062306] __ratelimit: 1414 callbacks suppressed
[  537.062335] PERFMON: max interrupts exceeded!
[  537.063443] PERFMON: max interrupts exceeded!
[  537.066285] PERFMON: max interrupts exceeded!
[  537.067289] PERFMON: max interrupts exceeded!
[  537.068282] PERFMON: max interrupts exceeded!
[  537.069322] PERFMON: max interrupts exceeded!
[  537.071312] PERFMON: max interrupts exceeded!
[  537.072295] PERFMON: max interrupts exceeded!
[  537.073279] PERFMON: max interrupts exceeded!
[  537.074287] PERFMON: max interrupts exceeded!
[root@hpdv5 new]# 

--
JSR


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

* Re: [PATCH] perfcounters: IRQ and NMI support on AMD CPUs
  2009-03-05 20:01           ` Jaswinder Singh Rajput
@ 2009-03-06  6:37             ` Mike Galbraith
  2009-03-06  6:51               ` Mike Galbraith
  0 siblings, 1 reply; 16+ messages in thread
From: Mike Galbraith @ 2009-03-06  6:37 UTC (permalink / raw)
  To: Jaswinder Singh Rajput; +Cc: Ingo Molnar, Peter Zijlstra, Paul Mackerras, lkml

On Fri, 2009-03-06 at 01:31 +0530, Jaswinder Singh Rajput wrote:
> On Thu, 2009-03-05 at 20:41 +0100, Ingo Molnar wrote:
> > * Peter Zijlstra <peterz@infradead.org> wrote:
> > 
> > > On Fri, 2009-03-06 at 00:26 +0530, Jaswinder Singh Rajput wrote:
> > > 
> > > > But kerneltop is still not working and I am not getting any NMI Interrupts.
> > > 
> > > Does the below work for you?
> > > 
> > > The BKGD suggests its 48 for all existing machines (it 
> > > certainly is for mine).
> > 
> > Yeah, this did the trick on AMD/Barcelona!
> > 
> 
> Nice.
> 
> but on my AMD box I got interrupts and NMI for some time:
> 
> NMI:        100    1108209   Non-maskable interrupts
> LOC:        213     192815   Local timer interrupts
> CNT:        100    1108206   Performance counter interrupts
> RES:      21132      20397   Rescheduling interrupts
> 
> but kerneltop does not show anything, it only shows # irqs/sec for some
> time and then irqs also become 0.

Hm.  Kerneltop on my Q6600 has ceased to function with n 1 as well, but
n 0 still works.  Zero NMIs.

Perfstat has also gone south.
perfstat: perfstat.c:423: main: Assertion `res == sizeof(single_count)' failed.

	-Mike


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

* Re: [PATCH] perfcounters: IRQ and NMI support on AMD CPUs
  2009-03-06  6:37             ` Mike Galbraith
@ 2009-03-06  6:51               ` Mike Galbraith
  2009-03-06  7:11                 ` Mike Galbraith
  0 siblings, 1 reply; 16+ messages in thread
From: Mike Galbraith @ 2009-03-06  6:51 UTC (permalink / raw)
  To: Jaswinder Singh Rajput; +Cc: Ingo Molnar, Peter Zijlstra, Paul Mackerras, lkml

On Fri, 2009-03-06 at 07:37 +0100, Mike Galbraith wrote:
> On Fri, 2009-03-06 at 01:31 +0530, Jaswinder Singh Rajput wrote:
> > On Thu, 2009-03-05 at 20:41 +0100, Ingo Molnar wrote:
> > > * Peter Zijlstra <peterz@infradead.org> wrote:
> > > 
> > > > On Fri, 2009-03-06 at 00:26 +0530, Jaswinder Singh Rajput wrote:
> > > > 
> > > > > But kerneltop is still not working and I am not getting any NMI Interrupts.
> > > > 
> > > > Does the below work for you?
> > > > 
> > > > The BKGD suggests its 48 for all existing machines (it 
> > > > certainly is for mine).
> > > 
> > > Yeah, this did the trick on AMD/Barcelona!
> > > 
> > 
> > Nice.
> > 
> > but on my AMD box I got interrupts and NMI for some time:
> > 
> > NMI:        100    1108209   Non-maskable interrupts
> > LOC:        213     192815   Local timer interrupts
> > CNT:        100    1108206   Performance counter interrupts
> > RES:      21132      20397   Rescheduling interrupts
> > 
> > but kerneltop does not show anything, it only shows # irqs/sec for some
> > time and then irqs also become 0.
> 
> Hm.  Kerneltop on my Q6600 has ceased to function with n 1 as well, but
> n 0 still works.  Zero NMIs.
> 
> Perfstat has also gone south.
> perfstat: perfstat.c:423: main: Assertion `res == sizeof(single_count)' failed.

Ah, my woes are gonna be 2743a5b0fa6f309da904f2190a9cc25deee34dbd.

Never mind.

	-Mike


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

* Re: [PATCH] perfcounters: IRQ and NMI support on AMD CPUs
  2009-03-06  6:51               ` Mike Galbraith
@ 2009-03-06  7:11                 ` Mike Galbraith
  0 siblings, 0 replies; 16+ messages in thread
From: Mike Galbraith @ 2009-03-06  7:11 UTC (permalink / raw)
  To: Jaswinder Singh Rajput; +Cc: Ingo Molnar, Peter Zijlstra, Paul Mackerras, lkml

On Fri, 2009-03-06 at 07:51 +0100, Mike Galbraith wrote:

> Ah, my woes are gonna be 2743a5b0fa6f309da904f2190a9cc25deee34dbd.

(and indeed, they both work fine now)


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

* Re: [tip:perfcounters/core] perfcounters: IRQ and NMI support on AMD CPUs
  2009-03-05 17:27 ` [tip:perfcounters/core] " Peter Zijlstra
@ 2009-03-12  1:44   ` Robert Richter
  2009-03-12  9:12     ` Peter Zijlstra
  0 siblings, 1 reply; 16+ messages in thread
From: Robert Richter @ 2009-03-12  1:44 UTC (permalink / raw)
  To: Peter Zijlstra, Ingo Molnar; +Cc: linux-kernel

On 05.03.09 17:27:29, Peter Zijlstra wrote:
> Commit-ID:  b0f3f28e0f14eb335f67bfaae33ce8b8d74fd58b
> Gitweb:     http://git.kernel.org/tip/b0f3f28e0f14eb335f67bfaae33ce8b8d74fd58b
> Author:     "Peter Zijlstra" <a.p.zijlstra@chello.nl>
> AuthorDate: Thu, 5 Mar 2009 18:08:27 +0100
> Commit:     Ingo Molnar <mingo@elte.hu>
> CommitDate: Thu, 5 Mar 2009 18:25:16 +0100
> 
> perfcounters: IRQ and NMI support on AMD CPUs
> 
> The below completes the K7+ performance counter support:
> 
>  - IRQ support
>  - NMI support
> 
> KernelTop output works now as well.
> 
> Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
> Cc: Jaswinder Singh Rajput <jaswinder@kernel.org>
> Cc: Paul Mackerras <paulus@samba.org>
> LKML-Reference: <1236273633.5187.286.camel@laptop>
> Signed-off-by: Ingo Molnar <mingo@elte.hu>
> 
> 
> ---
>  arch/x86/kernel/cpu/perf_counter.c |  272 ++++++++++++++++++++++++++++++------
>  1 files changed, 228 insertions(+), 44 deletions(-)
> 
> diff --git a/arch/x86/kernel/cpu/perf_counter.c b/arch/x86/kernel/cpu/perf_counter.c
> index 3b65f19..6ebe9ab 100644
> --- a/arch/x86/kernel/cpu/perf_counter.c
> +++ b/arch/x86/kernel/cpu/perf_counter.c

[...]

> @@ -205,18 +243,24 @@ static u64 pmc_intel_save_disable_all(void)
>  
>  static u64 pmc_amd_save_disable_all(void)
>  {
> -	int idx;
> -	u64 val, ctrl = 0;
> +	struct cpu_hw_counters *cpuc = &__get_cpu_var(cpu_hw_counters);
> +	int enabled, idx;
> +
> +	enabled = cpuc->enabled;
> +	cpuc->enabled = 0;
> +	barrier();

Peter,

please add comments to all barrier()s you added to this file. Is it
sufficient in hw_perf_save_disable() to stop NMI's only on the current
core?

-Robert

>  
>  	for (idx = 0; idx < nr_counters_generic; idx++) {
> +		u64 val;
> +
>  		rdmsrl(MSR_K7_EVNTSEL0 + idx, val);
> -		if (val & ARCH_PERFMON_EVENTSEL0_ENABLE)
> -			ctrl |= (1 << idx);
> -		val &= ~ARCH_PERFMON_EVENTSEL0_ENABLE;
> -		wrmsrl(MSR_K7_EVNTSEL0 + idx, val);
> +		if (val & ARCH_PERFMON_EVENTSEL0_ENABLE) {
> +			val &= ~ARCH_PERFMON_EVENTSEL0_ENABLE;
> +			wrmsrl(MSR_K7_EVNTSEL0 + idx, val);
> +		}
>  	}
>  
> -	return ctrl;
> +	return enabled;
>  }
>  
>  u64 hw_perf_save_disable(void)

[...]

-- 
Advanced Micro Devices, Inc.
Operating System Research Center
email: robert.richter@amd.com


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

* Re: [tip:perfcounters/core] perfcounters: IRQ and NMI support on AMD CPUs
  2009-03-12  1:44   ` Robert Richter
@ 2009-03-12  9:12     ` Peter Zijlstra
  0 siblings, 0 replies; 16+ messages in thread
From: Peter Zijlstra @ 2009-03-12  9:12 UTC (permalink / raw)
  To: Robert Richter; +Cc: Ingo Molnar, linux-kernel

On Thu, 2009-03-12 at 02:44 +0100, Robert Richter wrote:
> On 05.03.09 17:27:29, Peter Zijlstra wrote:
> > Commit-ID:  b0f3f28e0f14eb335f67bfaae33ce8b8d74fd58b
> > Gitweb:     http://git.kernel.org/tip/b0f3f28e0f14eb335f67bfaae33ce8b8d74fd58b
> > Author:     "Peter Zijlstra" <a.p.zijlstra@chello.nl>
> > AuthorDate: Thu, 5 Mar 2009 18:08:27 +0100
> > Commit:     Ingo Molnar <mingo@elte.hu>
> > CommitDate: Thu, 5 Mar 2009 18:25:16 +0100
> > 
> > perfcounters: IRQ and NMI support on AMD CPUs
> > 
> > The below completes the K7+ performance counter support:
> > 
> >  - IRQ support
> >  - NMI support
> > 
> > KernelTop output works now as well.
> > 
> > Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
> > Cc: Jaswinder Singh Rajput <jaswinder@kernel.org>
> > Cc: Paul Mackerras <paulus@samba.org>
> > LKML-Reference: <1236273633.5187.286.camel@laptop>
> > Signed-off-by: Ingo Molnar <mingo@elte.hu>
> > 
> > 
> > ---
> >  arch/x86/kernel/cpu/perf_counter.c |  272 ++++++++++++++++++++++++++++++------
> >  1 files changed, 228 insertions(+), 44 deletions(-)
> > 
> > diff --git a/arch/x86/kernel/cpu/perf_counter.c b/arch/x86/kernel/cpu/perf_counter.c
> > index 3b65f19..6ebe9ab 100644
> > --- a/arch/x86/kernel/cpu/perf_counter.c
> > +++ b/arch/x86/kernel/cpu/perf_counter.c
> 
> [...]
> 
> > @@ -205,18 +243,24 @@ static u64 pmc_intel_save_disable_all(void)
> >  
> >  static u64 pmc_amd_save_disable_all(void)
> >  {
> > -	int idx;
> > -	u64 val, ctrl = 0;
> > +	struct cpu_hw_counters *cpuc = &__get_cpu_var(cpu_hw_counters);
> > +	int enabled, idx;
> > +
> > +	enabled = cpuc->enabled;
> > +	cpuc->enabled = 0;
> > +	barrier();
> 
> Peter,
> 
> please add comments to all barrier()s you added to this file. Is it
> sufficient in hw_perf_save_disable() to stop NMI's only on the current
> core?

Yes, counters are fundamentally per cpu. But you're right, I'll go
through the code and add comments and fix up some barriers.


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

end of thread, other threads:[~2009-03-12  9:12 UTC | newest]

Thread overview: 16+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-03-05 17:20 [PATCH] perfcounters: IRQ and NMI support on AMD CPUs Peter Zijlstra
2009-03-05 17:25 ` Ingo Molnar
2009-03-05 17:27 ` [tip:perfcounters/core] " Peter Zijlstra
2009-03-12  1:44   ` Robert Richter
2009-03-12  9:12     ` Peter Zijlstra
2009-03-05 18:32 ` [PATCH] " Jaswinder Singh Rajput
2009-03-05 18:45   ` Peter Zijlstra
2009-03-05 18:56     ` Jaswinder Singh Rajput
2009-03-05 19:07       ` Peter Zijlstra
2009-03-05 19:37         ` Jaswinder Singh Rajput
2009-03-05 19:34       ` Peter Zijlstra
2009-03-05 19:41         ` Ingo Molnar
2009-03-05 20:01           ` Jaswinder Singh Rajput
2009-03-06  6:37             ` Mike Galbraith
2009-03-06  6:51               ` Mike Galbraith
2009-03-06  7:11                 ` Mike Galbraith

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox