diff -Nru linux-2.5.74.vanilla/include/linux/sched.h linux-2.5.74.mod/include/linux/sched.h
--- linux-2.5.74.vanilla/include/linux/sched.h	Mon Jul  7 16:57:33 2003
+++ linux-2.5.74.mod/include/linux/sched.h	Wed Jul  9 17:07:02 2003
@@ -124,6 +124,8 @@
 #define SCHED_NORMAL		0
 #define SCHED_FIFO		1
 #define SCHED_RR		2
+#define SCHED_SOFTRR		3
+
 
 struct sched_param {
 	int sched_priority;
@@ -343,6 +345,7 @@
 	unsigned long policy;
 	unsigned long cpus_allowed;
 	unsigned int time_slice, first_time_slice;
+	unsigned long ts_timestamp;
 
 	struct list_head tasks;
 	struct list_head ptrace_children;
diff -Nru linux-2.5.74.vanilla/kernel/sched.c linux-2.5.74.mod/kernel/sched.c
--- linux-2.5.74.vanilla/kernel/sched.c	Mon Jul  7 16:57:33 2003
+++ linux-2.5.74.mod/kernel/sched.c	Wed Jul  9 17:42:00 2003
@@ -76,6 +76,7 @@
 #define MAX_SLEEP_AVG		(10*HZ)
 #define STARVATION_LIMIT	(10*HZ)
 #define NODE_THRESHOLD		125
+#define SCHED_TS_KSOFTRR	8
 
 /*
  * If a task is 'interactive' then we reinsert it in the active
@@ -1175,6 +1176,7 @@
 void scheduler_tick(int user_ticks, int sys_ticks)
 {
 	int cpu = smp_processor_id();
+	unsigned int time_slice;
 	runqueue_t *rq = this_rq();
 	task_t *p = current;
 
@@ -1219,14 +1221,29 @@
 		 * RR tasks need a special form of timeslice management.
 		 * FIFO tasks have no timeslices.
 		 */
-		if ((p->policy == SCHED_RR) && !--p->time_slice) {
-			p->time_slice = task_timeslice(p);
+		if ((p->policy == SCHED_RR || p->policy == SCHED_SOFTRR) &&
+		    !--p->time_slice) {
+			p->time_slice = time_slice = task_timeslice(p);
 			p->first_time_slice = 0;
 			set_tsk_need_resched(p);
 
-			/* put it at the end of the queue: */
+			/*
+			 * We rotate SCHED_RR like POSIX states. On the
+			 * contrary, SCHED_SOFTRR are real-time tasks without
+			 * attitude and we do not want them to starve other
+			 * tasks while we want them to be able to preempt
+			 * SCHED_NORMAL tasks. The rule is that SCHED_SOFTRR
+			 * will be expired if they require roughly more then
+			 * 1/SCHED_TS_KSOFTRR percent of CPU time.
+			 */
 			dequeue_task(p, rq->active);
-			enqueue_task(p, rq->active);
+			if (p->policy == SCHED_RR ||
+			    (jiffies - p->ts_timestamp) > SCHED_TS_KSOFTRR * time_slice)
+				enqueue_task(p, rq->active);
+			else
+				enqueue_task(p, rq->expired);
+
+			p->ts_timestamp = jiffies;
 		}
 		goto out_unlock;
 	}
@@ -1243,6 +1260,8 @@
 			enqueue_task(p, rq->expired);
 		} else
 			enqueue_task(p, rq->active);
+
+		p->ts_timestamp = jiffies;
 	}
 out_unlock:
 	spin_unlock(&rq->lock);
@@ -1740,9 +1759,14 @@
 	else {
 		retval = -EINVAL;
 		if (policy != SCHED_FIFO && policy != SCHED_RR &&
-				policy != SCHED_NORMAL)
+				policy != SCHED_NORMAL && policy != SCHED_SOFTRR)
 			goto out_unlock;
 	}
+
+#if 1
+	if (policy == SCHED_RR && !capable(CAP_SYS_NICE))
+		policy = SCHED_SOFTRR;
+#endif
 
 	/*
 	 * Valid priorities for SCHED_FIFO and SCHED_RR are
