From a370025d1ed83b2b8202c4fefe4ea465bf22f10a Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Wed, 10 Nov 2004 21:29:32 -0800 Subject: [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 Signed-off-by: Jesse Barnes Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/profile.h | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) (limited to 'include/linux') 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__ */ -- cgit v1.2.3