[PATCH 1/4] arm: provide a mechanism to reserve performance counters

Jamie Iles jamie.iles at picochip.com
Fri Dec 11 04:44:19 EST 2009


To add support for perf events and to allow the hardware
counters to be shared with oprofile, we need a way to reserve
access to the pmu (performance monitor unit).

Signed-off-by: Jamie Iles <jamie.iles at picochip.com>
---
 arch/arm/include/asm/pmu.h |   54 ++++++++++++++++++++++++++++++++++++++++++++
 arch/arm/kernel/Makefile   |    1 +
 arch/arm/kernel/pmu.c      |   32 ++++++++++++++++++++++++++
 arch/arm/mm/Kconfig        |    4 +++
 4 files changed, 91 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/include/asm/pmu.h
 create mode 100644 arch/arm/kernel/pmu.c

diff --git a/arch/arm/include/asm/pmu.h b/arch/arm/include/asm/pmu.h
new file mode 100644
index 0000000..94d6c67
--- /dev/null
+++ b/arch/arm/include/asm/pmu.h
@@ -0,0 +1,54 @@
+/*
+ *  linux/arch/arm/include/asm/pmu.h
+ *
+ *  Copyright (C) 2009 picoChip Designs Ltd, Jamie Iles
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#ifndef __ARM_PMU_H__
+#define __ARM_PMU_H__
+
+#ifdef CONFIG_CPU_HAS_PMU
+
+/**
+ * reserve_pmu() - Reserve the hardware performance counters
+ *
+ * Reserve the hardware performance counters in the system for exclusive use.
+ * Note: success here does not guarantee exclusive access - callers must
+ * respect the return value.
+ *
+ * Returns zero on success, negative error on failure.
+ */
+extern int
+reserve_pmu(void);
+
+/**
+ * release_pmu() - Relinquish control of the performance counters
+ *
+ * Release the performance counters and allow someone else to use them.
+ * Callers must have disabled the counters and released IRQs before calling
+ * this.
+ */
+extern void
+release_pmu(void);
+
+#else /* CONFIG_CPU_HAS_PMU */
+
+static inline int
+reserve_pmu(void)
+{
+	return -ENODEV;
+}
+
+static inline void
+release_pmu(void)
+{
+}
+
+#endif /* CONFIG_CPU_HAS_PMU */
+
+#endif /* __ARM_PMU_H__ */
diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile
index e7ccf7e..286a276 100644
--- a/arch/arm/kernel/Makefile
+++ b/arch/arm/kernel/Makefile
@@ -46,6 +46,7 @@ obj-$(CONFIG_CPU_XSCALE)	+= xscale-cp0.o
 obj-$(CONFIG_CPU_XSC3)		+= xscale-cp0.o
 obj-$(CONFIG_CPU_MOHAWK)	+= xscale-cp0.o
 obj-$(CONFIG_IWMMXT)		+= iwmmxt.o
+obj-$(CONFIG_CPU_HAS_PMU)	+= pmu.o
 AFLAGS_iwmmxt.o			:= -Wa,-mcpu=iwmmxt
 
 ifneq ($(CONFIG_ARCH_EBSA110),y)
diff --git a/arch/arm/kernel/pmu.c b/arch/arm/kernel/pmu.c
new file mode 100644
index 0000000..a2b1a26
--- /dev/null
+++ b/arch/arm/kernel/pmu.c
@@ -0,0 +1,32 @@
+/*
+ *  linux/arch/arm/kernel/pmu.c
+ *
+ *  Copyright (C) 2009 picoChip Designs Ltd, Jamie Iles
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/semaphore.h>
+
+#include <asm/pmu.h>
+
+static DECLARE_MUTEX(pmu_mutex);
+
+int
+reserve_pmu(void)
+{
+	return down_trylock(&pmu_mutex) ? -EBUSY : 0;
+}
+EXPORT_SYMBOL_GPL(reserve_pmu);
+
+void
+release_pmu(void)
+{
+	up(&pmu_mutex);
+}
+EXPORT_SYMBOL_GPL(release_pmu);
diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig
index dd4698c..60edbfe 100644
--- a/arch/arm/mm/Kconfig
+++ b/arch/arm/mm/Kconfig
@@ -398,6 +398,7 @@ config CPU_V6
 	select CPU_HAS_ASID if MMU
 	select CPU_COPY_V6 if MMU
 	select CPU_TLB_V6 if MMU
+	select CPU_HAS_PMU
 
 # ARMv6k
 config CPU_32v6K
@@ -536,6 +537,9 @@ config CPU_COPY_FA
 config CPU_COPY_V6
 	bool
 
+config CPU_HAS_PMU
+	bool
+
 # This selects the TLB model
 config CPU_TLB_V3
 	bool
-- 
1.6.5.4




More information about the linux-arm-kernel mailing list