Skip to contentSkip to conversation

add requeue task

PATCH In review Con Kolivas 4 participants 10 messages Nov 2, 2004 – Nov 3, 2004

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 add requeue task

add requeue task

We can requeue tasks for cheaper then doing a complete dequeue followed by an enqueue. Add the requeue_task function and perform it where possible.

Change the granularity code to requeue tasks at their best priority instead of changing priority while they're running. This keeps tasks at their top interactive level during their whole timeslice.

kernel/sched.c +20 -7
Index: linux-2.6.10-rc1-mm2/kernel/sched.c
===================================================================
@@ -579,6 +579,16 @@ static void enqueue_task(struct task_str
 }
 
 /*
+ * Put task to the end of the run list without the overhead of dequeue
+ * followed by enqueue.
+ */
+static void requeue_task(struct task_struct *p, prio_array_t *array)
+{
+	list_del(&p->run_list);
+	list_add_tail(&p->run_list, array->queue + p->prio);
+}
+
+/*
  * Used by the migration code - we pull tasks from the head of the
  * remote queue so we want these tasks to show up at the head of the
  * local queue:
@@ -2425,8 +2435,7 @@ void scheduler_tick(void)
 			set_tsk_need_resched(p);
 
 			/* put it at the end of the queue: */
-			dequeue_task(p, rq->active);
-			enqueue_task(p, rq->active);
+			requeue_task(p, rq->active);
 		}
 		goto out_unlock;
 	}
@@ -2467,10 +2476,8 @@ void scheduler_tick(void)
 			(p->time_slice >= TIMESLICE_GRANULARITY(p)) &&
 			(p->array == rq->active)) {
 
-			dequeue_task(p, rq->active);
+			requeue_task(p, rq->active);
 			set_tsk_need_resched(p);
-			p->prio = effective_prio(p);
-			enqueue_task(p, rq->active);
 		}
 	}
 out_unlock:
@@ -3569,8 +3576,14 @@ asmlinkage long sys_sched_yield(void)
 	} else if (!rq->expired->nr_active)
 		schedstat_inc(rq, yld_exp_empty);
 
-	dequeue_task(current, array);
-	enqueue_task(current, target);
+	if (array != target) {
+		dequeue_task(current, array);
+		enqueue_task(current, target);
+	} else
+		/*
+		 * requeue_task is cheaper so perform that if possible.
+		 */
+		requeue_task(current, array);
 
 	/*
 	 * Since we are going to call schedule() anyway, there's
#2 lore raw
In reply to Ingo Molnar
Quoted 6 lines · Ingo Molnar
Quoted 1 line · Con Kolivas

add requeue task

Quoted 8 lines

ack for this bit, but please split this one out:

| Change the granularity code to requeue tasks at their best priority
| instead of changing priority while they're running. This keeps tasks | at their top interactive level during their whole timeslice.

this is a behavioral change and should go into the 'possible negative effect on interactivity' bucket. (of course it could very likely have a positive effect as well - the bucket is just to separate the risks.)

Actually I'd like to say I did it for positive effect to counter the change that occurred with dropping interactive credit. That was what I found in my testing, and I'd like them both to go together into -mm.

Con

#3 lore raw
Quoted 11 lines · Con Kolivas
Quoted 7 lines
| Change the granularity code to requeue tasks at their best priority
| instead of changing priority while they're running. This keeps tasks 
| at their top interactive level during their whole timeslice.

this is a behavioral change and should go into the 'possible negative effect on interactivity' bucket. (of course it could very likely have a positive effect as well - the bucket is just to separate the risks.)

Actually I'd like to say I did it for positive effect to counter the change that occurred with dropping interactive credit. That was what I found in my testing, and I'd like them both to go together into -mm.

just in case my splitout comment wasnt clear: ack for that fix too, conditional on good -mm exposure. Unlike the interactive_credit change i think this one would be borderline doable for 2.6.10 if in -mm for a couple of weeks at least, because the regression fixed by this is fresh in 2.6.9.

Ingo

#6 lore raw
In reply to Con Kolivas
Quoted 4 lines · Con Kolivas

add requeue task

Quoted 9 lines

------------------------------------------------------------------------

We can requeue tasks for cheaper then doing a complete dequeue followed by an enqueue. Add the requeue_task function and perform it where possible.

Change the granularity code to requeue tasks at their best priority instead of changing priority while they're running. This keeps tasks at their top interactive level during their whole timeslice.

I wonder... these things are all in sufficiently rarely used places, that the icache miss might be more costly than the operations saved.

But....

Quoted 35 lines

Index: linux-2.6.10-rc1-mm2/kernel/sched.c
===================================================================

kernel/sched.c +11 -2
@@ -579,6 +579,16 @@ static void enqueue_task(struct task_str
 }
 
 /*
+ * Put task to the end of the run list without the overhead of dequeue
+ * followed by enqueue.
+ */
+static void requeue_task(struct task_struct *p, prio_array_t *array)
+{
+	list_del(&p->run_list);
+	list_add_tail(&p->run_list, array->queue + p->prio);
+}
+
+/*
  * Used by the migration code - we pull tasks from the head of the
  * remote queue so we want these tasks to show up at the head of the
  * local queue:
@@ -2425,8 +2435,7 @@ void scheduler_tick(void)
 			set_tsk_need_resched(p);
 
 			/* put it at the end of the queue: */
