diff options
| author | San Mehat <san@google.com> | 2010-05-06 15:37:55 -0700 | 
|---|---|---|
| committer | Arve Hjønnevåg <arve@android.com> | 2013-07-01 13:40:29 -0700 | 
| commit | 4624fb9d2d69c2ed59cb07712e1d8693e343dce7 (patch) | |
| tree | ab97f45443aabc948fe3c03dc481b751b2aacce5 | |
| parent | 45a84f273f0502a54b877bd53f117f83de00724f (diff) | |
| download | olio-linux-3.10-4624fb9d2d69c2ed59cb07712e1d8693e343dce7.tar.xz olio-linux-3.10-4624fb9d2d69c2ed59cb07712e1d8693e343dce7.zip | |
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>
| -rw-r--r-- | include/linux/sched.h | 3 | ||||
| -rw-r--r-- | kernel/fork.c | 16 | 
2 files changed, 19 insertions, 0 deletions
| diff --git a/include/linux/sched.h b/include/linux/sched.h index 178a8d909f1..7ccfeb1e406 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -1606,6 +1606,9 @@ static inline cputime_t task_gtime(struct task_struct *t)  extern void task_cputime_adjusted(struct task_struct *p, cputime_t *ut, cputime_t *st);  extern void thread_group_cputime_adjusted(struct task_struct *p, cputime_t *ut, cputime_t *st); +extern int task_free_register(struct notifier_block *n); +extern int task_free_unregister(struct notifier_block *n); +  /*   * Per process flags   */ diff --git a/kernel/fork.c b/kernel/fork.c index 5733ad5d585..41671a5d637 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);  } |