diff options
author | Ingo Molnar <mingo@kernel.org> | 2019-02-11 08:01:50 +0100 |
---|---|---|
committer | Ingo Molnar <mingo@kernel.org> | 2019-02-11 08:01:50 +0100 |
commit | c9ba7560c550fe6c1f4a8f0666bea41d2a349d1d (patch) | |
tree | b15d53e69f73b160b4625e91187cd436c5a3e683 /kernel/sched/core.c | |
parent | f6783319737f28e4436a69611853a5a098cbe974 (diff) | |
parent | d13937116f1e82bf508a6325111b322c30c85eb9 (diff) | |
download | linux-c9ba7560c550fe6c1f4a8f0666bea41d2a349d1d.tar.bz2 |
Merge tag 'v5.0-rc6' into sched/core, to pick up fixes
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'kernel/sched/core.c')
-rw-r--r-- | kernel/sched/core.c | 19 |
1 files changed, 16 insertions, 3 deletions
diff --git a/kernel/sched/core.c b/kernel/sched/core.c index ec1b67a195cc..e86e2b8f6922 100644 --- a/kernel/sched/core.c +++ b/kernel/sched/core.c @@ -398,6 +398,18 @@ static bool set_nr_if_polling(struct task_struct *p) #endif #endif +/** + * wake_q_add() - queue a wakeup for 'later' waking. + * @head: the wake_q_head to add @task to + * @task: the task to queue for 'later' wakeup + * + * Queue a task for later wakeup, most likely by the wake_up_q() call in the + * same context, _HOWEVER_ this is not guaranteed, the wakeup can come + * instantly. + * + * This function must be used as-if it were wake_up_process(); IOW the task + * must be ready to be woken at this location. + */ void wake_q_add(struct wake_q_head *head, struct task_struct *task) { struct wake_q_node *node = &task->wake_q; @@ -407,10 +419,11 @@ void wake_q_add(struct wake_q_head *head, struct task_struct *task) * its already queued (either by us or someone else) and will get the * wakeup due to that. * - * This cmpxchg() executes a full barrier, which pairs with the full - * barrier executed by the wakeup in wake_up_q(). + * In order to ensure that a pending wakeup will observe our pending + * state, even in the failed case, an explicit smp_mb() must be used. */ - if (cmpxchg(&node->next, NULL, WAKE_Q_TAIL)) + smp_mb__before_atomic(); + if (cmpxchg_relaxed(&node->next, NULL, WAKE_Q_TAIL)) return; get_task_struct(task); |