-			dequeue_task(p, rq->active);
-			enqueue_task(p, rq->active);
+			requeue_task(p, rq->active);
 		}
 		goto out_unlock;
 	}
@@ -2467,10 +2476,8 @@ void scheduler_tick(void)
 			(p->time_slice >= TIMESLICE_GRANULARITY(p)) &&

kernel/sched.c void scheduler_tick(void) · line 2483

Quoted 10 lines
kernel/sched.c +1 -3
 			(p->array == rq->active)) {
 
-			dequeue_task(p, rq->active);
+			requeue_task(p, rq->active);
 			set_tsk_need_resched(p);
-			p->prio = effective_prio(p);
-			enqueue_task(p, rq->active);
 		}
 	}
 out_unlock:

This isn't a 1:1 transformation. Looks like the effective_prio there might be superfluous, but if so that should be a different patch.

Quoted 8 lines
kernel/sched.c +1 -2
@@ -3569,8 +3576,14 @@ asmlinkage long sys_sched_yield(void)
 	} else if (!rq->expired->nr_active)
 		schedstat_inc(rq, yld_exp_empty);
 
-	dequeue_task(current, array);
-	enqueue_task(current, target);
+	if (array != target) {

kernel/sched.c asmlinkage long sys_sched_yield(void) · line 3589

Quoted 10 lines
kernel/sched.c +7 -0
+		dequeue_task(current, array);
+		enqueue_task(current, target);
+	} else
+		/*
+		 * requeue_task is cheaper so perform that if possible.
+		 */
+		requeue_task(current, array);
 
 	/*
 	 * Since we are going to call schedule() anyway, there's

Hmm if you have to go to this trouble I'd say its not worth it. Ingo may want to weigh in though.

#1 lore raw
In reply to Con Kolivas
Quoted 1 line · Con Kolivas

add requeue task

ack for this bit, but please split this one out:

| Change the granularity code to requeue tasks at their best priority
| instead of changing priority while they're running. This keeps tasks 
| at their top interactive level during their whole timeslice.

this is a behavioral change and should go into the 'possible negative effect on interactivity' bucket. (of course it could very likely have a positive effect as well - the bucket is just to separate the risks.)

Ingo

#4 lore raw

PATCH 1/1 requeue at granularity intervals

In reply to Ingo Molnar

requeue at granularity intervals

Change the granularity code to requeue tasks at their best priority instead of changing priority while they're running. This keeps tasks at their top interactive level during their whole timeslice.

kernel/sched.c +1 -3
Index: linux-2.6.10-rc1-mm2/kernel/sched.c
===================================================================
@@ -2476,10 +2476,8 @@ void scheduler_tick(void)
 			(p->time_slice >= TIMESLICE_GRANULARITY(p)) &&
 			(p->array == rq->active)) {
 
-			dequeue_task(p, rq->active);
+			requeue_task(p, rq->active);
 			set_tsk_need_resched(p);
-			p->prio = effective_prio(p);
-			enqueue_task(p, rq->active);
 		}
 	}
 out_unlock:
#5 lore raw

PATCH 1/1 add requeue task redo

In reply to Ingo Molnar

add requeue task redo

We can requeue tasks for cheaper then doing a complete dequeue followed by an enqueue. Add the requeue_task function and perform it where possible.

kernel/sched.c +19 -4
Index: linux-2.6.10-rc1-mm2/kernel/sched.c
===================================================================
@@ -579,6 +579,16 @@ static void enqueue_task(struct task_str
 }
 
 /*
+ * Put task to the end of the run list without the overhead of dequeue
+ * followed by enqueue.
+ */
+static void requeue_task(struct task_struct *p, prio_array_t *array)
+{
+	list_del(&p->run_list);
+	list_add_tail(&p->run_list, array->queue + p->prio);
+}
+
+/*
  * Used by the migration code - we pull tasks from the head of the
  * remote queue so we want these tasks to show up at the head of the
  * local queue:
@@ -2425,8 +2435,7 @@ void scheduler_tick(void)
 			set_tsk_need_resched(p);
 
 			/* put it at the end of the queue: */
