diff options
author | San Mehat <san@google.com> | 2010-05-06 15:37:55 -0700 |
---|---|---|
committer | Nitin Garg <nitin.garg@freescale.com> | 2014-04-21 22:34:43 -0500 |
commit | 8c0db644c9d43389772fc6d4f47352aef52e31dc (patch) | |
tree | a8d62e58b1d01505289c1a3690b61ad6dd91c873 /kernel | |
parent | c3af187f917abce635f49e0d9a1d231092591fbc (diff) |
sched: Add a generic notifier when a task struct is about to be freed
This patch adds a notifier which can be used by subsystems that may
be interested in when a task has completely died and is about to
have it's last resource freed.
The Android lowmemory killer uses this to determine when a task
it has killed has finally given up its goods.
Signed-off-by: San Mehat <san@google.com>
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/fork.c | 16 |
1 files changed, 16 insertions, 0 deletions
diff --git a/kernel/fork.c b/kernel/fork.c index cabb2c0f696a..0aa1bb5c8d6e 100644 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -198,6 +198,9 @@ struct kmem_cache *vm_area_cachep; /* SLAB cache for mm_struct structures (tsk->mm) */ static struct kmem_cache *mm_cachep; +/* Notifier list called when a task struct is freed */ +static ATOMIC_NOTIFIER_HEAD(task_free_notifier); + static void account_kernel_stack(struct thread_info *ti, int account) { struct zone *zone = page_zone(virt_to_page(ti)); @@ -231,6 +234,18 @@ static inline void put_signal_struct(struct signal_struct *sig) free_signal_struct(sig); } +int task_free_register(struct notifier_block *n) +{ + return atomic_notifier_chain_register(&task_free_notifier, n); +} +EXPORT_SYMBOL(task_free_register); + +int task_free_unregister(struct notifier_block *n) +{ + return atomic_notifier_chain_unregister(&task_free_notifier, n); +} +EXPORT_SYMBOL(task_free_unregister); + void __put_task_struct(struct task_struct *tsk) { WARN_ON(!tsk->exit_state); @@ -242,6 +257,7 @@ void __put_task_struct(struct task_struct *tsk) delayacct_tsk_free(tsk); put_signal_struct(tsk->signal); + atomic_notifier_call_chain(&task_free_notifier, 0, tsk); if (!profile_handoff_task(tsk)) free_task(tsk); } |