Commit 7b3d61f6 authored by John Stultz's avatar John Stultz Committed by Peter Zijlstra
Browse files

sched: Split out __schedule() deactivate task logic into a helper



As we're going to re-use the deactivation logic,
split it into a helper.

Signed-off-by: default avatarJohn Stultz <jstultz@google.com>
Signed-off-by: default avatarPeter Zijlstra (Intel) <peterz@infradead.org>
Reviewed-by: default avatarMetin Kaya <metin.kaya@arm.com>
Reviewed-by: default avatarQais Yousef <qyousef@layalina.io>
Tested-by: default avatarK Prateek Nayak <kprateek.nayak@amd.com>
Tested-by: default avatarMetin Kaya <metin.kaya@arm.com>
Link: https://lore.kernel.org/r/20241009235352.1614323-7-jstultz@google.com
parent 18adad1d
Loading
Loading
Loading
Loading
+40 −27
Original line number Diff line number Diff line
@@ -6490,6 +6490,45 @@ pick_next_task(struct rq *rq, struct task_struct *prev, struct rq_flags *rf)
#define SM_PREEMPT		1
#define SM_RTLOCK_WAIT		2

/*
 * Helper function for __schedule()
 *
 * If a task does not have signals pending, deactivate it
 * Otherwise marks the task's __state as RUNNING
 */
static bool try_to_block_task(struct rq *rq, struct task_struct *p,
			      unsigned long task_state)
{
	int flags = DEQUEUE_NOCLOCK;

	if (signal_pending_state(task_state, p)) {
		WRITE_ONCE(p->__state, TASK_RUNNING);
		return false;
	}

	p->sched_contributes_to_load =
		(task_state & TASK_UNINTERRUPTIBLE) &&
		!(task_state & TASK_NOLOAD) &&
		!(task_state & TASK_FROZEN);

	if (unlikely(is_special_task_state(task_state)))
		flags |= DEQUEUE_SPECIAL;

	/*
	 * __schedule()			ttwu()
	 *   prev_state = prev->state;    if (p->on_rq && ...)
	 *   if (prev_state)		    goto out;
	 *     p->on_rq = 0;		  smp_acquire__after_ctrl_dep();
	 *				  p->state = TASK_WAKING
	 *
	 * Where __schedule() and ttwu() have matching control dependencies.
	 *
	 * After this, schedule() must not care about p->state any more.
	 */
	block_task(rq, p, flags);
	return true;
}

/*
 * __schedule() is the main scheduler function.
 *
@@ -6598,33 +6637,7 @@ static void __sched notrace __schedule(int sched_mode)
			goto picked;
		}
	} else if (!preempt && prev_state) {
		if (signal_pending_state(prev_state, prev)) {
			WRITE_ONCE(prev->__state, TASK_RUNNING);
		} else {
			int flags = DEQUEUE_NOCLOCK;

			prev->sched_contributes_to_load =
				(prev_state & TASK_UNINTERRUPTIBLE) &&
				!(prev_state & TASK_NOLOAD) &&
				!(prev_state & TASK_FROZEN);

			if (unlikely(is_special_task_state(prev_state)))
				flags |= DEQUEUE_SPECIAL;

			/*
			 * __schedule()			ttwu()
			 *   prev_state = prev->state;    if (p->on_rq && ...)
			 *   if (prev_state)		    goto out;
			 *     p->on_rq = 0;		  smp_acquire__after_ctrl_dep();
			 *				  p->state = TASK_WAKING
			 *
			 * Where __schedule() and ttwu() have matching control dependencies.
			 *
			 * After this, schedule() must not care about p->state any more.
			 */
			block_task(rq, prev, flags);
			block = true;
		}
		block = try_to_block_task(rq, prev, prev_state);
		switch_count = &prev->nvcsw;
	}