summaryrefslogtreecommitdiff
path: root/include/linux
diff options
context:
space:
mode:
authorJesse Barnes <jbarnes@engr.sgi.com>2004-11-10 21:29:32 -0800
committerLinus Torvalds <torvalds@ppc970.osdl.org>2004-11-10 21:29:32 -0800
commita370025d1ed83b2b8202c4fefe4ea465bf22f10a (patch)
treec18274d669421dc47eaedfbeab4a113f92172426 /include/linux
parent6998fe2529d33f5441dbfed6e924c990d052c167 (diff)
[PATCH] remove contention on profile_lock
profile_hook unconditionally takes a read lock on profile_lock if kernel profiling is enabled. The lock protects the profile_hook notifier chain from being written while it's being called. The routine profile_hook is called in a very hot path though: every timer tick on every CPU. As you can imagine, on a large system, this makes the cacheline containing profile_lock pretty hot. Since oprofile was the only user of the profile_hook, I removed the notifier chain altogether in favor of a simple function pointer with the help of John Levon. This removes all of the contention in the hot path since the variable is very seldom written and simplifies things a little to boot. Acked-by: John Levon <levon@movementarian.org> Signed-off-by: Jesse Barnes <jbarnes@sgi.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'include/linux')
-rw-r--r--include/linux/profile.h18
1 files changed, 8 insertions, 10 deletions
diff --git a/include/linux/profile.h b/include/linux/profile.h
index a22f4a15c981..026969a5595c 100644
--- a/include/linux/profile.h
+++ b/include/linux/profile.h
@@ -53,13 +53,13 @@ int task_handoff_unregister(struct notifier_block * n);
int profile_event_register(enum profile_type, struct notifier_block * n);
int profile_event_unregister(enum profile_type, struct notifier_block * n);
-int register_profile_notifier(struct notifier_block * nb);
-int unregister_profile_notifier(struct notifier_block * nb);
+int register_timer_hook(int (*hook)(struct pt_regs *));
+void unregister_timer_hook(int (*hook)(struct pt_regs *));
-struct pt_regs;
+/* Timer based profiling hook */
+extern int (*timer_hook)(struct pt_regs *);
-/* profiling hook activated on each timer interrupt */
-void profile_hook(struct pt_regs * regs);
+struct pt_regs;
#else
@@ -87,18 +87,16 @@ static inline int profile_event_unregister(enum profile_type t, struct notifier_
#define profile_handoff_task(a) (0)
#define profile_munmap(a) do { } while (0)
-static inline int register_profile_notifier(struct notifier_block * nb)
+static inline int register_timer_hook(int (*hook)(struct pt_regs *))
{
return -ENOSYS;
}
-static inline int unregister_profile_notifier(struct notifier_block * nb)
+static inline void unregister_timer_hook(int (*hook)(struct pt_regs *))
{
- return -ENOSYS;
+ return;
}
-#define profile_hook(regs) do { } while (0)
-
#endif /* CONFIG_PROFILING */
#endif /* __KERNEL__ */