diff options
| author | Russell King <rmk+kernel@armlinux.org.uk> | 2016-11-01 09:17:57 +0000 |
|---|---|---|
| committer | Russell King <rmk+kernel@armlinux.org.uk> | 2016-11-01 09:17:57 +0000 |
| commit | 9902aa4728fe9128ea45f1a772e2238d64d8cdc5 (patch) | |
| tree | cca30efb3ad2126fcb10aa6349ed799a5656e851 /kernel/task_work.c | |
| parent | df0bd1e8f3c508bf4c3445f94b12e38289b65f13 (diff) | |
| parent | 90731c24d2db7ec04df43ddbcee9605183d05187 (diff) | |
Merge branch 'drm-tda998x-mali' into drm-tda998x-devel
Diffstat (limited to 'kernel/task_work.c')
| -rw-r--r-- | kernel/task_work.c | 11 |
1 files changed, 6 insertions, 5 deletions
diff --git a/kernel/task_work.c b/kernel/task_work.c index 53fa971d000d..d513051fcca2 100644 --- a/kernel/task_work.c +++ b/kernel/task_work.c @@ -29,7 +29,7 @@ task_work_add(struct task_struct *task, struct callback_head *work, bool notify) struct callback_head *head; do { - head = ACCESS_ONCE(task->task_works); + head = READ_ONCE(task->task_works); if (unlikely(head == &work_exited)) return -ESRCH; work->next = head; @@ -57,6 +57,9 @@ task_work_cancel(struct task_struct *task, task_work_func_t func) struct callback_head **pprev = &task->task_works; struct callback_head *work; unsigned long flags; + + if (likely(!task->task_works)) + return NULL; /* * If cmpxchg() fails we continue without updating pprev. * Either we raced with task_work_add() which added the @@ -64,8 +67,7 @@ task_work_cancel(struct task_struct *task, task_work_func_t func) * we raced with task_work_run(), *pprev == NULL/exited. */ raw_spin_lock_irqsave(&task->pi_lock, flags); - while ((work = ACCESS_ONCE(*pprev))) { - smp_read_barrier_depends(); + while ((work = lockless_dereference(*pprev))) { if (work->func != func) pprev = &work->next; else if (cmpxchg(pprev, work, work->next) == work) @@ -95,7 +97,7 @@ void task_work_run(void) * work_exited unless the list is empty. */ do { - work = ACCESS_ONCE(task->task_works); + work = READ_ONCE(task->task_works); head = !work && (task->flags & PF_EXITING) ? &work_exited : NULL; } while (cmpxchg(&task->task_works, work, head) != work); @@ -108,7 +110,6 @@ void task_work_run(void) * fail, but it can play with *work and other entries. */ raw_spin_unlock_wait(&task->pi_lock); - smp_mb(); do { next = work->next; |
