Skip to contentSkip to conversation

adds base POWER arch support to perfmon2 minimal v3

PATCH New Corey Ashford 1 participant 1 message Aug 7, 2008 PowerPC

lore
Share & tools
lore
#0 lore raw

PATCH 1/2 adds base POWER arch support to perfmon2 minimal v3

This patch adds a base level of support for the POWER architecture to the perfmon2 minimal v3 patch set posted to the mailing list by Stephane Eranian on 06/30/2008.

Thanks for your consideration,

- Corey

Signature · 6 lines
Corey Ashford
Software Engineer
IBM Linux Technology Center, Linux Toolchain
Beaverton, OR
503-578-3507
[email protected]

This patch adds chip-independent perfmon2 support for the PowerPC and POWER architectures. It does not implement perfmon2 for any specific PowerPC or POWER chip, but does add the underpinnings for that implementation.

Prerequisites: The patch is built on top of Steven Rothwell's Linux git tree, plus Stephane Eranian's minimal perfmon2 patch v2 posted to the LKML mailing list on 6/30.

In addition to adding a new directory, arch/powerpc/perfmon, and several files in that new directory, it also adds perfmon2 support for handling the PMU exception on these processors.

In order to share the PMU exception handler with Oprofile, we continue to use the same exception wrapper (STD_PSERIES_EXCEPTION), but mimmick what the MASKABLE_PSERIES_EXCEPTION macro does from within powerpc_irq_handler in arch/powerpc/perfmon/perfmon.c. In order to do this correctly, a new member was added to the paca structure to record that a PMU exception occurred while interrupts were soft disabled.

--

include/asm-powerpc/paca.h +4 -0
Index: linux-next/include/asm-powerpc/paca.h
===================================================================
@@ -99,6 +99,10 @@
 	u8 soft_enabled;		/* irq soft-enable flag */
 	u8 hard_enabled;		/* set if irqs are enabled in MSR */
 	u8 io_sync;			/* writel() needs spin_unlock sync */
+#ifdef CONFIG_PERFMON
+	u8 pmu_except_pending;          /* PMU exception occurred while soft
+					 * disabled */
+#endif
 
 	/* Stuff for accurate time accounting */
 	u64 user_time;			/* accumulated usermode TB ticks */
arch/powerpc/kernel/irq.c +33 -0
Index: linux-next/arch/powerpc/kernel/irq.c
===================================================================
@@ -114,6 +114,24 @@
 	: : "r" (enable), "i" (offsetof(struct paca_struct, soft_enabled)));
 }
 
+#ifdef CONFIG_PERFMON
+static inline unsigned long get_pmu_except_pending(void)
+{
+	unsigned long pending;
+
+	__asm__ __volatile__("lbz %0,%1(13)"
+	: "=r" (pending) : "i" (offsetof(struct paca_struct, pmu_except_pending)));
+
+	return pending;
+}
+
+static inline void set_pmu_except_pending(unsigned long pending)
+{
+	__asm__ __volatile__("stb %0,%1(13)"
+	: : "r" (pending), "i" (offsetof(struct paca_struct, pmu_except_pending)));
+}
+#endif /* CONFIG_PERFMON */
+
 notrace void raw_local_irq_restore(unsigned long en)
 {
 	/*
@@ -172,6 +190,21 @@
 		lv1_get_version_info(&tmp);
 	}
 
+#ifdef CONFIG_PERFMON
+	/*
+	 * If a PMU exception occurred while interrupts were soft disabled,
+	 * force a PMU exception.
+	 */
+	if (get_pmu_except_pending()) {
+		set_pmu_except_pending(0);
+		/*
+		 * When both MSR_EE and MMCR_PMAO are set, a PMU exception
+		 * will occur.
+		 */
+		mtspr(SPRN_MMCR0, mfspr(SPRN_MMCR0) | (MMCR0_PMXE | MMCR0_PMAO));
+	}
+#endif /* CONFIG_PERFMON */
+
 	__hard_irq_enable();
 }
 EXPORT_SYMBOL(raw_local_irq_restore);
