Commit e6d3c4e5 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag 'sched_ext-for-6.14-rc4-fixes' of...

Merge tag 'sched_ext-for-6.14-rc4-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/sched_ext

Pull sched_ext fix from Tejun Heo:
 "pick_task_scx() has a workaround to avoid stalling when the fair
  class's balance() says yes but pick_task() says no.

  The workaround was incorrectly deciding to keep the prev taks running
  if the task is on SCX even when the task is in a sleeping state, which
  can lead to several confusing failure modes.

  Fix it by testing the prev task is currently queued on SCX instead"

* tag 'sched_ext-for-6.14-rc4-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/sched_ext:
  sched_ext: Fix pick_task_scx() picking non-queued tasks when it's called without balance()
parents 5394eea1 8fef0a3b
Loading
Loading
Loading
Loading
+7 −4
Original line number Diff line number Diff line
@@ -3117,7 +3117,6 @@ static struct task_struct *pick_task_scx(struct rq *rq)
{
	struct task_struct *prev = rq->curr;
	struct task_struct *p;
	bool prev_on_scx = prev->sched_class == &ext_sched_class;
	bool keep_prev = rq->scx.flags & SCX_RQ_BAL_KEEP;
	bool kick_idle = false;

@@ -3137,14 +3136,18 @@ static struct task_struct *pick_task_scx(struct rq *rq)
	 * if pick_task_scx() is called without preceding balance_scx().
	 */
	if (unlikely(rq->scx.flags & SCX_RQ_BAL_PENDING)) {
		if (prev_on_scx) {
		if (prev->scx.flags & SCX_TASK_QUEUED) {
			keep_prev = true;
		} else {
			keep_prev = false;
			kick_idle = true;
		}
	} else if (unlikely(keep_prev && !prev_on_scx)) {
		/* only allowed during transitions */
	} else if (unlikely(keep_prev &&
			    prev->sched_class != &ext_sched_class)) {
		/*
		 * Can happen while enabling as SCX_RQ_BAL_PENDING assertion is
		 * conditional on scx_enabled() and may have been skipped.
		 */
		WARN_ON_ONCE(scx_ops_enable_state() == SCX_OPS_ENABLED);
		keep_prev = false;
	}