<html><head><meta name="color-scheme" content="light dark"></head><body><pre style="word-wrap: break-word; white-space: pre-wrap;">
From: Ingo Molnar &lt;mingo@elte.hu&gt;

* Nick Piggin &lt;nickpiggin@yahoo.com.au&gt; wrote:

&gt; Increasing priority (negative nice) doesn't have much impact. -20 CPU
&gt; hog only gets about double the CPU of a 0 priority CPU hog and only
&gt; about 120% the CPU time of a nice -10 hog.

this is a property of the base scheduler as well.

We can do a nonlinear timeslice distribution trivially - the attached
patch implements the following timeslice distribution ontop of
2.6.8-rc3-mm1:

   [ -20 ... 0 ... 19 ] =&gt; [800ms ... 100ms ... 5ms]

the nice-20/nice+19 ratio is now 1:160 - sufficient for all aspects.

Signed-off-by: Ingo Molnar &lt;mingo@elte.hu&gt;
Signed-off-by: Andrew Morton &lt;akpm@osdl.org&gt;
---

 25-akpm/kernel/sched.c |   31 ++++++++++++++-----------------
 1 files changed, 14 insertions(+), 17 deletions(-)

diff -puN kernel/sched.c~sched-nonlinear-timeslicespatch kernel/sched.c
--- 25/kernel/sched.c~sched-nonlinear-timeslicespatch	2004-08-06 02:42:28.891434632 -0700
+++ 25-akpm/kernel/sched.c	2004-08-06 02:42:28.898433568 -0700
@@ -70,8 +70,6 @@
 #define USER_PRIO(p)		((p)-MAX_RT_PRIO)
 #define TASK_USER_PRIO(p)	USER_PRIO((p)-&gt;static_prio)
 #define MAX_USER_PRIO		(USER_PRIO(MAX_PRIO))
-#define AVG_TIMESLICE	(MIN_TIMESLICE + ((MAX_TIMESLICE - MIN_TIMESLICE) *\
-			(MAX_PRIO-1-NICE_TO_PRIO(0))/(MAX_USER_PRIO - 1)))
 
 /*
  * Some helpers for converting nanosecond timing to jiffy resolution
@@ -83,11 +81,11 @@
  * These are the 'tuning knobs' of the scheduler:
  *
  * Minimum timeslice is 5 msecs (or 1 jiffy, whichever is larger),
- * default timeslice is 100 msecs, maximum timeslice is 200 msecs.
+ * default timeslice is 100 msecs, maximum timeslice is 800 msecs.
  * Timeslices get refilled after they expire.
  */
 #define MIN_TIMESLICE		max(5 * HZ / 1000, 1)
-#define MAX_TIMESLICE		(200 * HZ / 1000)
+#define DEF_TIMESLICE		(100 * HZ / 1000)
 #define ON_RUNQUEUE_WEIGHT	 30
 #define CHILD_PENALTY		 95
 #define PARENT_PENALTY		100
@@ -95,7 +93,7 @@
 #define PRIO_BONUS_RATIO	 25
 #define MAX_BONUS		(MAX_USER_PRIO * PRIO_BONUS_RATIO / 100)
 #define INTERACTIVE_DELTA	  2
-#define MAX_SLEEP_AVG		(AVG_TIMESLICE * MAX_BONUS)
+#define MAX_SLEEP_AVG		(DEF_TIMESLICE * MAX_BONUS)
 #define STARVATION_LIMIT	(MAX_SLEEP_AVG)
 #define NS_MAX_SLEEP_AVG	(JIFFIES_TO_NS(MAX_SLEEP_AVG))
 #define CREDIT_LIMIT		100
@@ -164,25 +162,24 @@
 	((p)-&gt;prio &lt; (rq)-&gt;curr-&gt;prio)
 
 /*
- * BASE_TIMESLICE scales user-nice values [ -20 ... 19 ]
- * to time slice values.
+ * task_timeslice() scales user-nice values [ -20 ... 0 ... 19 ]
+ * to time slice values: [800ms ... 100ms ... 5ms]
  *
  * The higher a thread's priority, the bigger timeslices
  * it gets during one round of execution. But even the lowest
  * priority thread gets MIN_TIMESLICE worth of execution time.
- *
- * task_timeslice() is the interface that is used by the scheduler.
  */
 
-#define BASE_TIMESLICE(p) \
-	max(MAX_TIMESLICE * (MAX_PRIO - (p)-&gt;static_prio) / (MAX_USER_PRIO), \
-		MIN_TIMESLICE)
+#define SCALE_PRIO(x, prio) \
+	max(x * (MAX_PRIO - prio) / (MAX_USER_PRIO/2), MIN_TIMESLICE)
 
 static unsigned int task_timeslice(task_t *p)
 {
-	return BASE_TIMESLICE(p);
+	if (p-&gt;static_prio &lt; NICE_TO_PRIO(0))
+		return SCALE_PRIO(DEF_TIMESLICE*4, p-&gt;static_prio);
+	else
+		return SCALE_PRIO(DEF_TIMESLICE, p-&gt;static_prio);
 }
-
 #define task_hot(p, now, sd) ((now) - (p)-&gt;timestamp &lt; (sd)-&gt;cache_hot_time)
 
 enum idle_type
@@ -793,7 +790,7 @@ static void recalc_task_prio(task_t *p, 
 		if (p-&gt;mm &amp;&amp; p-&gt;activated != -1 &amp;&amp;
 			sleep_time &gt; INTERACTIVE_SLEEP(p)) {
 				p-&gt;sleep_avg = JIFFIES_TO_NS(MAX_SLEEP_AVG -
-						AVG_TIMESLICE);
+						DEF_TIMESLICE);
 				if (!HIGH_CREDIT(p))
 					p-&gt;interactive_credit++;
 		} else {
@@ -1435,8 +1432,8 @@ void fastcall sched_exit(task_t * p)
 	rq = task_rq_lock(p-&gt;parent, &amp;flags);
 	if (p-&gt;first_time_slice) {
 		p-&gt;parent-&gt;time_slice += p-&gt;time_slice;
-		if (unlikely(p-&gt;parent-&gt;time_slice &gt; MAX_TIMESLICE))
-			p-&gt;parent-&gt;time_slice = MAX_TIMESLICE;
+		if (unlikely(p-&gt;parent-&gt;time_slice &gt; task_timeslice(p)))
+			p-&gt;parent-&gt;time_slice = task_timeslice(p);
 	}
 	if (p-&gt;sleep_avg &lt; p-&gt;parent-&gt;sleep_avg)
 		p-&gt;parent-&gt;sleep_avg = p-&gt;parent-&gt;sleep_avg /
_
</pre></body></html>