arch/powerpc/perfmon/perfmon.c new file +310 -0

310 lines not on this page · raw message

arch/powerpc/perfmon/Kconfig new file +26 -0
Index: linux-next/arch/powerpc/perfmon/Kconfig
===================================================================
@@ -0,0 +1,26 @@
+menu "Hardware Performance Monitoring support"
+config PERFMON
+	bool "Perfmon2 performance monitoring interface"
+	default n
+	help
+	Enables the perfmon2 interface to access the hardware
+	performance counters. See <http://perfmon2.sf.net/> for
+	more details.
+
+config PERFMON_DEBUG
+	bool "Perfmon debugging"
+	default n
+	depends on PERFMON
+	help
+	Enables perfmon debugging support
+
+config PERFMON_DEBUG_FS
+	bool "Enable perfmon statistics reporting via debugfs"
+	default y
+	depends on PERFMON && DEBUG_FS
+	help
+	Enable collection and reporting of perfmon timing statistics under
+	debugfs. This is used for debugging and performance analysis of the
+	subsystem. The debugfs filesystem must be mounted.
+
+endmenu
arch/powerpc/Kconfig +1 -0
Index: linux-next/arch/powerpc/Kconfig
===================================================================
@@ -219,6 +219,7 @@
 
 source "arch/powerpc/sysdev/Kconfig"
 source "arch/powerpc/platforms/Kconfig"
+source "arch/powerpc/perfmon/Kconfig"
 
 menu "Kernel options"
 
include/asm-powerpc/perfmon.h new file +33 -0
Index: linux-next/include/asm-powerpc/perfmon.h
===================================================================
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2007 Hewlett-Packard Development Company, L.P.
+ * Contributed by Stephane Eranian <[email protected]>
+ *
+ * This file contains powerpc specific definitions for the perfmon
+ * interface.
+ *
+ * This file MUST never be included directly. Use linux/perfmon.h.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public
+ * License as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ * 02111-1307 USA
+ */
+#ifndef _ASM_POWERPC_PERFMON_H_
+#define _ASM_POWERPC_PERFMON_H_
+
+/*
+ * arch-specific user visible interface definitions
+ */
+#define PFM_ARCH_MAX_PMCS	(256+64) /* 256 HW 64 SW */
+#define PFM_ARCH_MAX_PMDS	(256+64) /* 256 HW 64 SW */
+
+#endif /* _ASM_POWERPC_PERFMON_H_ */
include/asm-powerpc/perfmon_kern.h new file +314 -0

314 lines not on this page · raw message

arch/powerpc/Makefile +1 -0
Index: linux-next/arch/powerpc/Makefile
===================================================================
@@ -147,6 +147,7 @@
 				   arch/powerpc/platforms/
 core-$(CONFIG_MATH_EMULATION)	+= arch/powerpc/math-emu/
 core-$(CONFIG_XMON)		+= arch/powerpc/xmon/
+core-$(CONFIG_PERFMON)		+= arch/powerpc/perfmon/
 core-$(CONFIG_KVM) 		+= arch/powerpc/kvm/
 
 drivers-$(CONFIG_OPROFILE)	+= arch/powerpc/oprofile/
arch/powerpc/perfmon/Makefile new file +1 -0
Index: linux-next/arch/powerpc/perfmon/Makefile
===================================================================
@@ -0,0 +1 @@
+obj-$(CONFIG_PERFMON)		+= perfmon.o
include/asm-powerpc/unistd.h +13 -1
Index: linux-next/include/asm-powerpc/unistd.h
===================================================================
@@ -335,10 +335,22 @@
 #define __NR_subpage_prot	310
 #define __NR_timerfd_settime	311
 #define __NR_timerfd_gettime	312
