Revert "Revert "sched: Add a generic notifier when a task struct is about to be freed""
authorRebecca Schultz Zavin <rebecca@android.com>
Tue, 21 Dec 2010 19:36:14 +0000 (11:36 -0800)
committerRebecca Schultz Zavin <rebecca@android.com>
Tue, 21 Dec 2010 19:36:36 +0000 (11:36 -0800)
This reverts commit d534322cb6066ae0db4790ceacba3e1a95b1ee7c.

include/linux/sched.h
kernel/fork.c

index ba3494e52d1709bb440877ff490e9e13d871af02..6e3dd4fef93c1c699f9f74d599e7f56c886bc646 100644 (file)
@@ -1679,6 +1679,9 @@ static inline void put_task_struct(struct task_struct *t)
 extern void task_times(struct task_struct *p, cputime_t *ut, cputime_t *st);
 extern void thread_group_times(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
  */
index c445f8cc408d777dd7a94aec3fa78c07e1d98b98..f3d93ab730c6798ab11f47bd24197557cdf800cf 100644 (file)
@@ -147,6 +147,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));
@@ -177,6 +180,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);
@@ -187,6 +202,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);
 }