Index: linux-2.6.9-rc3-bk8/include/linux/sched.h
===================================================================
--- linux-2.6.9-rc3-bk8.orig/include/linux/sched.h	2004-10-09 16:22:44.844209801 +1000
+++ linux-2.6.9-rc3-bk8/include/linux/sched.h	2004-10-09 16:35:53.626612563 +1000
@@ -622,6 +622,7 @@ do { if (atomic_dec_and_test(&(tsk)->usa
 #define PF_FORKED	0x00400000	/* I have just forked */
 #define PF_YIELDED	0x00800000	/* I have just yielded */
 #define PF_UISLEEP	0x01000000	/* Uninterruptible sleep */
+#define PF_PREEMPT	0x02000000	/* I have been preempted */
 
 #ifdef CONFIG_SMP
 extern int set_cpus_allowed(task_t *p, cpumask_t new_mask);
Index: linux-2.6.9-rc3-bk8/kernel/sched.c
===================================================================
--- linux-2.6.9-rc3-bk8.orig/kernel/sched.c	2004-10-09 16:22:44.843209955 +1000
+++ linux-2.6.9-rc3-bk8/kernel/sched.c	2004-10-09 16:36:22.458093098 +1000
@@ -629,7 +629,7 @@ static void enqueue_task(struct task_str
  * remote queue so we want these tasks to show up at the head of the
  * local queue:
  */
-static inline void enqueue_task_head(struct task_struct *p, runqueue_t *rq)
+static void enqueue_task_head(struct task_struct *p, runqueue_t *rq)
 {
 	list_add(&p->run_list, rq->queue + p->prio);
 	__set_bit(p->prio, rq->bitmap);
@@ -640,7 +640,10 @@ static inline void enqueue_task_head(str
  */
 static void __activate_task(task_t *p, runqueue_t *rq)
 {
-	enqueue_task(p, rq);
+	if (p->flags & PF_PREEMPT)
+		enqueue_task_head(p, rq);
+	else
+		enqueue_task(p, rq);
 	rq->nr_running++;
 }
 
@@ -806,6 +809,7 @@ static void activate_task(task_t *p, run
 static void deactivate_task(struct task_struct *p, runqueue_t *rq)
 {
 	rq->nr_running--;
+	p->flags &= ~PF_PREEMPT;
 	if (p->state == TASK_UNINTERRUPTIBLE) {
 		p->flags |= PF_UISLEEP;
 		rq->nr_uninterruptible++;
@@ -2176,6 +2180,7 @@ static void time_slice_expired(task_t *p
 	dequeue_task(p, rq);
 	p->prio = effective_prio(p);
 	p->time_slice = RR_INTERVAL();
+	p->flags &= ~PF_PREEMPT;
 	enqueue_task(p, rq);
 }
 
@@ -2500,6 +2505,7 @@ switch_tasks:
 		rq->preempted = 0;
 		rq->cache_ticks = 0;
 		next->timestamp = now;
+		next->flags |= PF_PREEMPT;
 		rq->nr_switches++;
 		rq->curr = next;
 		++*switch_count;
@@ -3238,6 +3244,7 @@ asmlinkage long sys_sched_yield(void)
 		current->flags |= PF_YIELDED;
 		current->prio = MAX_PRIO - 1;
 	}
+	current->flags &= ~PF_PREEMPT;
 	enqueue_task(current, rq);
 
 	/*

