linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] [4/7] oprofile - NMI hook
@ 2002-10-15 22:33 John Levon
  2002-10-15 22:56 ` Andi Kleen
  2002-10-16 14:06 ` Keith Owens
  0 siblings, 2 replies; 6+ messages in thread
From: John Levon @ 2002-10-15 22:33 UTC (permalink / raw)
  To: torvalds; +Cc: linux-kernel


This patch provides a simple api to let oprofile hook into
the NMI interrupt for the perfctr profiler.


diff -Naur -X dontdiff linux-linus/arch/i386/kernel/i386_ksyms.c linux-linus2/arch/i386/kernel/i386_ksyms.c
--- linux-linus/arch/i386/kernel/i386_ksyms.c	Tue Oct 15 22:46:47 2002
+++ linux-linus2/arch/i386/kernel/i386_ksyms.c	Tue Oct 15 22:47:19 2002
@@ -29,6 +29,7 @@
 #include <asm/pgtable.h>
 #include <asm/pgalloc.h>
 #include <asm/tlbflush.h>
+#include <asm/nmi.h>
 
 extern void dump_thread(struct pt_regs *, struct user *);
 extern spinlock_t rtc_lock;
@@ -151,6 +152,10 @@
 EXPORT_SYMBOL(flush_tlb_page);
 #endif
 
+#if defined(CONFIG_X86_LOCAL_APIC) && defined(CONFIG_PM)
+EXPORT_SYMBOL_GPL(set_nmi_pm_callback);
+EXPORT_SYMBOL_GPL(unset_nmi_pm_callback);
+#endif
 #ifdef CONFIG_X86_IO_APIC
 EXPORT_SYMBOL(IO_APIC_get_PCI_irq_vector);
 #endif
@@ -169,6 +174,8 @@
 
 EXPORT_SYMBOL_GPL(register_profile_notifier);
 EXPORT_SYMBOL_GPL(unregister_profile_notifier);
+EXPORT_SYMBOL_GPL(set_nmi_callback);
+EXPORT_SYMBOL_GPL(unset_nmi_callback);
  
 #undef memcpy
 #undef memset
diff -Naur -X dontdiff linux-linus/arch/i386/kernel/nmi.c linux-linus2/arch/i386/kernel/nmi.c
--- linux-linus/arch/i386/kernel/nmi.c	Sun Oct 13 19:51:03 2002
+++ linux-linus2/arch/i386/kernel/nmi.c	Tue Oct 15 22:47:02 2002
@@ -175,6 +175,18 @@
 	return 0;
 }
 
+struct pm_dev * set_nmi_pm_callback(pm_callback callback)
+{
+	apic_pm_unregister(nmi_pmdev);
+	return apic_pm_register(PM_SYS_DEV, 0, callback);
+}
+
+void unset_nmi_pm_callback(struct pm_dev * dev)
+{
+	apic_pm_unregister(dev);
+	nmi_pmdev = apic_pm_register(PM_SYS_DEV, 0, nmi_pm_callback);
+}
+ 
 static void nmi_pm_init(void)
 {
 	if (!nmi_pmdev)
diff -Naur -X dontdiff linux-linus/arch/i386/kernel/traps.c linux-linus2/arch/i386/kernel/traps.c
--- linux-linus/arch/i386/kernel/traps.c	Sun Oct 13 19:51:03 2002
+++ linux-linus2/arch/i386/kernel/traps.c	Tue Oct 15 22:47:02 2002
@@ -40,6 +40,7 @@
 #include <asm/debugreg.h>
 #include <asm/desc.h>
 #include <asm/i387.h>
+#include <asm/nmi.h>
 
 #include <asm/smp.h>
 #include <asm/pgalloc.h>
@@ -478,17 +479,16 @@
 		return;
 	}
 #endif
-	printk("Uhhuh. NMI received for unknown reason %02x.\n", reason);
+	printk("Uhhuh. NMI received for unknown reason %02x on CPU %d.\n",
+		reason, smp_processor_id());
 	printk("Dazed and confused, but trying to continue\n");
 	printk("Do you have a strange power saving mode enabled?\n");
 }
 
