mirror of
https://github.com/torvalds/linux.git
synced 2024-12-31 23:31:29 +00:00
deal with task_work callbacks adding more work
It doesn't matter on normal return to userland path (we'll recheck the NOTIFY_RESUME flag anyway), but in case of exit_task_work() we'll need that as soon as we get callbacks capable of triggering more task_work_add(). Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
This commit is contained in:
parent
ed3e694d78
commit
a2d4c71d15
@ -60,19 +60,21 @@ void task_work_run(void)
|
|||||||
struct task_struct *task = current;
|
struct task_struct *task = current;
|
||||||
struct callback_head *p, *q;
|
struct callback_head *p, *q;
|
||||||
|
|
||||||
raw_spin_lock_irq(&task->pi_lock);
|
while (1) {
|
||||||
p = task->task_works;
|
raw_spin_lock_irq(&task->pi_lock);
|
||||||
task->task_works = NULL;
|
p = task->task_works;
|
||||||
raw_spin_unlock_irq(&task->pi_lock);
|
task->task_works = NULL;
|
||||||
|
raw_spin_unlock_irq(&task->pi_lock);
|
||||||
|
|
||||||
if (unlikely(!p))
|
if (unlikely(!p))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
q = p->next; /* head */
|
q = p->next; /* head */
|
||||||
p->next = NULL; /* cut it */
|
p->next = NULL; /* cut it */
|
||||||
while (q) {
|
while (q) {
|
||||||
p = q->next;
|
p = q->next;
|
||||||
q->func(q);
|
q->func(q);
|
||||||
q = p;
|
q = p;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user