This implements the perf nmi handler for ibs interrupts. The code was
copied from oprofile and should be merged somewhen.
Signed-off-by: Robert Richter <robert.richter@amd.com>
---
arch/x86/kernel/cpu/perf_event.c | 10 ++++
arch/x86/kernel/cpu/perf_event_amd.c | 87 ++++++++++++++++++++++++++++++++++
2 files changed, 97 insertions(+), 0 deletions(-)
diff --git a/arch/x86/kernel/cpu/perf_event.c b/arch/x86/kernel/cpu/perf_event.c
index a42d033..8f9674f 100644
--- a/arch/x86/kernel/cpu/perf_event.c
+++ b/arch/x86/kernel/cpu/perf_event.c
@@ -383,12 +383,15 @@ static void release_pmc_hardware(void) {}
static int reserve_ds_buffers(void);
static void release_ds_buffers(void);
+static int reserve_ibs_hardware(void);
+static void release_ibs_hardware(void);
static void hw_perf_event_destroy(struct perf_event *event)
{
if (atomic_dec_and_mutex_lock(&active_events, &pmc_reserve_mutex)) {
release_pmc_hardware();
release_ds_buffers();
+ release_ibs_hardware();
mutex_unlock(&pmc_reserve_mutex);
}
}
@@ -537,6 +540,13 @@ static int __hw_perf_event_init(struct perf_event *event)
if (err)
release_pmc_hardware();
}
+ if (!err) {
+ err = reserve_ibs_hardware();
+ if (err) {
+ release_ds_buffers();
+ release_pmc_hardware();
+ }
+ }
}
if (!err)
atomic_inc(&active_events);
diff --git a/arch/x86/kernel/cpu/perf_event_amd.c b/arch/x86/kernel/cpu/perf_event_amd.c
index 246304d..27daead 100644
--- a/arch/x86/kernel/cpu/perf_event_amd.c
+++ b/arch/x86/kernel/cpu/perf_event_amd.c
@@ -1,5 +1,7 @@
#ifdef CONFIG_CPU_SUP_AMD
+#include <linux/pci.h>
+
static DEFINE_RAW_SPINLOCK(amd_nb_lock);
static __initconst const u64 amd_hw_cache_event_ids
@@ -106,6 +108,91 @@ static const u64 amd_perfmon_event_map[] =
[PERF_COUNT_HW_BRANCH_MISSES] = 0x00c5,
};
+#ifdef CONFIG_X86_LOCAL_APIC
+
+/* IBS - apic initialization, taken from oprofile, should be unified */
+
+static u8 ...That on_each_cpu() looks wonky, why isn't this in the hotplug hooks? --
Right, it should be there. Will update this patch. -Robert -- Advanced Micro Devices, Inc. Operating System Research Center email: robert.richter@amd.com --
Peter, please see my updated version below. -Robert --- From bcb2c4aec6bf09fc7c05f31dde9dacd57b9c679c Mon Sep 17 00:00:00 2001 From: Robert Richter <robert.richter@amd.com> Date: Mon, 19 Apr 2010 15:32:37 +0200 Subject: [PATCH] perf, x86: setup NMI handler for IBS This implements the perf nmi handler for ibs interrupts. The code was copied from oprofile and should be merged somewhen. Signed-off-by: Robert Richter <robert.richter@amd.com> --- arch/x86/kernel/cpu/perf_event.c | 5 ++ arch/x86/kernel/cpu/perf_event_amd.c | 85 ++++++++++++++++++++++++++++++++++ 2 files changed, 90 insertions(+), 0 deletions(-) diff --git a/arch/x86/kernel/cpu/perf_event.c b/arch/x86/kernel/cpu/perf_event.c index 940107f..0ad8c45 100644 --- a/arch/x86/kernel/cpu/perf_event.c +++ b/arch/x86/kernel/cpu/perf_event.c @@ -516,6 +516,8 @@ static int x86_pmu_hw_config(struct perf_event *event) return x86_setup_perfctr(event); } +static inline void init_ibs_nmi(void); + /* * Setup the hardware configuration for a given attr_type */ @@ -537,6 +539,8 @@ static int __hw_perf_event_init(struct perf_event *event) if (err) release_pmc_hardware(); } + if (!err) + init_ibs_nmi(); } if (!err) atomic_inc(&active_events); @@ -1381,6 +1385,7 @@ static void __init pmu_check_apic(void) return; x86_pmu.apic = 0; + x86_pmu.ibs = 0; pr_info("no APIC, boot with the \"lapic\" boot parameter to force-enable it.\n"); pr_info("no hardware sampling interrupt available.\n"); } diff --git a/arch/x86/kernel/cpu/perf_event_amd.c b/arch/x86/kernel/cpu/perf_event_amd.c index 246304d..a6ce6f8 100644 --- a/arch/x86/kernel/cpu/perf_event_amd.c +++ b/arch/x86/kernel/cpu/perf_event_amd.c @@ -1,5 +1,7 @@ #ifdef CONFIG_CPU_SUP_AMD +#include <linux/pci.h> + static DEFINE_RAW_SPINLOCK(amd_nb_lock); static __initconst const u64 amd_hw_cache_event_ids @@ -106,6 +108,85 @@ static const u64 amd_perfmon_event_map[] = ...
