X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=kernel%2Fprofile.c;h=f89248e6d70479f73e34e78faf62fefa6fb532fe;hb=987b0145d94eecf292d8b301228356f44611ab7c;hp=68afe121e5071f0574e37e7b9e20f1d66bd4c290;hpb=f7ed79d23a47594e7834d66a8f14449796d4f3e6;p=linux-2.6.git diff --git a/kernel/profile.c b/kernel/profile.c index 68afe121e..f89248e6d 100644 --- a/kernel/profile.c +++ b/kernel/profile.c @@ -23,7 +23,6 @@ #include #include #include -#include #include #include @@ -45,7 +44,7 @@ static cpumask_t prof_cpu_mask = CPU_MASK_ALL; #ifdef CONFIG_SMP static DEFINE_PER_CPU(struct profile_hit *[2], cpu_profile_hits); static DEFINE_PER_CPU(int, cpu_profile_flip); -static DEFINE_MUTEX(profile_flip_mutex); +static DECLARE_MUTEX(profile_flip_mutex); #endif /* CONFIG_SMP */ static int __init profile_setup(char * str) @@ -87,52 +86,72 @@ void __init profile_init(void) #ifdef CONFIG_PROFILING -static BLOCKING_NOTIFIER_HEAD(task_exit_notifier); -static ATOMIC_NOTIFIER_HEAD(task_free_notifier); -static BLOCKING_NOTIFIER_HEAD(munmap_notifier); +static DECLARE_RWSEM(profile_rwsem); +static DEFINE_RWLOCK(handoff_lock); +static struct notifier_block * task_exit_notifier; +static struct notifier_block * task_free_notifier; +static struct notifier_block * munmap_notifier; void profile_task_exit(struct task_struct * task) { - blocking_notifier_call_chain(&task_exit_notifier, 0, task); + down_read(&profile_rwsem); + notifier_call_chain(&task_exit_notifier, 0, task); + up_read(&profile_rwsem); } int profile_handoff_task(struct task_struct * task) { int ret; - ret = atomic_notifier_call_chain(&task_free_notifier, 0, task); + read_lock(&handoff_lock); + ret = notifier_call_chain(&task_free_notifier, 0, task); + read_unlock(&handoff_lock); return (ret == NOTIFY_OK) ? 1 : 0; } void profile_munmap(unsigned long addr) { - blocking_notifier_call_chain(&munmap_notifier, 0, (void *)addr); + down_read(&profile_rwsem); + notifier_call_chain(&munmap_notifier, 0, (void *)addr); + up_read(&profile_rwsem); } int task_handoff_register(struct notifier_block * n) { - return atomic_notifier_chain_register(&task_free_notifier, n); + int err = -EINVAL; + + write_lock(&handoff_lock); + err = notifier_chain_register(&task_free_notifier, n); + write_unlock(&handoff_lock); + return err; } int task_handoff_unregister(struct notifier_block * n) { - return atomic_notifier_chain_unregister(&task_free_notifier, n); + int err = -EINVAL; + + write_lock(&handoff_lock); + err = notifier_chain_unregister(&task_free_notifier, n); + write_unlock(&handoff_lock); + return err; } int profile_event_register(enum profile_type type, struct notifier_block * n) { int err = -EINVAL; + down_write(&profile_rwsem); + switch (type) { case PROFILE_TASK_EXIT: - err = blocking_notifier_chain_register( - &task_exit_notifier, n); + err = notifier_chain_register(&task_exit_notifier, n); break; case PROFILE_MUNMAP: - err = blocking_notifier_chain_register( - &munmap_notifier, n); + err = notifier_chain_register(&munmap_notifier, n); break; } + up_write(&profile_rwsem); + return err; } @@ -141,17 +160,18 @@ int profile_event_unregister(enum profile_type type, struct notifier_block * n) { int err = -EINVAL; + down_write(&profile_rwsem); + switch (type) { case PROFILE_TASK_EXIT: - err = blocking_notifier_chain_unregister( - &task_exit_notifier, n); + err = notifier_chain_unregister(&task_exit_notifier, n); break; case PROFILE_MUNMAP: - err = blocking_notifier_chain_unregister( - &munmap_notifier, n); + err = notifier_chain_unregister(&munmap_notifier, n); break; } + up_write(&profile_rwsem); return err; } @@ -223,7 +243,7 @@ static void profile_flip_buffers(void) { int i, j, cpu; - mutex_lock(&profile_flip_mutex); + down(&profile_flip_mutex); j = per_cpu(cpu_profile_flip, get_cpu()); put_cpu(); on_each_cpu(__profile_flip_buffers, NULL, 0, 1); @@ -239,14 +259,14 @@ static void profile_flip_buffers(void) hits[i].hits = hits[i].pc = 0; } } - mutex_unlock(&profile_flip_mutex); + up(&profile_flip_mutex); } static void profile_discard_flip_buffers(void) { int i, cpu; - mutex_lock(&profile_flip_mutex); + down(&profile_flip_mutex); i = per_cpu(cpu_profile_flip, get_cpu()); put_cpu(); on_each_cpu(__profile_flip_buffers, NULL, 0, 1); @@ -254,7 +274,7 @@ static void profile_discard_flip_buffers(void) struct profile_hit *hits = per_cpu(cpu_profile_hits, cpu)[i]; memset(hits, 0, NR_PROFILE_HIT*sizeof(struct profile_hit)); } - mutex_unlock(&profile_flip_mutex); + up(&profile_flip_mutex); } void profile_hit(int type, void *__pc) @@ -299,7 +319,7 @@ out: } #ifdef CONFIG_HOTPLUG_CPU -static int profile_cpu_callback(struct notifier_block *info, +static int __devinit profile_cpu_callback(struct notifier_block *info, unsigned long action, void *__cpu) { int node, cpu = (unsigned long)__cpu;