public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Peter Zijlstra <a.p.zijlstra@chello.nl>
To: Jason Wessel <jason.wessel@windriver.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>,
	Ingo Molnar <mingo@elte.hu>, LKML <linux-kernel@vger.kernel.org>
Subject: Re: [PATCH 2/2] perf,hw_breakpoint: Initialize hardware api earlier
Date: Tue, 16 Nov 2010 22:24:14 +0100	[thread overview]
Message-ID: <1289942654.2109.671.camel@laptop> (raw)
In-Reply-To: <4CDFE516.3050006@windriver.com>

[-- Attachment #1: Type: text/plain, Size: 535 bytes --]

On Sun, 2010-11-14 at 07:33 -0600, Jason Wessel wrote:
> 
> This sounds to me like it would be early enough.  I could certainly run
> the simple test case in the patch to make sure it still works, if you
> point me to your patch(es).  I imagine I should also test the hand off
> procedure where the debugger uses the registers directly up until the
> point that perf is capable of handling reservations for the hw
> breakpoint slots. 

I had to actually write them -- I had some hacky things in my sysfs RFC.
Find attached.

[-- Attachment #2: perf-i386-fix-kconfig.patch --]
[-- Type: text/x-patch, Size: 879 bytes --]

Subject: perf, x86: Fixup Kconfig deps
From: Peter Zijlstra <a.p.zijlstra@chello.nl>
Date: Tue Nov 16 21:49:01 CET 2010

This leads to a Kconfig dep inversion, x86 selects PERF_EVENT (due to
a hw_breakpoint dep) but doesn't unconditionally provide
HAVE_PERF_EVENT.

Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
LKML-Reference: <new-submission>
---
 arch/x86/Kconfig |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

Index: linux-2.6/arch/x86/Kconfig
===================================================================
--- linux-2.6.orig/arch/x86/Kconfig
+++ linux-2.6/arch/x86/Kconfig
@@ -21,7 +21,7 @@ config X86
 	select HAVE_UNSTABLE_SCHED_CLOCK
 	select HAVE_IDE
 	select HAVE_OPROFILE
-	select HAVE_PERF_EVENTS if (!M386 && !M486)
+	select HAVE_PERF_EVENTS
 	select HAVE_IRQ_WORK
 	select HAVE_IOREMAP_PROT
 	select HAVE_KPROBES

[-- Attachment #3: perf-fix-hw-init.patch --]
[-- Type: text/x-patch, Size: 6904 bytes --]

Subject: perf, arch: Use early_initcall() for all arch pmu implementations
From: Peter Zijlstra <a.p.zijlstra@chello.nl>
Date: Tue Nov 16 22:08:28 CET 2010

Currently architectures use various random locations to init the PMU
driver, for some this happens before the perf core code is
initialized.

In order to avoid calling perf_pmu_register() before the core code is
up and running and able to deal with it, move all arch init to at
least early_initcall (some archs use a later init, which is fine).

Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
LKML-Reference: <new-submission>
---
 arch/alpha/include/asm/perf_event.h |    6 ------
 arch/alpha/kernel/irq_alpha.c       |    2 --
 arch/alpha/kernel/perf_event.c      |    9 ++++++---
 arch/sparc/include/asm/perf_event.h |    4 ----
 arch/sparc/kernel/nmi.c             |    2 --
 arch/sparc/kernel/perf_event.c      |    7 +++++--
 arch/x86/include/asm/perf_event.h   |    2 --
 arch/x86/kernel/cpu/common.c        |    1 -
 arch/x86/kernel/cpu/perf_event.c    |    9 ++++++---
 9 files changed, 17 insertions(+), 25 deletions(-)

Index: linux-2.6/arch/alpha/include/asm/perf_event.h
===================================================================
--- linux-2.6.orig/arch/alpha/include/asm/perf_event.h
+++ linux-2.6/arch/alpha/include/asm/perf_event.h
@@ -1,10 +1,4 @@
 #ifndef __ASM_ALPHA_PERF_EVENT_H
 #define __ASM_ALPHA_PERF_EVENT_H
 
-#ifdef CONFIG_PERF_EVENTS
-extern void init_hw_perf_events(void);
-#else
-static inline void init_hw_perf_events(void)    { }
-#endif
-
 #endif /* __ASM_ALPHA_PERF_EVENT_H */
Index: linux-2.6/arch/alpha/kernel/irq_alpha.c
===================================================================
--- linux-2.6.orig/arch/alpha/kernel/irq_alpha.c
+++ linux-2.6/arch/alpha/kernel/irq_alpha.c
@@ -112,8 +112,6 @@ init_IRQ(void)
 	wrent(entInt, 0);
 
 	alpha_mv.init_irq();
-
-	init_hw_perf_events();
 }
 
 /*
Index: linux-2.6/arch/alpha/kernel/perf_event.c
===================================================================
--- linux-2.6.orig/arch/alpha/kernel/perf_event.c
+++ linux-2.6/arch/alpha/kernel/perf_event.c
@@ -14,6 +14,7 @@
 #include <linux/kernel.h>
 #include <linux/kdebug.h>
 #include <linux/mutex.h>
+#include <linux/init.h>
 
 #include <asm/hwrpb.h>
 #include <asm/atomic.h>
@@ -863,13 +864,13 @@ static void alpha_perf_event_irq_handler
 /*
  * Init call to initialise performance events at kernel startup.
  */
-void __init init_hw_perf_events(void)
+int __init init_hw_perf_events(void)
 {
 	pr_info("Performance events: ");
 
 	if (!supported_cpu()) {
 		pr_cont("No support for your CPU.\n");
-		return;
+		return 0;
 	}
 
 	pr_cont("Supported CPU type!\n");
@@ -882,5 +883,7 @@ void __init init_hw_perf_events(void)
 	alpha_pmu = &ev67_pmu;
 
 	perf_pmu_register(&pmu);
-}
 
+	return 0;
+}
+early_initcall(init_hw_perf_events);
Index: linux-2.6/arch/sparc/include/asm/perf_event.h
===================================================================
--- linux-2.6.orig/arch/sparc/include/asm/perf_event.h
+++ linux-2.6/arch/sparc/include/asm/perf_event.h
@@ -4,8 +4,6 @@
 #ifdef CONFIG_PERF_EVENTS
 #include <asm/ptrace.h>
 
-extern void init_hw_perf_events(void);
-
 #define perf_arch_fetch_caller_regs(regs, ip)		\
 do {							\
 	unsigned long _pstate, _asi, _pil, _i7, _fp;	\
@@ -26,8 +24,6 @@ do {							\
 	(regs)->u_regs[UREG_I6] = _fp;			\
 	(regs)->u_regs[UREG_I7] = _i7;			\
 } while (0)
-#else
-static inline void init_hw_perf_events(void)	{ }
 #endif
 
 #endif
Index: linux-2.6/arch/sparc/kernel/nmi.c
===================================================================
--- linux-2.6.orig/arch/sparc/kernel/nmi.c
+++ linux-2.6/arch/sparc/kernel/nmi.c
@@ -270,8 +270,6 @@ int __init nmi_init(void)
 			atomic_set(&nmi_active, -1);
 		}
 	}
