diff options
| author | Al Viro <viro@zeniv.linux.org.uk> | 2012-06-27 03:31:24 -0400 |
|---|---|---|
| committer | Al Viro <viro@zeniv.linux.org.uk> | 2012-07-22 15:57:57 -0400 |
| commit | ed3e694d78cc75fa79bf29698631b146fd27aa35 (patch) | |
| tree | 97dad6768546b489a3d09c42cef0738b57f4822e /kernel/task_work.c | |
| parent | 67d1214551e800f9fe7dc7c47a346d2df0fafed5 (diff) | |
move exit_task_work() past exit_files() et.al.
... and get rid of PF_EXITING check in task_work_add().
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'kernel/task_work.c')
| -rw-r--r-- | kernel/task_work.c | 30 |
1 files changed, 11 insertions, 19 deletions
diff --git a/kernel/task_work.c b/kernel/task_work.c index 76266fb665dc..fb396089f66a 100644 --- a/kernel/task_work.c +++ b/kernel/task_work.c | |||
| @@ -5,34 +5,26 @@ | |||
| 5 | int | 5 | int |
| 6 | task_work_add(struct task_struct *task, struct callback_head *twork, bool notify) | 6 | task_work_add(struct task_struct *task, struct callback_head *twork, bool notify) |
| 7 | { | 7 | { |
| 8 | struct callback_head *last, *first; | ||
| 8 | unsigned long flags; | 9 | unsigned long flags; |
| 9 | int err = -ESRCH; | ||
| 10 | 10 | ||
| 11 | #ifndef TIF_NOTIFY_RESUME | ||
| 12 | if (notify) | ||
| 13 | return -ENOTSUPP; | ||
| 14 | #endif | ||
| 15 | /* | 11 | /* |
| 16 | * We must not insert the new work if the task has already passed | 12 | * Not inserting the new work if the task has already passed |
| 17 | * exit_task_work(). We rely on do_exit()->raw_spin_unlock_wait() | 13 | * exit_task_work() is the responisbility of callers. |
| 18 | * and check PF_EXITING under pi_lock. | ||
| 19 | */ | 14 | */ |
| 20 | raw_spin_lock_irqsave(&task->pi_lock, flags); | 15 | raw_spin_lock_irqsave(&task->pi_lock, flags); |
| 21 | if (likely(!(task->flags & PF_EXITING))) { | 16 | last = task->task_works; |
| 22 | struct callback_head *last = task->task_works; | 17 | first = last ? last->next : twork; |
| 23 | struct callback_head *first = last ? last->next : twork; | 18 | twork->next = first; |
| 24 | twork->next = first; | 19 | if (last) |
| 25 | if (last) | 20 | last->next = twork; |
| 26 | last->next = twork; | 21 | task->task_works = twork; |
| 27 | task->task_works = twork; | ||
| 28 | err = 0; | ||
| 29 | } | ||
| 30 | raw_spin_unlock_irqrestore(&task->pi_lock, flags); | 22 | raw_spin_unlock_irqrestore(&task->pi_lock, flags); |
| 31 | 23 | ||
| 32 | /* test_and_set_bit() implies mb(), see tracehook_notify_resume(). */ | 24 | /* test_and_set_bit() implies mb(), see tracehook_notify_resume(). */ |
| 33 | if (likely(!err) && notify) | 25 | if (notify) |
| 34 | set_notify_resume(task); | 26 | set_notify_resume(task); |
| 35 | return err; | 27 | return 0; |
| 36 | } | 28 | } |
| 37 | 29 | ||
| 38 | struct callback_head * | 30 | struct callback_head * |
