Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6bc912b7 authored by Peter Zijlstra's avatar Peter Zijlstra Committed by Ingo Molnar
Browse files

sched: SCHED_OTHER vs SCHED_IDLE isolation



Stronger SCHED_IDLE isolation:

 - no SCHED_IDLE buddies
 - never let SCHED_IDLE preempt on wakeup
 - always preempt SCHED_IDLE on wakeup
 - limit SLEEPER fairness for SCHED_IDLE.

Signed-off-by: default avatarMike Galbraith <efault@gmx.de>
Signed-off-by: default avatarPeter Zijlstra <a.p.zijlstra@chello.nl>
Signed-off-by: default avatarIngo Molnar <mingo@elte.hu>
parent cce7ade8
Loading
Loading
Loading
Loading
+22 −8
Original line number Original line Diff line number Diff line
@@ -677,9 +677,13 @@ place_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, int initial)
			unsigned long thresh = sysctl_sched_latency;
			unsigned long thresh = sysctl_sched_latency;


			/*
			/*
			 * convert the sleeper threshold into virtual time
			 * Convert the sleeper threshold into virtual time.
			 * SCHED_IDLE is a special sub-class.  We care about
			 * fairness only relative to other SCHED_IDLE tasks,
			 * all of which have the same weight.
			 */
			 */
			if (sched_feat(NORMALIZED_SLEEPER))
			if (sched_feat(NORMALIZED_SLEEPER) &&
					task_of(se)->policy != SCHED_IDLE)
				thresh = calc_delta_fair(thresh, se);
				thresh = calc_delta_fair(thresh, se);


			vruntime -= thresh;
			vruntime -= thresh;
@@ -1340,15 +1344,19 @@ wakeup_preempt_entity(struct sched_entity *curr, struct sched_entity *se)


static void set_last_buddy(struct sched_entity *se)
static void set_last_buddy(struct sched_entity *se)
{
{
	if (likely(task_of(se)->policy != SCHED_IDLE)) {
		for_each_sched_entity(se)
		for_each_sched_entity(se)
			cfs_rq_of(se)->last = se;
			cfs_rq_of(se)->last = se;
	}
	}
}


static void set_next_buddy(struct sched_entity *se)
static void set_next_buddy(struct sched_entity *se)
{
{
	if (likely(task_of(se)->policy != SCHED_IDLE)) {
		for_each_sched_entity(se)
		for_each_sched_entity(se)
			cfs_rq_of(se)->next = se;
			cfs_rq_of(se)->next = se;
	}
	}
}


/*
/*
 * Preempt the current task with a newly woken task if needed:
 * Preempt the current task with a newly woken task if needed:
@@ -1393,11 +1401,17 @@ static void check_preempt_wakeup(struct rq *rq, struct task_struct *p, int sync)
		return;
		return;


	/*
	/*
	 * Batch tasks do not preempt (their preemption is driven by
	 * Batch and idle tasks do not preempt (their preemption is driven by
	 * the tick):
	 * the tick):
	 */
	 */
	if (unlikely(p->policy == SCHED_BATCH))
	if (unlikely(p->policy != SCHED_NORMAL))
		return;

	/* Idle tasks are by definition preempted by everybody. */
	if (unlikely(curr->policy == SCHED_IDLE)) {
		resched_task(curr);
		return;
		return;
	}


	if (!sched_feat(WAKEUP_PREEMPT))
	if (!sched_feat(WAKEUP_PREEMPT))
		return;
		return;