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 * |