+#define __NR_pfm_create_context	313
+#define __NR_pfm_write_pmcs	314
+#define __NR_pfm_write_pmds	315
+#define __NR_pfm_read_pmds	316
+#define __NR_pfm_load_context	317
+#define __NR_pfm_start		318
+#define __NR_pfm_stop		319
+#define __NR_pfm_reserved_1	320
+#define __NR_pfm_reserved_2	321
+#define __NR_pfm_reserved_3	322
+#define __NR_pfm_reserved_4	323
+#define __NR_pfm_unload_context	324
 
 #ifdef __KERNEL__
 
-#define __NR_syscalls		313
+#define __NR_syscalls		325
 
 #define __NR__exit __NR_exit
 #define NR_syscalls	__NR_syscalls
include/asm-powerpc/systbl.h +12 -0
Index: linux-next/include/asm-powerpc/systbl.h
===================================================================
@@ -316,3 +316,15 @@
 SYSCALL(subpage_prot)
 COMPAT_SYS_SPU(timerfd_settime)
 COMPAT_SYS_SPU(timerfd_gettime)
+SYSCALL(pfm_create_context)
+SYSCALL(pfm_write_pmcs)
+SYSCALL(pfm_write_pmds)
+SYSCALL(pfm_read_pmds)
+SYSCALL(pfm_load_context)
+SYSCALL(pfm_start)
+SYSCALL(pfm_stop)
+SYSCALL(pfm_reserved_1)
+SYSCALL(pfm_reserved_2)
+SYSCALL(pfm_reserved_3)
+SYSCALL(pfm_reserved_4)
+SYSCALL(pfm_unload_context)
arch/powerpc/kernel/process.c +8 -0
Index: linux-next/arch/powerpc/kernel/process.c
===================================================================
@@ -33,6 +33,7 @@
 #include <linux/mqueue.h>
 #include <linux/hardirq.h>
 #include <linux/utsname.h>
+#include <linux/perfmon_kern.h>
 
 #include <asm/pgtable.h>
 #include <asm/uaccess.h>
@@ -349,6 +350,11 @@
 
 	local_irq_save(flags);
 
+	if (test_tsk_thread_flag(prev, TIF_PERFMON_CTXSW))
+		pfm_ctxsw_out(prev, new);
+	if (test_tsk_thread_flag(new, TIF_PERFMON_CTXSW))
+		pfm_ctxsw_in(prev, new);
+
 	account_system_vtime(current);
 	account_process_vtime(current);
 	calculate_steal_time();
@@ -497,6 +503,7 @@
 void exit_thread(void)
 {
 	discard_lazy_cpu_state();
+	pfm_exit_thread();
 }
 
 void flush_thread(void)
@@ -617,6 +624,7 @@
 #else
 	kregs->nip = (unsigned long)ret_from_fork;
 #endif
+	pfm_copy_thread(p);
 
 	return 0;
 }
include/asm-x86/perfmon_kern.h +10 -0
Index: linux-next/include/asm-x86/perfmon_kern.h
===================================================================
@@ -398,6 +398,16 @@
 }
 
 /*
+ * pfm_arch_clear_pmd_ovfl_cond - alter the pmds in such a way that they
+ * will not cause cause interrupts when unused.
+ *
+ * This is a nop on x86
+ */
+static inline void pfm_arch_clear_pmd_ovfl_cond(struct pfm_context *ctx,
+					        struct pfm_event_set *set)
+{}
+
+/*
  * functions implemented in arch/x86/perfmon/perfmon.c
  */
 int  pfm_arch_init(void);
perfmon/perfmon_ctxsw.c +1 -0
Index: linux-next/perfmon/perfmon_ctxsw.c
===================================================================
@@ -65,6 +65,7 @@
 			num--;
 		}
 	}
+	pfm_arch_clear_pmd_ovfl_cond(ctx, set);
 }
 
 /*