summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorJohn Levon <levon@movementarian.org>2002-10-15 04:30:38 -0700
committerLinus Torvalds <torvalds@home.transmeta.com>2002-10-15 04:30:38 -0700
commit120790b8fe2d901d99f459a567fefbb35c2d15e1 (patch)
treea3abac277c8b40f171364bedb3f2309ceb2062b0 /include
parent7e1aee05c99cfbb7e5cf33bae11ab9fa8df6c57c (diff)
[PATCH] oprofile - timer hook
This implements a simple hook into the profiling timer for x86 so that non-perfctr machines can still use oprofile. This has proven useful for laptops and the like. It also reduces header dependencies a bit by centralising readprofile code
Diffstat (limited to 'include')
-rw-r--r--include/asm-i386/hw_irq.h49
-rw-r--r--include/linux/profile.h11
-rw-r--r--include/linux/sched.h4
3 files changed, 52 insertions, 12 deletions
diff --git a/include/asm-i386/hw_irq.h b/include/asm-i386/hw_irq.h
index f23f4f75ce65..1a60daa9172e 100644
--- a/include/asm-i386/hw_irq.h
+++ b/include/asm-i386/hw_irq.h
@@ -13,6 +13,7 @@
*/
#include <linux/config.h>
+#include <linux/profile.h>
#include <asm/atomic.h>
#include <asm/irq.h>
@@ -65,20 +66,31 @@ extern char _stext, _etext;
#define IO_APIC_IRQ(x) (((x) >= 16) || ((1<<(x)) & io_apic_irqs))
-extern unsigned long prof_cpu_mask;
-extern unsigned int * prof_buffer;
-extern unsigned long prof_len;
-extern unsigned long prof_shift;
-
/*
- * x86 profiling function, SMP safe. We might want to do this in
- * assembly totally?
+ * The profiling function is SMP safe. (nothing can mess
+ * around with "current", and the profiling counters are
+ * updated with atomic operations). This is especially
+ * useful with a profiling multiplier != 1
*/
-static inline void x86_do_profile (unsigned long eip)
+static inline void x86_do_profile(struct pt_regs * regs)
{
+ unsigned long eip;
+ extern unsigned long prof_cpu_mask;
+ extern char _stext;
+#ifdef CONFIG_PROFILING
+ extern void x86_profile_hook(struct pt_regs *);
+
+ x86_profile_hook(regs);
+#endif
+
+ if (user_mode(regs))
+ return;
+
if (!prof_buffer)
return;
+ eip = regs->eip;
+
/*
* Only measure the CPUs specified by /proc/irq/prof_cpu_mask.
* (default is all CPUs.)
@@ -97,7 +109,28 @@ static inline void x86_do_profile (unsigned long eip)
eip = prof_len-1;
atomic_inc((atomic_t *)&prof_buffer[eip]);
}
+
+struct notifier_block;
+
+#ifdef CONFIG_PROFILING
+
+int register_profile_notifier(struct notifier_block * nb);
+int unregister_profile_notifier(struct notifier_block * nb);
+
+#else
+
+static inline int register_profile_notifier(struct notifier_block * nb)
+{
+ return -ENOSYS;
+}
+
+static inline int unregister_profile_notifier(struct notifier_block * nb)
+{
+ return -ENOSYS;
+}
+#endif /* CONFIG_PROFILING */
+
#ifdef CONFIG_SMP /*more of this file should probably be ifdefed SMP */
static inline void hw_resend_irq(struct hw_interrupt_type *h, unsigned int i) {
if (IO_APIC_IRQ(i))
diff --git a/include/linux/profile.h b/include/linux/profile.h
index 15c1e91198b0..11fbe9cec572 100644
--- a/include/linux/profile.h
+++ b/include/linux/profile.h
@@ -8,6 +8,17 @@
#include <linux/init.h>
#include <asm/errno.h>
+/* parse command line */
+int __init profile_setup(char * str);
+
+/* init basic kernel profiler */
+void __init profile_init(void);
+
+extern unsigned int * prof_buffer;
+extern unsigned long prof_len;
+extern unsigned long prof_shift;
+
+
enum profile_type {
EXIT_TASK,
EXIT_MMAP,
diff --git a/include/linux/sched.h b/include/linux/sched.h
index 89c4ead4cf4b..764a3ebf3c24 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -492,10 +492,6 @@ extern unsigned long itimer_ticks;
extern unsigned long itimer_next;
extern void do_timer(struct pt_regs *);
-extern unsigned int * prof_buffer;
-extern unsigned long prof_len;
-extern unsigned long prof_shift;
-
extern void FASTCALL(__wake_up(wait_queue_head_t *q, unsigned int mode, int nr));
extern void FASTCALL(__wake_up_locked(wait_queue_head_t *q, unsigned int mode));
extern void FASTCALL(__wake_up_sync(wait_queue_head_t *q, unsigned int mode, int nr));