Commit 534b2904 authored by Thomas Gleixner's avatar Thomas Gleixner Committed by Sebastian Andrzej Siewior
Browse files

sched: Prevent balance_push() on remote runqueues

sched_setscheduler() and rt_mutex_setprio() invoke the run-queue balance
callback after changing priorities or the scheduling class of a task. The
run-queue for which the callback is invoked can be local or remote.

That's not a problem for the regular rq::push_work which is serialized with
a busy flag in the run-queue struct, but for the balance_push() work which
is only valid to be invoked on the outgoing CPU that's wrong. It not only
triggers the debug warning, but also leaves the per CPU variable push_work
unprotected, which can result in double enqueues on the stop machine list.

Remove the warning and check that the function is invoked on the
outgoing CPU. If not, just return and do nothing.

Fixes: ae792702

 ("sched: Optimize finish_lock_switch()")
Reported-by: default avatarSebastian Siewior <bigeasy@linutronix.de>
Signed-off-by: default avatarThomas Gleixner <tglx@linutronix.de>
Cc: stable@vger.kernel.org
Signed-off-by: default avatarSebastian Andrzej Siewior <bigeasy@linutronix.de>
Link: https://lore.kernel.org/r/87tujb0yn1.ffs@tglx
parent bbd94800
......@@ -8588,7 +8588,6 @@ static void balance_push(struct rq *rq)
struct task_struct *push_task = rq->curr;
lockdep_assert_rq_held(rq);
SCHED_WARN_ON(rq->cpu != smp_processor_id());
/*
* Ensure the thing is persistent until balance_push_set(.on = false);
......@@ -8596,9 +8595,10 @@ static void balance_push(struct rq *rq)
rq->balance_callback = &balance_push_callback;
/*
* Only active while going offline.
* Only active while going offline and when invoked on the outgoing
* CPU.
*/
if (!cpu_dying(rq->cpu))
if (!cpu_dying(rq->cpu) && rq == this_rq())
return;
/*
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment