Index: linux-2.6.9-rc1-mm1/include/linux/sched.h
===================================================================
--- linux-2.6.9-rc1-mm1.orig/include/linux/sched.h	2004-08-26 22:47:42.255970628 +1000
+++ linux-2.6.9-rc1-mm1/include/linux/sched.h	2004-08-26 22:49:58.845719985 +1000
@@ -127,9 +127,10 @@ extern unsigned long nr_iowait(void);
 #define SCHED_FIFO		1
 #define SCHED_RR		2
 #define SCHED_BATCH		3
+#define SCHED_ISO		4
 
 #define SCHED_MIN		0
-#define SCHED_MAX		3
+#define SCHED_MAX		4
 
 #define SCHED_RANGE(policy)	((policy) >= SCHED_MIN && \
 					(policy) <= SCHED_MAX)
@@ -344,6 +345,7 @@ struct signal_struct {
 
 #define rt_task(p)		(unlikely((p)->prio < MAX_RT_PRIO))
 #define batch_task(p)		((p)->policy == SCHED_BATCH)
+#define iso_task(p)		((p)->policy == SCHED_ISO)
 
 /*
  * Some day this will be a full-fledged user tracking system..
Index: linux-2.6.9-rc1-mm1/kernel/sched.c
===================================================================
--- linux-2.6.9-rc1-mm1.orig/kernel/sched.c	2004-08-26 22:49:34.503507165 +1000
+++ linux-2.6.9-rc1-mm1/kernel/sched.c	2004-08-26 22:52:01.639644924 +1000
@@ -643,6 +643,8 @@ static unsigned int burst(task_t *p)
 {
 	if (likely(!rt_task(p))) {
 		unsigned int task_user_prio = TASK_USER_PRIO(p);
+		if (iso_task(p))
+			task_user_prio /= 2;
 		return 39 - task_user_prio;
 	} else
 		return p->burst;
@@ -676,20 +678,24 @@ static unsigned int slice(task_t *p)
 	return slice;
 }
 
-/*
- * sched_interactive - sysctl which allows interactive tasks to have bursts
- */
-int sched_interactive = 1;
-
 static int rr_interval(task_t * p)
 {
 	int rr_interval = RR_INTERVAL();
-	if (unlikely(!rr_interval))
+	if (batch_task(p))
+		rr_interval *= 10;
+	else if (iso_task(p))
+		rr_interval /= 2;
+	if (!rr_interval)
 		rr_interval = 1;
 	return rr_interval;
 }
 
 /*
+ * sched_interactive - sysctl which allows interactive tasks to have bursts
+ */
+int sched_interactive = 1;
+
+/*
  * effective_prio - dynamic priority dependent on burst.
  * The priority normally decreases by one each RR_INTERVAL.
  * As the burst increases the priority stays at the top "stair" or
@@ -721,7 +727,7 @@ static int effective_prio(task_t *p)
 	if (p->burst > best_burst)
 		p->burst = best_burst;
 	first_slice = rr;
-	if (sched_interactive && !sched_compute && p->mm)
+	if (sched_interactive && !sched_compute && p->mm && !iso_task(p))
 		first_slice *= (p->burst + 1);
 	prio = MAX_PRIO - 2 - best_burst;
 
@@ -2889,7 +2895,11 @@ static int setscheduler(pid_t pid, int p
 
 	retval = -EPERM;
 	if (SCHED_RT(policy) && !capable(CAP_SYS_NICE))
-		goto out_unlock;
+		/*
+		 * If the caller requested an RT policy without having the
+		 * necessary rights, we downgrade the policy to SCHED_ISO.
+		 */
+		policy = SCHED_ISO;
 	if ((current->euid != p->euid) && (current->euid != p->uid) &&
 	    !capable(CAP_SYS_NICE))
 		goto out_unlock;
@@ -3226,6 +3236,7 @@ asmlinkage long sys_sched_get_priority_m
 		break;
 	case SCHED_NORMAL:
 	case SCHED_BATCH:
+	case SCHED_ISO:
 		ret = 0;
 		break;
 	}
@@ -3250,6 +3261,7 @@ asmlinkage long sys_sched_get_priority_m
 		break;
 	case SCHED_NORMAL:
 	case SCHED_BATCH:
+	case SCHED_ISO:
 		ret = 0;
 	}
 	return ret;