-	if (!err)
-		init_hw_perf_events();
 
 	return err;
 }
Index: linux-2.6/arch/sparc/kernel/perf_event.c
===================================================================
--- linux-2.6.orig/arch/sparc/kernel/perf_event.c
+++ linux-2.6/arch/sparc/kernel/perf_event.c
@@ -1307,20 +1307,23 @@ static bool __init supported_pmu(void)
 	return false;
 }
 
-void __init init_hw_perf_events(void)
+int __init init_hw_perf_events(void)
 {
 	pr_info("Performance events: ");
 
 	if (!supported_pmu()) {
 		pr_cont("No support for PMU type '%s'\n", sparc_pmu_type);
-		return;
+		return 0;
 	}
 
 	pr_cont("Supported PMU type is '%s'\n", sparc_pmu_type);
 
 	perf_pmu_register(&pmu);
 	register_die_notifier(&perf_event_nmi_notifier);
+
+	return 0;
 }
+early_initcall(init_hw_perf_event);
 
 void perf_callchain_kernel(struct perf_callchain_entry *entry,
 			   struct pt_regs *regs)
Index: linux-2.6/arch/x86/include/asm/perf_event.h
===================================================================
--- linux-2.6.orig/arch/x86/include/asm/perf_event.h
+++ linux-2.6/arch/x86/include/asm/perf_event.h
@@ -125,7 +125,6 @@ union cpuid10_edx {
 #define IBS_OP_MAX_CNT_EXT	0x007FFFFFULL	/* not a register bit mask */
 
 #ifdef CONFIG_PERF_EVENTS
-extern void init_hw_perf_events(void);
 extern void perf_events_lapic_init(void);
 
 #define PERF_EVENT_INDEX_OFFSET			0
@@ -156,7 +155,6 @@ extern unsigned long perf_misc_flags(str
 }
 
 #else
-static inline void init_hw_perf_events(void)		{ }
 static inline void perf_events_lapic_init(void)	{ }
 #endif
 
Index: linux-2.6/arch/x86/kernel/cpu/common.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/cpu/common.c
+++ linux-2.6/arch/x86/kernel/cpu/common.c
@@ -894,7 +894,6 @@ void __init identify_boot_cpu(void)
 #else
 	vgetcpu_set_mode();
 #endif
-	init_hw_perf_events();
 }
 
 void __cpuinit identify_secondary_cpu(struct cpuinfo_x86 *c)
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
@@ -1348,7 +1348,7 @@ static void __init pmu_check_apic(void)
 	pr_info("no hardware sampling interrupt available.\n");
 }
 
