Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 84650
b: refs/heads/master
c: ee7c82d
h: refs/heads/master
v: v3
  • Loading branch information
Oleg Nesterov authored and Linus Torvalds committed Feb 8, 2008
1 parent 2023f2b commit 5a6df83
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 63 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 6405f7f4675884b671bee66678e1c2859bdb0e56
refs/heads/master: ee7c82da830ea860b1f9274f1f0cdf99f206e7c2
88 changes: 26 additions & 62 deletions trunk/kernel/exit.c
Original file line number Diff line number Diff line change
Expand Up @@ -1355,17 +1355,35 @@ static int wait_task_stopped(struct task_struct *p, int delayed_group_leader,
int noreap, struct siginfo __user *infop,
int __user *stat_addr, struct rusage __user *ru)
{
int retval, exit_code;
int retval, exit_code, why;
uid_t uid = 0; /* unneeded, required by compiler */
pid_t pid;

if (!p->exit_code)
return 0;
exit_code = 0;
spin_lock_irq(&p->sighand->siglock);

if (unlikely(!task_is_stopped_or_traced(p)))
goto unlock_sig;

if (delayed_group_leader && !(p->ptrace & PT_PTRACED) &&
p->signal->group_stop_count > 0)
/*
* A group stop is in progress and this is the group leader.
* We won't report until all threads have stopped.
*/
goto unlock_sig;

exit_code = p->exit_code;
if (!exit_code)
goto unlock_sig;

if (!noreap)
p->exit_code = 0;

uid = p->uid;
unlock_sig:
spin_unlock_irq(&p->sighand->siglock);
if (!exit_code)
return 0;

/*
Expand All @@ -1375,65 +1393,15 @@ static int wait_task_stopped(struct task_struct *p, int delayed_group_leader,
* keep holding onto the tasklist_lock while we call getrusage and
* possibly take page faults for user memory.
*/
pid = task_pid_nr_ns(p, current->nsproxy->pid_ns);
get_task_struct(p);
pid = task_pid_nr_ns(p, current->nsproxy->pid_ns);
why = (p->ptrace & PT_PTRACED) ? CLD_TRAPPED : CLD_STOPPED;
read_unlock(&tasklist_lock);

if (unlikely(noreap)) {
uid_t uid = p->uid;
int why = (p->ptrace & PT_PTRACED) ? CLD_TRAPPED : CLD_STOPPED;

exit_code = p->exit_code;
if (unlikely(!exit_code) || unlikely(p->exit_state))
goto bail_ref;
if (unlikely(noreap))
return wait_noreap_copyout(p, pid, uid,
why, exit_code,
infop, ru);
}

write_lock_irq(&tasklist_lock);

/*
* This uses xchg to be atomic with the thread resuming and setting
* it. It must also be done with the write lock held to prevent a
* race with the EXIT_ZOMBIE case.
*/
exit_code = xchg(&p->exit_code, 0);
if (unlikely(p->exit_state)) {
/*
* The task resumed and then died. Let the next iteration
* catch it in EXIT_ZOMBIE. Note that exit_code might
* already be zero here if it resumed and did _exit(0).
* The task itself is dead and won't touch exit_code again;
* other processors in this function are locked out.
*/
p->exit_code = exit_code;
exit_code = 0;
}
if (unlikely(exit_code == 0)) {
/*
* Another thread in this function got to it first, or it
* resumed, or it resumed and then died.
*/
write_unlock_irq(&tasklist_lock);
bail_ref:
put_task_struct(p);
/*
* We are returning to the wait loop without having successfully
* removed the process and having released the lock. We cannot
* continue, since the "p" task pointer is potentially stale.
*
* Return -EAGAIN, and do_wait() will restart the loop from the
* beginning. Do _not_ re-acquire the lock.
*/
return -EAGAIN;
}

/* move to end of parent's list to avoid starvation */
remove_parent(p);
add_parent(p);

write_unlock_irq(&tasklist_lock);

retval = ru ? getrusage(p, RUSAGE_BOTH, ru) : 0;
if (!retval && stat_addr)
Expand All @@ -1443,15 +1411,13 @@ static int wait_task_stopped(struct task_struct *p, int delayed_group_leader,
if (!retval && infop)
retval = put_user(0, &infop->si_errno);
if (!retval && infop)
retval = put_user((short)((p->ptrace & PT_PTRACED)
? CLD_TRAPPED : CLD_STOPPED),
&infop->si_code);
retval = put_user(why, &infop->si_code);
if (!retval && infop)
retval = put_user(exit_code, &infop->si_status);
if (!retval && infop)
retval = put_user(pid, &infop->si_pid);
if (!retval && infop)
retval = put_user(p->uid, &infop->si_uid);
retval = put_user(uid, &infop->si_uid);
if (!retval)
retval = pid;
put_task_struct(p);
Expand Down Expand Up @@ -1558,8 +1524,6 @@ static long do_wait(pid_t pid, int options, struct siginfo __user *infop,
retval = wait_task_stopped(p, ret == 2,
(options & WNOWAIT), infop,
stat_addr, ru);
if (retval == -EAGAIN)
goto repeat;
if (retval != 0) /* He released the lock. */
goto end;
} else if (p->exit_state == EXIT_ZOMBIE) {
Expand Down

0 comments on commit 5a6df83

Please sign in to comment.