Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 312947
b: refs/heads/master
c: ed3e694
h: refs/heads/master
i:
  312945: 91fa72c
  312943: 7a32532
v: v3
  • Loading branch information
Al Viro committed Jul 22, 2012
1 parent 4f227f3 commit 2f3bb0d
Show file tree
Hide file tree
Showing 3 changed files with 14 additions and 24 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: 67d1214551e800f9fe7dc7c47a346d2df0fafed5
refs/heads/master: ed3e694d78cc75fa79bf29698631b146fd27aa35
6 changes: 2 additions & 4 deletions trunk/kernel/exit.c
Original file line number Diff line number Diff line change
Expand Up @@ -953,14 +953,11 @@ void do_exit(long code)
exit_signals(tsk); /* sets PF_EXITING */
/*
* tsk->flags are checked in the futex code to protect against
* an exiting task cleaning up the robust pi futexes, and in
* task_work_add() to avoid the race with exit_task_work().
* an exiting task cleaning up the robust pi futexes.
*/
smp_mb();
raw_spin_unlock_wait(&tsk->pi_lock);

exit_task_work(tsk);

if (unlikely(in_atomic()))
printk(KERN_INFO "note: %s[%d] exited with preempt_count %d\n",
current->comm, task_pid_nr(current),
Expand Down Expand Up @@ -995,6 +992,7 @@ void do_exit(long code)
exit_shm(tsk);
exit_files(tsk);
exit_fs(tsk);
exit_task_work(tsk);
check_stack_usage();
exit_thread();

Expand Down
30 changes: 11 additions & 19 deletions trunk/kernel/task_work.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,34 +5,26 @@
int
task_work_add(struct task_struct *task, struct callback_head *twork, bool notify)
{
struct callback_head *last, *first;
unsigned long flags;
int err = -ESRCH;

#ifndef TIF_NOTIFY_RESUME
if (notify)
return -ENOTSUPP;
#endif
/*
* We must not insert the new work if the task has already passed
* exit_task_work(). We rely on do_exit()->raw_spin_unlock_wait()
* and check PF_EXITING under pi_lock.
* Not inserting the new work if the task has already passed
* exit_task_work() is the responisbility of callers.
*/
raw_spin_lock_irqsave(&task->pi_lock, flags);
if (likely(!(task->flags & PF_EXITING))) {
struct callback_head *last = task->task_works;
struct callback_head *first = last ? last->next : twork;
twork->next = first;
if (last)
last->next = twork;
task->task_works = twork;
err = 0;
}
last = task->task_works;
first = last ? last->next : twork;
twork->next = first;
if (last)
last->next = twork;
task->task_works = twork;
raw_spin_unlock_irqrestore(&task->pi_lock, flags);

/* test_and_set_bit() implies mb(), see tracehook_notify_resume(). */
if (likely(!err) && notify)
if (notify)
set_notify_resume(task);
return err;
return 0;
}

struct callback_head *
Expand Down

0 comments on commit 2f3bb0d

Please sign in to comment.