From: Matt H. <mat...@us...> - 2006-06-14 00:02:11
|
Modify oprofile to use the task watcher chain to watch for task exit. oprofile uses task exit as a point to synch buffers. This patch does not modify oprofile to use the task free path of task watchers. oprofile has its own task_free atomic notifier chain. Since its an atomic chain we can't replace it with task watcher. Also, it's called much later when the actual task struct is really about to be freed. Signed-off-by: Matt Helsley <mat...@us...> Cc: Philippe Elie <ph...@wa...> Cc: opr...@li... -- drivers/oprofile/buffer_sync.c | 11 ++++++----- include/linux/profile.h | 3 +-- kernel/exit.c | 1 - kernel/profile.c | 14 -------------- 4 files changed, 7 insertions(+), 22 deletions(-) Index: linux-2.6.17-rc6-mm2/kernel/exit.c =================================================================== --- linux-2.6.17-rc6-mm2.orig/kernel/exit.c +++ linux-2.6.17-rc6-mm2/kernel/exit.c @@ -847,11 +847,10 @@ fastcall NORET_TYPE void do_exit(long co struct task_struct *tsk = current; struct taskstats *tidstats, *tgidstats; int group_dead; int notify_result; - profile_task_exit(tsk); tsk->exit_code = code; notify_result = notify_watchers(WATCH_TASK_EXIT, tsk); WARN_ON(atomic_read(&tsk->fs_excl)); Index: linux-2.6.17-rc6-mm2/drivers/oprofile/buffer_sync.c =================================================================== --- linux-2.6.17-rc6-mm2.orig/drivers/oprofile/buffer_sync.c +++ linux-2.6.17-rc6-mm2/drivers/oprofile/buffer_sync.c @@ -63,12 +63,13 @@ static int task_free_notify(struct notif static int task_exit_notify(struct notifier_block * self, unsigned long val, void * data) { /* To avoid latency problems, we only process the current CPU, * hoping that most samples for the task are on this CPU */ - sync_buffer(raw_smp_processor_id()); - return 0; + if (get_watch_event(val) == WATCH_TASK_EXIT) + sync_buffer(raw_smp_processor_id()); + return NOTIFY_DONE; } /* The task is about to try a do_munmap(). We peek at what it's going to * do, and if it's an executable region, process the samples first, so @@ -150,11 +151,11 @@ int sync_start(void) start_cpu_work(); err = task_handoff_register(&task_free_nb); if (err) goto out1; - err = profile_event_register(PROFILE_TASK_EXIT, &task_exit_nb); + err = register_task_watcher(&task_exit_nb); if (err) goto out2; err = profile_event_register(PROFILE_MUNMAP, &munmap_nb); if (err) goto out3; @@ -165,11 +166,11 @@ int sync_start(void) out: return err; out4: profile_event_unregister(PROFILE_MUNMAP, &munmap_nb); out3: - profile_event_unregister(PROFILE_TASK_EXIT, &task_exit_nb); + unregister_task_watcher(&task_exit_nb); out2: task_handoff_unregister(&task_free_nb); out1: end_sync(); goto out; @@ -178,11 +179,11 @@ out1: void sync_stop(void) { unregister_module_notifier(&module_load_nb); profile_event_unregister(PROFILE_MUNMAP, &munmap_nb); - profile_event_unregister(PROFILE_TASK_EXIT, &task_exit_nb); + unregister_task_watcher(&task_exit_nb); task_handoff_unregister(&task_free_nb); end_sync(); } Index: linux-2.6.17-rc6-mm2/kernel/profile.c =================================================================== --- linux-2.6.17-rc6-mm2.orig/kernel/profile.c +++ linux-2.6.17-rc6-mm2/kernel/profile.c @@ -85,19 +85,13 @@ void __init profile_init(void) /* Profile event notifications */ #ifdef CONFIG_PROFILING -static BLOCKING_NOTIFIER_HEAD(task_exit_notifier); static ATOMIC_NOTIFIER_HEAD(task_free_notifier); static BLOCKING_NOTIFIER_HEAD(munmap_notifier); -void profile_task_exit(struct task_struct * task) -{ - blocking_notifier_call_chain(&task_exit_notifier, 0, task); -} - int profile_handoff_task(struct task_struct * task) { int ret; ret = atomic_notifier_call_chain(&task_free_notifier, 0, task); return (ret == NOTIFY_OK) ? 1 : 0; @@ -121,14 +115,10 @@ int task_handoff_unregister(struct notif int profile_event_register(enum profile_type type, struct notifier_block * n) { int err = -EINVAL; switch (type) { - case PROFILE_TASK_EXIT: - err = blocking_notifier_chain_register( - &task_exit_notifier, n); - break; case PROFILE_MUNMAP: err = blocking_notifier_chain_register( &munmap_notifier, n); break; } @@ -140,14 +130,10 @@ int profile_event_register(enum profile_ int profile_event_unregister(enum profile_type type, struct notifier_block * n) { int err = -EINVAL; switch (type) { - case PROFILE_TASK_EXIT: - err = blocking_notifier_chain_unregister( - &task_exit_notifier, n); - break; case PROFILE_MUNMAP: err = blocking_notifier_chain_unregister( &munmap_notifier, n); break; } Index: linux-2.6.17-rc6-mm2/include/linux/profile.h =================================================================== --- linux-2.6.17-rc6-mm2.orig/include/linux/profile.h +++ linux-2.6.17-rc6-mm2/include/linux/profile.h @@ -24,12 +24,11 @@ void create_prof_cpu_mask(struct proc_di #else #define create_prof_cpu_mask(x) do { (void)(x); } while (0) #endif enum profile_type { - PROFILE_TASK_EXIT, - PROFILE_MUNMAP + PROFILE_MUNMAP = 1 }; #ifdef CONFIG_PROFILING struct task_struct; -- |
From: Chase V. <cha...@cl...> - 2006-06-14 00:59:55
|
On Tuesday 13 June 2006 18:54, Matt Helsley wrote: > switch (type) { > - case PROFILE_TASK_EXIT: > - err = blocking_notifier_chain_register( > - &task_exit_notifier, n); > - break; > case PROFILE_MUNMAP: > err = blocking_notifier_chain_register( > &munmap_notifier, n); > break; > } if (type == PROFILE_MUNMAP) ? > @@ -140,14 +130,10 @@ int profile_event_register(enum profile_ > int profile_event_unregister(enum profile_type type, struct notifier_block > * n) { > int err = -EINVAL; > > switch (type) { > - case PROFILE_TASK_EXIT: > - err = blocking_notifier_chain_unregister( > - &task_exit_notifier, n); > - break; > case PROFILE_MUNMAP: > err = blocking_notifier_chain_unregister( > &munmap_notifier, n); > break; > } Same... Thanks, Chase |
From: Matt H. <mat...@us...> - 2006-06-14 01:24:51
|
On Tue, 2006-06-13 at 19:59 -0500, Chase Venters wrote: > On Tuesday 13 June 2006 18:54, Matt Helsley wrote: > > > switch (type) { > > - case PROFILE_TASK_EXIT: > > - err = blocking_notifier_chain_register( > > - &task_exit_notifier, n); > > - break; > > case PROFILE_MUNMAP: > > err = blocking_notifier_chain_register( > > &munmap_notifier, n); > > break; > > } > > if (type == PROFILE_MUNMAP) > > ? > > > @@ -140,14 +130,10 @@ int profile_event_register(enum profile_ > > int profile_event_unregister(enum profile_type type, struct notifier_block > > * n) { > > int err = -EINVAL; > > > > switch (type) { > > - case PROFILE_TASK_EXIT: > > - err = blocking_notifier_chain_unregister( > > - &task_exit_notifier, n); > > - break; > > case PROFILE_MUNMAP: > > err = blocking_notifier_chain_unregister( > > &munmap_notifier, n); > > break; > > } > > Same... > > Thanks, > Chase Hmm. Perhaps I ought to get rid of the condition and enum entirely then change the names of the functions to profile_mmmap() and profile_munmap(). It really depends on what additional changes, if any, are expected here. Since I don't have any plans to further modify profiling beyond what I've outlined in these patches I'm not sure what the best course is here. Thanks, -Matt Helsley |
From: Matt H. <mat...@us...> - 2006-06-14 22:52:37
|
On Tue, 2006-06-13 at 16:54 -0700, Matt Helsley wrote: > Modify oprofile to use the task watcher chain to watch for task exit. > oprofile uses task exit as a point to synch buffers. > > This patch does not modify oprofile to use the task free path of task watchers. > oprofile has its own task_free atomic notifier chain. Since its an atomic chain > we can't replace it with task watcher. Also, it's called much later when the > actual task struct is really about to be freed. > > Signed-off-by: Matt Helsley <mat...@us...> > Cc: Philippe Elie <ph...@wa...> > Cc: opr...@li... > -- > > drivers/oprofile/buffer_sync.c | 11 ++++++----- > include/linux/profile.h | 3 +-- > kernel/exit.c | 1 - > kernel/profile.c | 14 -------------- > 4 files changed, 7 insertions(+), 22 deletions(-) My apologies, I forgot to add you to the CC list of a relevant patch in this series. Here's a link to the patch that introduces the task watchers notifier chain, functions operating on the chain, and sends notifications useful to profiling: http://www.ussg.iu.edu/hypermail/linux/kernel/0606.1/1800.html Cheers, -Matt Helsley |