extern void exit_thread(void);
 
 extern void exit_files(struct task_struct *);
-extern void exit_signal(struct task_struct *);
+extern void __cleanup_signal(struct signal_struct *);
 extern void __exit_signal(struct task_struct *);
 extern void __exit_sighand(struct task_struct *);
 extern void exit_itimers(struct signal_struct *);
 
 extern kmem_cache_t    *files_cachep;
 extern kmem_cache_t    *filp_cachep;
 extern kmem_cache_t    *fs_cachep;
-extern kmem_cache_t    *signal_cachep;
 extern kmem_cache_t    *sighand_cachep;
 extern kmem_cache_t    *bio_cachep;
 
 
 #endif
 
 /* SLAB cache for signal_struct structures (tsk->signal) */
-kmem_cache_t *signal_cachep;
+static kmem_cache_t *signal_cachep;
 
 /* SLAB cache for sighand_struct structures (tsk->sighand) */
 kmem_cache_t *sighand_cachep;
        return 0;
 }
 
+void __cleanup_signal(struct signal_struct *sig)
+{
+       exit_thread_group_keys(sig);
+       kmem_cache_free(signal_cachep, sig);
+}
+
+static inline void cleanup_signal(struct task_struct *tsk)
+{
+       struct signal_struct *sig = tsk->signal;
+
+       atomic_dec(&sig->live);
+
+       if (atomic_dec_and_test(&sig->count))
+               __cleanup_signal(sig);
+}
+
 static inline void copy_flags(unsigned long clone_flags, struct task_struct *p)
 {
        unsigned long new_flags = p->flags;
        if (p->mm)
                mmput(p->mm);
 bad_fork_cleanup_signal:
-       exit_signal(p);
+       cleanup_signal(p);
 bad_fork_cleanup_sighand:
-       if (p->sighand)
-               __exit_sighand(p);
+       __exit_sighand(p);
 bad_fork_cleanup_fs:
        exit_fs(p); /* blocking */
 bad_fork_cleanup_files:
 
        clear_tsk_thread_flag(tsk,TIF_SIGPENDING);
        flush_sigqueue(&tsk->pending);
        if (sig) {
-               /*
-                * We are cleaning up the signal_struct here.
-                */
-               exit_thread_group_keys(sig);
-               kmem_cache_free(signal_cachep, sig);
+               __cleanup_signal(sig);
        }
 }
 
-void exit_signal(struct task_struct *tsk)
-{
-       atomic_dec(&tsk->signal->live);
-
-       write_lock_irq(&tasklist_lock);
-       __exit_signal(tsk);
-       write_unlock_irq(&tasklist_lock);
-}
-
 /*
  * Flush all handlers for a task.
  */