linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Ingo Molnar <mingo@elte.hu>
To: Linus Torvalds <torvalds@transmeta.com>
Cc: Mike Galbraith <efault@gmx.de>, Andrew Morton <akpm@digeo.com>,
	Robert Love <rml@tech9.net>, <linux-kernel@vger.kernel.org>
Subject: Re: [patch] "interactivity changes", sched-2.5.64-B2
Date: Fri, 7 Mar 2003 20:31:55 +0100 (CET)	[thread overview]
Message-ID: <Pine.LNX.4.44.0303072024220.17370-100000@localhost.localdomain> (raw)
In-Reply-To: <Pine.LNX.4.44.0303071104210.2521-100000@home.transmeta.com>


the attached patch (against your tree) fixes the SMP locking bug. The
patch also includes some other stuff i already added to my tree by that
time:

 - only update the priority and do a requeueing if the sleep average has
   changed. (this does not happen for pure CPU hogs or pure interactive
   tasks, so no need to requeue/recalc-prio in that case.) [All the 
   necessary values are available at that point already, so gcc should
   have an easy job making this branch really cheap.]

 - do not do a full task activation in the migration-thread path - that is
   supposed to be near-atomic anyway.

 - fix up comments

i solved the SMP locking bug by moving the requeueing outside of
try_to_wake_up(). It does not matter that the priority update is not
atomically done now, since the current process wont do anything inbetween.  
(well, it could get preempted in a preemptible kernel, but even that wont
do any harm.)

did a quick testcompile & testboot on an SMP box, appears to work.

	Ingo

--- linux/kernel/sched.c.orig	
+++ linux/kernel/sched.c	
@@ -321,10 +321,7 @@ static int effective_prio(task_t *p)
 }
 
 /*
- * activate_task - move a task to the runqueue.
-
- * Also update all the scheduling statistics stuff. (sleep average
- * calculation, priority modifiers, etc.)
+ * __activate_task - move a task to the runqueue.
  */
 static inline void __activate_task(task_t *p, runqueue_t *rq)
 {
@@ -332,9 +329,16 @@ static inline void __activate_task(task_
 	nr_running_inc(rq);
 }
 
-static inline void activate_task(task_t *p, runqueue_t *rq)
+/*
+ * activate_task - move a task to the runqueue and do priority recalculation
+ *
+ * Update all the scheduling statistics stuff. (sleep average
+ * calculation, priority modifiers, etc.)
+ */
+static inline int activate_task(task_t *p, runqueue_t *rq)
 {
 	unsigned long sleep_time = jiffies - p->last_run;
+	int requeue_waker = 0;
 
 	if (sleep_time) {
 		int sleep_avg;
@@ -357,23 +361,25 @@ static inline void activate_task(task_t 
 		 */
 		if (sleep_avg > MAX_SLEEP_AVG) {
 			if (!in_interrupt()) {
-				prio_array_t *array = current->array;
-				BUG_ON(!array);
 				sleep_avg += current->sleep_avg - MAX_SLEEP_AVG;
 				if (sleep_avg > MAX_SLEEP_AVG)
 					sleep_avg = MAX_SLEEP_AVG;
 
-				current->sleep_avg = sleep_avg;
-				dequeue_task(current, array);
-				current->prio = effective_prio(current);
-				enqueue_task(current, array);
+				if (current->sleep_avg != sleep_avg) {
+					current->sleep_avg = sleep_avg;
+					requeue_waker = 1;
+				}
 			}
 			sleep_avg = MAX_SLEEP_AVG;
 		}
-		p->sleep_avg = sleep_avg;
-		p->prio = effective_prio(p);
+		if (p->sleep_avg != sleep_avg) {
+			p->sleep_avg = sleep_avg;
+			p->prio = effective_prio(p);
+		}
 	}
 	__activate_task(p, rq);
+
+	return requeue_waker;
 }
 
 /*
@@ -486,8 +492,8 @@ void kick_if_running(task_t * p)
  */
 static int try_to_wake_up(task_t * p, unsigned int state, int sync)
 {
+	int success = 0, requeue_waker = 0;
 	unsigned long flags;
-	int success = 0;
 	long old_state;
 	runqueue_t *rq;
 
@@ -513,7 +519,7 @@ repeat_lock_task:
 			if (sync)
 				__activate_task(p, rq);
 			else {
-				activate_task(p, rq);
+				requeue_waker = activate_task(p, rq);
 				if (p->prio < rq->curr->prio)
 					resched_task(rq->curr);
 			}
@@ -523,6 +529,21 @@ repeat_lock_task:
 	}
 	task_rq_unlock(rq, &flags);
 
+	/*
+	 * We have to do this outside the other spinlock, the two
+	 * runqueues might be different:
+	 */
+	if (requeue_waker) {
+		prio_array_t *array;
+
+		rq = task_rq_lock(current, &flags);
+		array = current->array;
+		dequeue_task(current, array);
+		current->prio = effective_prio(current);
+		enqueue_task(current, array);
+		task_rq_unlock(rq, &flags);
+	}
+
 	return success;
 }
 
@@ -2360,7 +2381,7 @@ repeat:
 			set_task_cpu(p, cpu_dest);
 			if (p->array) {
 				deactivate_task(p, rq_src);
-				activate_task(p, rq_dest);
+				__activate_task(p, rq_dest);
 				if (p->prio < rq_dest->curr->prio)
 					resched_task(rq_dest->curr);
 			}


  parent reply	other threads:[~2003-03-07 19:21 UTC|newest]

Thread overview: 21+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <5.2.0.9.2.20030307093435.01a8fe88@pop.gmx.net>
2003-03-07  9:30 ` [patch] "HT scheduler", sched-2.5.63-B3 Ingo Molnar
     [not found] ` <Pine.LNX.4.44.0303071003060.6318-100000@localhost.localdom ain>
2003-03-07  9:38   ` Mike Galbraith
2003-03-07 10:03     ` [patch] "interactivity changes", sched-2.5.64-B2 Ingo Molnar
2003-03-07 14:45       ` Ingo Molnar
     [not found]       ` <Pine.LNX.4.44.0303071543480.12493-100000@localhost.localdo main>
2003-03-07 15:44         ` Mike Galbraith
2003-03-07 18:50           ` Ingo Molnar
2003-03-07 18:55             ` Linus Torvalds
2003-03-07 19:10             ` Linus Torvalds
2003-03-07 19:13               ` Ingo Molnar
2003-03-07 19:31               ` Ingo Molnar [this message]
     [not found]     ` <Pine.LNX.4.44.0303071049500.7326-100000@localhost.localdom ain>
2003-03-07 10:23       ` Mike Galbraith
2003-03-07 12:54         ` Mike Galbraith
2003-03-07 13:27           ` Mike Galbraith
2003-03-07 14:43             ` Ingo Molnar
2003-03-07 20:34               ` Martin Josefsson
2003-03-07 20:39                 ` Ingo Molnar
2003-03-07 21:05                   ` Martin Josefsson
2003-03-07 21:47                     ` Martin Josefsson
2003-03-07 21:03                 ` David Lang
2003-03-07 21:13                   ` Martin Josefsson
2003-03-07 23:05                     ` Helge Hafting

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=Pine.LNX.4.44.0303072024220.17370-100000@localhost.localdomain \
    --to=mingo@elte.hu \
    --cc=akpm@digeo.com \
    --cc=efault@gmx.de \
    --cc=linux-kernel@vger.kernel.org \
    --cc=rml@tech9.net \
    --cc=torvalds@transmeta.com \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).