-			dequeue_task(p, rq->active);
-			enqueue_task(p, rq->active);
+			requeue_task(p, rq->active);
 		}
 		goto out_unlock;
 	}
@@ -3569,8 +3578,14 @@ asmlinkage long sys_sched_yield(void)
 	} else if (!rq->expired->nr_active)
 		schedstat_inc(rq, yld_exp_empty);
 
-	dequeue_task(current, array);
-	enqueue_task(current, target);
+	if (array != target) {
+		dequeue_task(current, array);
+		enqueue_task(current, target);
+	} else
+		/*
+		 * requeue_task is cheaper so perform that if possible.
+		 */
+		requeue_task(current, array);
 
 	/*
 	 * Since we are going to call schedule() anyway, there's
#7 lore raw
In reply to Nick Piggin
Quoted 29 lines · Nick Piggin
Quoted 4 lines · Con Kolivas

add requeue task

Quoted 9 lines

------------------------------------------------------------------------

We can requeue tasks for cheaper then doing a complete dequeue followed by an enqueue. Add the requeue_task function and perform it where possible.

Change the granularity code to requeue tasks at their best priority instead of changing priority while they're running. This keeps tasks at their top interactive level during their whole timeslice.

I wonder... these things are all in sufficiently rarely used places, that the icache miss might be more costly than the operations saved.

But....

Quoted 9 lines

Index: linux-2.6.10-rc1-mm2/kernel/sched.c
===================================================================

kernel/sched.c +0 -0
@@ -579,6 +579,16 @@ static void enqueue_task(struct task_str
 }
 
Quoted 9 lines

kernel/sched.c static void enqueue_task(struct task_str · line 589

Quoted 9 lines
kernel/sched.c +8 -0
 /*
+ * Put task to the end of the run list without the overhead of dequeue
+ * followed by enqueue.
+ */
+static void requeue_task(struct task_struct *p, prio_array_t *array)
+{
+	list_del(&p->run_list);
+	list_add_tail(&p->run_list, array->queue + p->prio);
+}

Shouldn't this be

list_move_tail(&p->run_list, array->queue + p->prio);

?

Nikita.

#8 lore raw
Quoted 16 lines · Nikita Danilov
Quoted 12 lines · Nick Piggin

kernel/sched.c static void enqueue_task(struct task_str · line 589

Quoted 11 lines · Con Kolivas

add requeue task

/*
+ * Put task to the end of the run list without the overhead of dequeue
+ * followed by enqueue.
+ */

kernel/sched.c +5 -0
+static void requeue_task(struct task_struct *p, prio_array_t *array)
+{
+	list_del(&p->run_list);
+	list_add_tail(&p->run_list, array->queue + p->prio);
+}

Shouldn't this be

Quoted 4 lines

list_move_tail(&p->run_list, array->queue + p->prio);

?

I think it should indeed.

#9 lore raw
In reply to Nikita Danilov
Quoted 8 lines · Nikita Danilov
Quoted 4 lines

kernel/sched.c static void enqueue_task(struct task_str · line 589

Quoted 3 lines · Con Kolivas
kernel/sched.c +3 -0
+	list_del(&p->run_list);
+	list_add_tail(&p->run_list, array->queue + p->prio);
+}

Shouldn't this be

list_move_tail(&p->run_list, array->queue + p->prio);

Yes indeed thanks! Fortunately they're one and the same thing. I've already resent this patch once, let akpm's tree settle for a bit before I throw more at him.

Cheers,
Con