All of lore.kernel.org
 help / color / mirror / Atom feed
From: Mike Galbraith <efault@gmx.de>
To: Brian Rogers <brian@xyzw.org>
Cc: Ingo Molnar <mingo@elte.hu>,
	linux-kernel@vger.kernel.org,
	Peter Zijlstra <a.p.zijlstra@chello.nl>
Subject: Re: [BUG] How to get real-time priority using idle priority
Date: Wed, 14 Jan 2009 06:13:34 +0100	[thread overview]
Message-ID: <1231910014.610.14.camel@marge.simson.net> (raw)
In-Reply-To: <1231815523.5899.7.camel@marge.simson.net>

On Tue, 2009-01-13 at 03:58 +0100, Mike Galbraith wrote:
> On Mon, 2009-01-12 at 17:05 -0800, Brian Rogers wrote:

> > I'll try Mike's "more complete" patch on top of 2.6.29-rc1 and see what 
> > that does.
> 
> Don't bother.  I just tried a SCHED_IDLE make -j8 and had character
> repeats while typing.  Must be another spot.

Hrmph, what an annoying problem.  The below works pretty well, but
_still_ has latency problems in some circumstances.

The more I look at this, the more I think these guys _really_ want to be
a separate class.  The problem is the incredible rate of min_vruntime
advancement creating absurdly huge spreads.

Hm, maybe I could advance min_vruntime at nice 0 when these guys are
running, only advance their vruntime at warp 512, but that seems awfully
hackish.  If they were a separate class, they could use the full nice
spectrum instead of being merely mega-nice.

diff --git a/kernel/sched.c b/kernel/sched.c
index deb5ac8..5221515 100644
--- a/kernel/sched.c
+++ b/kernel/sched.c
@@ -1888,8 +1888,29 @@ void set_task_cpu(struct task_struct *p, unsigned int new_cpu)
 			schedstat_inc(p, se.nr_forced2_migrations);
 	}
 #endif
-	p->se.vruntime -= old_cfsrq->min_vruntime -
-					 new_cfsrq->min_vruntime;
+	if (old_cpu != new_cpu) {
+		u64 vruntime, min_vruntime;
+		s64 delta = p->se.vruntime - old_cfsrq->min_vruntime;
+
+		/*
+		 * min_vruntimes may be advancing at wildly different
+		 * rates, so we must scale the delta accordingly.
+		 */
+		if (new_cfsrq->load.weight != old_cfsrq->load.weight) {
+			int negative = delta < 0;
+
+			delta = negative ? -delta : delta;
+			delta = calc_delta_mine(delta,
+				new_cfsrq->load.weight, &old_cfsrq->load);
+			delta = negative ? -delta : delta;
+		}
+		vruntime = new_cfsrq->min_vruntime + delta;
+		min_vruntime = new_cfsrq->min_vruntime - sysctl_sched_latency;
+		delta = (s64)(vruntime - min_vruntime);
+		if (delta > 0)
+			min_vruntime = vruntime;
+		p->se.vruntime = min_vruntime;
+	}
 
 	__set_task_cpu(p, new_cpu);
 }
diff --git a/kernel/sched_fair.c b/kernel/sched_fair.c
index 8e1352c..b18658f 100644
--- a/kernel/sched_fair.c
+++ b/kernel/sched_fair.c
@@ -673,7 +673,8 @@ place_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, int initial)
 
 	if (!initial) {
 		/* sleeps upto a single latency don't count. */
-		if (sched_feat(NEW_FAIR_SLEEPERS)) {
+		if (sched_feat(NEW_FAIR_SLEEPERS) &&
+				task_of(se)->policy != SCHED_IDLE) {
 			unsigned long thresh = sysctl_sched_latency;
 
 			/*
@@ -793,6 +794,10 @@ set_next_entity(struct cfs_rq *cfs_rq, struct sched_entity *se)
 	}
 #endif
 	se->prev_sum_exec_runtime = se->sum_exec_runtime;
+
+	/* Idle tasks reach parity as soon as they get a chance to run. */
+	if (unlikely(task_of(se)->policy == SCHED_IDLE))
+		se->vruntime = cfs_rq->min_vruntime;
 }
 
 static int
@@ -1340,14 +1345,18 @@ wakeup_preempt_entity(struct sched_entity *curr, struct sched_entity *se)
 
 static void set_last_buddy(struct sched_entity *se)
 {
-	for_each_sched_entity(se)
-		cfs_rq_of(se)->last = se;
+	for_each_sched_entity(se) {
+		if (likely(task_of(se)->policy != SCHED_IDLE))
+			cfs_rq_of(se)->last = se;
+	}
 }
 
 static void set_next_buddy(struct sched_entity *se)
 {
-	for_each_sched_entity(se)
-		cfs_rq_of(se)->next = se;
+	for_each_sched_entity(se) {
+		if (likely(task_of(se)->policy != SCHED_IDLE))
+			cfs_rq_of(se)->next = se;
+	}
 }
 
 /*
@@ -1393,12 +1402,18 @@ static void check_preempt_wakeup(struct rq *rq, struct task_struct *p, int sync)
 		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):
 	 */
-	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;
+	}
+
 	if (!sched_feat(WAKEUP_PREEMPT))
 		return;
 



  reply	other threads:[~2009-01-14  5:13 UTC|newest]

Thread overview: 24+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-01-11 10:58 [BUG] How to get real-time priority using idle priority Brian Rogers
2009-01-12  5:09 ` Mike Galbraith
2009-01-12 13:03   ` Mike Galbraith
2009-01-12 13:14     ` Ingo Molnar
2009-01-12 15:23       ` Mike Galbraith
2009-01-12 15:24         ` Ingo Molnar
2009-01-13  1:05       ` Brian Rogers
2009-01-13  2:58         ` Mike Galbraith
2009-01-14  5:13           ` Mike Galbraith [this message]
2009-01-14  5:31             ` Ingo Molnar
2009-01-14  6:02               ` Mike Galbraith
2009-01-14  7:35                 ` Ingo Molnar
2009-01-15  9:28         ` Mike Galbraith
2009-01-15 10:14           ` Peter Zijlstra
2009-01-15 10:30             ` Mike Galbraith
2009-01-15 11:37               ` Mike Galbraith
2009-01-15 11:41                 ` Peter Zijlstra
2009-01-15 12:54                   ` Ingo Molnar
2009-01-15 13:05                     ` Peter Zijlstra
2009-01-15 13:15                       ` Ingo Molnar
2009-01-15 13:16                     ` Peter Zijlstra
2009-01-15 12:07           ` Brian Rogers
2009-01-12 20:46     ` [patch take 2] " Mike Galbraith
2009-01-12 20:50       ` Mike Galbraith

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1231910014.610.14.camel@marge.simson.net \
    --to=efault@gmx.de \
    --cc=a.p.zijlstra@chello.nl \
    --cc=brian@xyzw.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mingo@elte.hu \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.