History

fork/exit: move tty_kref_put() outside of __cleanup_signal()

tty_kref_put() has two callsites in copy_process() paths, 1. if copy_process() suceeds it is called before we copy signal->tty from parent 2. otherwise it is called from __cleanup_signal() under bad_fork_cleanup_signal: label In both cases tty_kref_put() is not right and unneeded because we don't have the balancing tty_kref_get(). Fortunately, this is harmless because this can only happen without CLONE_THREAD, and in this case signal->tty must be NULL. Remove tty_kref_put() from copy_process() and __cleanup_signal(), and change another caller of __cleanup_signal(), __exit_signal(), to call tty_kref_put() by hand. I hope this change makes sense by itself, but it is also needed to make ->signal refcountable.

Oleg Nesterov committed 16 years ago

Commit 4dec2a91 parent ffdf9182 files · +1 −2Browse files

Unified · Split

2 files
  1. kernel/exit.c +1 −0
  2. kernel/fork.c +0 −2
kernel/exit.c+1−0
@@ -149,6 +149,7 @@ static void __exit_signal(struct task_struct *tsk) · 148 unmodified lines
149149 * see account_group_exec_runtime().
150150 */
151151 task_rq_unlock_wait(tsk);
152+ tty_kref_put(sig->tty);
152153 __cleanup_signal(sig);
153154 }
154155 }
kernel/fork.c+0−2
@@ -892,7 +892,6 @@ static int copy_signal(unsigned long clone_flags, struct task_struct *tsk) · 891 unmodified lines
892892 void __cleanup_signal(struct signal_struct *sig)
893893 {
894894 thread_group_cputime_free(sig);
895− tty_kref_put(sig->tty);
896895 kmem_cache_free(signal_cachep, sig);
897896 }
898897
@@ -1263,7 +1262,6 @@ static struct task_struct *copy_process(unsigned long clone_flags, · 364 unmodified lines
12631262 p->nsproxy->pid_ns->child_reaper = p;
12641263
12651264 p->signal->leader_pid = pid;
1266− tty_kref_put(p->signal->tty);
12671265 p->signal->tty = tty_kref_get(current->signal->tty);
12681266 attach_pid(p, PIDTYPE_PGID, task_pgrp(current));
12691267 attach_pid(p, PIDTYPE_SID, task_session(current));