-void __init init_hw_perf_events(void)
+int __init init_hw_perf_events(void)
 {
 	struct event_constraint *c;
 	int err;
@@ -1363,11 +1363,11 @@ void __init init_hw_perf_events(void)
 		err = amd_pmu_init();
 		break;
 	default:
-		return;
+		return 0;
 	}
 	if (err != 0) {
 		pr_cont("no PMU driver, software events only.\n");
-		return;
+		return 0;
 	}
 
 	pmu_check_apic();
@@ -1420,7 +1420,10 @@ void __init init_hw_perf_events(void)
 
 	perf_pmu_register(&pmu);
 	perf_cpu_notifier(x86_pmu_notifier);
+
+	return 0;
 }
+early_initcall(init_hw_perf_events);
 
 static inline void x86_pmu_read(struct perf_event *event)
 {

[-- Attachment #4: perf-fix-init.patch --]
[-- Type: text/x-patch, Size: 1403 bytes --]

Subject: perf: Move perf_event_init() into main.c
From: Peter Zijlstra <a.p.zijlstra@chello.nl>
Date: Tue Nov 16 22:12:05 CET 2010

Currently we call perf_event_init() from sched_init(). In order to
make it more obvious move it to the cannnonical location.

Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
LKML-Reference: <new-submission>
---
 init/main.c    |    2 ++
 kernel/sched.c |    2 --
 2 files changed, 2 insertions(+), 2 deletions(-)

Index: linux-2.6/init/main.c
===================================================================
--- linux-2.6.orig/init/main.c
+++ linux-2.6/init/main.c
@@ -68,6 +68,7 @@
 #include <linux/sfi.h>
 #include <linux/shmem_fs.h>
 #include <linux/slab.h>
+#include <linux/perf_event.h>
 
 #include <asm/io.h>
 #include <asm/bugs.h>
@@ -604,6 +605,7 @@ asmlinkage void __init start_kernel(void
 				"enabled *very* early, fixing it\n");
 		local_irq_disable();
 	}
+	perf_event_init();
 	rcu_init();
 	radix_tree_init();
 	/* init some links before init_ISA_irqs() */
Index: linux-2.6/kernel/sched.c
===================================================================
--- linux-2.6.orig/kernel/sched.c
+++ linux-2.6/kernel/sched.c
@@ -7876,8 +7876,6 @@ void __init sched_init(void)
 		zalloc_cpumask_var(&cpu_isolated_map, GFP_NOWAIT);
 #endif /* SMP */
 
-	perf_event_init();
-
 	scheduler_running = 1;
 }
 