-asmlinkage void do_nmi(struct pt_regs * regs, long error_code)
+static void default_do_nmi(struct pt_regs * regs)
 {
 	unsigned char reason = inb(0x61);
-
-	++nmi_count(smp_processor_id());
-
+ 
 	if (!(reason & 0xc0)) {
 #if CONFIG_X86_LOCAL_APIC
 		/*
@@ -515,6 +515,33 @@
 	inb(0x71);		/* dummy */
 	outb(0x0f, 0x70);
 	inb(0x71);		/* dummy */
+}
+
+static int dummy_nmi_callback(struct pt_regs * regs, int cpu)
+{
+	return 0;
+}
+ 
+static nmi_callback_t nmi_callback = dummy_nmi_callback;
+ 
+asmlinkage void do_nmi(struct pt_regs * regs, long error_code)
+{
+	int cpu = smp_processor_id();
+
+	++nmi_count(cpu);
+
+	if (!nmi_callback(regs, cpu))
+		default_do_nmi(regs);
+}
+
+void set_nmi_callback(nmi_callback_t callback)
+{
+	nmi_callback = callback;
+}
+
+void unset_nmi_callback(void)
+{
+	nmi_callback = dummy_nmi_callback;
 }
 
 /*
diff -Naur -X dontdiff linux-linus/include/asm-i386/nmi.h linux-linus2/include/asm-i386/nmi.h
--- linux-linus/include/asm-i386/nmi.h	Thu Jan  1 01:00:00 1970
+++ linux-linus2/include/asm-i386/nmi.h	Tue Oct 15 22:47:02 2002
@@ -0,0 +1,49 @@
+/*
+ *  linux/include/asm-i386/nmi.h
+ */
+#ifndef ASM_NMI_H
+#define ASM_NMI_H
+
+#include <linux/pm.h>
+ 
+struct pt_regs;
+ 
+typedef int (*nmi_callback_t)(struct pt_regs * regs, int cpu);
+ 
+/** 
+ * set_nmi_callback
+ *
+ * Set a handler for an NMI. Only one handler may be
+ * set. Return 1 if the NMI was handled.
+ */
+void set_nmi_callback(nmi_callback_t callback);
+ 
+/** 
+ * unset_nmi_callback
+ *
+ * Remove the handler previously set.
+ */
+void unset_nmi_callback(void);
+ 
+#ifdef CONFIG_PM
+ 
+/** Replace the PM callback routine for NMI. */
+struct pm_dev * set_nmi_pm_callback(pm_callback callback);
+
+/** Unset the PM callback routine back to the default. */
+void unset_nmi_pm_callback(struct pm_dev * dev);
+
+#else
+
+static inline struct pm_dev * set_nmi_pm_callback(pm_callback callback)
+{
+	return 0;
+} 
+ 
+static inline void unset_nmi_pm_callback(struct pm_dev * dev)
+{
+}
+
+#endif /* CONFIG_PM */
+ 
+#endif /* ASM_NMI_H */

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

* Re: [PATCH] [4/7] oprofile - NMI hook
  2002-10-15 22:33 [PATCH] [4/7] oprofile - NMI hook John Levon
@ 2002-10-15 22:56 ` Andi Kleen
  2002-10-15 23:01   ` John Levon
  2002-10-16 14:06 ` Keith Owens
  1 sibling, 1 reply; 6+ messages in thread
From: Andi Kleen @ 2002-10-15 22:56 UTC (permalink / raw)
  To: John Levon; +Cc: linux-kernel

John Levon <levon@movementarian.org> writes:

> This patch provides a simple api to let oprofile hook into
> the NMI interrupt for the perfctr profiler.

I would suggest using a notifier list instead (include/linux/notifier.h) 
This would handle multiple users cleanly.

-Andi

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

* Re: [PATCH] [4/7] oprofile - NMI hook
  2002-10-15 22:56 ` Andi Kleen
@ 2002-10-15 23:01   ` John Levon
  2002-10-15 23:18     ` Andi Kleen
  0 siblings, 1 reply; 6+ messages in thread
From: John Levon @ 2002-10-15 23:01 UTC (permalink / raw)
  To: Andi Kleen; +Cc: linux-kernel

On Wed, Oct 16, 2002 at 12:56:28AM +0200, Andi Kleen wrote:

> > This patch provides a simple api to let oprofile hook into
> > the NMI interrupt for the perfctr profiler.
> 
> I would suggest using a notifier list instead (include/linux/notifier.h) 
> This would handle multiple users cleanly.

How ? The only safe way I can see would be to spin lock around the NMI
(and try lock when an NMI arrives).  This would either make every NMI
contend on a single spinlock, or require a NR_CPUS-sized array of
spinlocks, which is just ugly. And that wouldn't solve the
power-management problem - any NMI users need to collaborate to disable
NMI generation on a suspend.

regards
john

-- 
"CUT IT OUT FACEHEAD"
	- jeffk

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

* Re: [PATCH] [4/7] oprofile - NMI hook
  2002-10-15 23:01   ` John Levon
@ 2002-10-15 23:18     ` Andi Kleen
  0 siblings, 0 replies; 6+ messages in thread
From: Andi Kleen @ 2002-10-15 23:18 UTC (permalink / raw)
  To: John Levon; +Cc: Andi Kleen, linux-kernel

On Wed, Oct 16, 2002 at 01:01:06AM +0200, John Levon wrote:
> On Wed, Oct 16, 2002 at 12:56:28AM +0200, Andi Kleen wrote:
> 
> > > This patch provides a simple api to let oprofile hook into
> > > the NMI interrupt for the perfctr profiler.
> > 
> > I would suggest using a notifier list instead (include/linux/notifier.h) 
> > This would handle multiple users cleanly.
> 
> How ? The only safe way I can see would be to spin lock around the NMI
> (and try lock when an NMI arrives).  This would either make every NMI
> contend on a single spinlock, or require a NR_CPUS-sized array of
> spinlocks, which is just ugly. And that wouldn't solve the
> power-management problem - any NMI users need to collaborate to disable
> NMI generation on a suspend.

The locking issues could be fixed with read-copy-update, but you're
right that it's not a good solution right now. I take the objection
back then.

-Andi

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

* Re: [PATCH] [4/7] oprofile - NMI hook
  2002-10-15 22:33 [PATCH] [4/7] oprofile - NMI hook John Levon
  2002-10-15 22:56 ` Andi Kleen
@ 2002-10-16 14:06 ` Keith Owens
  2002-10-16 16:36   ` John Levon
  1 sibling, 1 reply; 6+ messages in thread
From: Keith Owens @ 2002-10-16 14:06 UTC (permalink / raw)
  To: John Levon; +Cc: linux-kernel

On Tue, 15 Oct 2002 23:33:19 +0100, 
John Levon <levon@movementarian.org> wrote:
>This patch provides a simple api to let oprofile hook into
>the NMI interrupt for the perfctr profiler.

Both kdb and lkcd use cross cpu NMI for debugging and dumping on SMP.
That plus oprofile and the NMI watchdog makes at least four users of
NMI.  A one level hook is not going to cut it, it should be a list.

I admit that removal of a hook from the NMI list while still handling
NMI interrupts is "interesting", but that is a SMOP ;).  RCU to the
rescue?


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

* Re: [PATCH] [4/7] oprofile - NMI hook
  2002-10-16 14:06 ` Keith Owens
@ 2002-10-16 16:36   ` John Levon
  0 siblings, 0 replies; 6+ messages in thread
From: John Levon @ 2002-10-16 16:36 UTC (permalink / raw)
  To: Keith Owens; +Cc: linux-kernel

On Thu, Oct 17, 2002 at 12:06:40AM +1000, Keith Owens wrote:

> Both kdb and lkcd use cross cpu NMI for debugging and dumping on SMP.
> That plus oprofile and the NMI watchdog makes at least four users of
> NMI.  A one level hook is not going to cut it, it should be a list.
> 
> I admit that removal of a hook from the NMI list while still handling
> NMI interrupts is "interesting", but that is a SMOP ;).  RCU to the
> rescue?

Yep, now RCU is merged I'll read up and see if I can come up with a list
API

regards
john
-- 
"It's a cardboard universe ... and if you lean too hard against it, you fall
 through." 
	- Philip K. Dick 

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

end of thread, other threads:[~2002-10-16 16:30 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2002-10-15 22:33 [PATCH] [4/7] oprofile - NMI hook John Levon
2002-10-15 22:56 ` Andi Kleen
2002-10-15 23:01   ` John Levon
2002-10-15 23:18     ` Andi Kleen
2002-10-16 14:06 ` Keith Owens
2002-10-16 16:36   ` John Levon

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).