[-- Attachment #5: perf-fix-tp-bp-init.patch --]
[-- Type: text/x-patch, Size: 1825 bytes --]

Subject: perf: Use early_initcall() for tracepoint and breakpoint init
From: Peter Zijlstra <a.p.zijlstra@chello.nl>
Date: Tue Nov 16 22:14:41 CET 2010

Just like other pmu implementations, use early_initcall().

Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
LKML-Reference: <new-submission>
---
 kernel/hw_breakpoint.c |    2 +-
 kernel/perf_event.c    |    9 +++------
 2 files changed, 4 insertions(+), 7 deletions(-)

Index: linux-2.6/kernel/hw_breakpoint.c
===================================================================
--- linux-2.6.orig/kernel/hw_breakpoint.c
+++ linux-2.6/kernel/hw_breakpoint.c
@@ -655,6 +655,6 @@ static int __init init_hw_breakpoint(voi
 
 	return -ENOMEM;
 }
-core_initcall(init_hw_breakpoint);
+early_initcall(init_hw_breakpoint);
 
 
Index: linux-2.6/kernel/perf_event.c
===================================================================
--- linux-2.6.orig/kernel/perf_event.c
+++ linux-2.6/kernel/perf_event.c
@@ -4831,10 +4831,12 @@ static struct pmu perf_tracepoint = {
 	.read		= perf_swevent_read,
 };
 
-static inline void perf_tp_register(void)
+static __init int perf_tp_init(void)
 {
 	perf_pmu_register(&perf_tracepoint);
+	return 0;
 }
+early_initcall(perf_tp_init);
 
 static int perf_event_set_filter(struct perf_event *event, void __user *arg)
 {
@@ -4861,10 +4863,6 @@ static void perf_event_free_filter(struc
 
 #else
 
-static inline void perf_tp_register(void)
-{
-}
-
 static int perf_event_set_filter(struct perf_event *event, void __user *arg)
 {
 	return -ENOENT;
@@ -6365,6 +6363,5 @@ void __init perf_event_init(void)
 	perf_pmu_register(&perf_swevent);
 	perf_pmu_register(&perf_cpu_clock);
 	perf_pmu_register(&perf_task_clock);
-	perf_tp_register();
 	perf_cpu_notifier(perf_cpu_notify);
 }

  reply	other threads:[~2010-11-16 21:24 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-11-13 21:37 [GIT PULL] hw-breakpoint fixes Frederic Weisbecker
2010-11-13 21:37 ` [PATCH 1/2] x86: Ignore trap bits on single step exceptions Frederic Weisbecker
2010-11-24 20:32   ` Michael Stefaniuc
2010-11-25  7:47     ` Frederic Weisbecker
2010-11-13 21:37 ` [PATCH 2/2] perf,hw_breakpoint: Initialize hardware api earlier Frederic Weisbecker
2010-11-13 21:46   ` Peter Zijlstra
2010-11-14 13:33     ` Jason Wessel
2010-11-16 21:24       ` Peter Zijlstra [this message]
2010-11-18 16:09         ` Jason Wessel
2010-11-18  9:39 ` [GIT PULL] hw-breakpoint fixes Ingo Molnar

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1289942654.2109.671.camel@laptop \
    --to=a.p.zijlstra@chello.nl \
    --cc=fweisbec@gmail.com \
    --cc=jason.wessel@windriver.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mingo@elte.hu \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox