]> git.hungrycats.org Git - linux/commitdiff
[PATCH] "interactivity changes", sched-2.5.64-A6
authorIngo Molnar <mingo@elte.hu>
Thu, 6 Mar 2003 05:08:47 +0000 (21:08 -0800)
committerIngo Molnar <mingo@elte.hu>
Thu, 6 Mar 2003 05:08:47 +0000 (21:08 -0800)
This includes the following items:

 - a new wakeup feature: SMART_WAKE_CHILD (now unconditional) [this is a
   reworked version of the wakeup changes from Andrea's tree.]

 - scheduler parameter tunings (CHILD_PENALTY, MAX_TIMESLICE,
   STARVATION_LIMIT, MAX_SLEEP_AVG)

 - activate_task() splitup to separate the interactivity-active variant
   from the task-queue variant => this fixes our statistics in some cases.

 - finer-grained preemption: if priority is equal then the task with the
   longer pending timeslice wins.

 - make it possible to disable sync-wakeups via SYNC_WAKEUPS (default:1)

 - a naming cleanup (sleep_timestamp => last_run)

 - fix up STARVATION_LIMIT usage so that a value of 0 is recognized as 'no
   starvation limit'.

It also merges Linus' "priority boost backmerging"

include/linux/sched.h
kernel/fork.c
kernel/sched.c

index 0b325d2820011c4e5484d2cb486f071a0fefca01..d001088e58b3c718b3c49945298ecb3135b581bd 100644 (file)
@@ -328,7 +328,7 @@ struct task_struct {
        prio_array_t *array;
 
        unsigned long sleep_avg;
-       unsigned long sleep_timestamp;
+       unsigned long last_run;
 
        unsigned long policy;
        unsigned long cpus_allowed;
index 6b423ee75c9fe854e44755f9bea08f08b371ebeb..788efda26e1f56e61babdf565ced2ed4a3abe588 100644 (file)
@@ -916,7 +916,7 @@ static struct task_struct *copy_process(unsigned long clone_flags,
         */
        p->first_time_slice = 1;
        current->time_slice >>= 1;
-       p->sleep_timestamp = jiffies;
+       p->last_run = jiffies;
        if (!current->time_slice) {
                /*
                 * This case is rare, it happens when the parent has only
index ad1ac7be565a1eb8e629c45b65c7715e0363ab2e..3e56e9dd8888eec983ea19a8b053a479c2e7d1e5 100644 (file)
 /*
  * These are the 'tuning knobs' of the scheduler:
  *
- * Minimum timeslice is 10 msecs, default timeslice is 150 msecs,
- * maximum timeslice is 300 msecs. Timeslices get refilled after
+ * Minimum timeslice is 10 msecs, default timeslice is 100 msecs,
+ * maximum timeslice is 200 msecs. Timeslices get refilled after
  * they expire.
  */
 #define MIN_TIMESLICE          ( 10 * HZ / 1000)
-#define MAX_TIMESLICE          (300 * HZ / 1000)
-#define CHILD_PENALTY          95
+#define MAX_TIMESLICE          (200 * HZ / 1000)
+#define CHILD_PENALTY          50
 #define PARENT_PENALTY         100
 #define EXIT_WEIGHT            3
 #define PRIO_BONUS_RATIO       25
 #define INTERACTIVE_DELTA      2
-#define MAX_SLEEP_AVG          (2*HZ)
-#define STARVATION_LIMIT       (2*HZ)
-#define NODE_THRESHOLD          125
+#define MAX_SLEEP_AVG          (10*HZ)
+#define STARVATION_LIMIT       (10*HZ)
 
 /*
  * If a task is 'interactive' then we reinsert it in the active
@@ -323,26 +322,36 @@ static inline int effective_prio(task_t *p)
  * Also update all the scheduling statistics stuff. (sleep average
  * calculation, priority modifiers, etc.)
  */
+static inline void __activate_task(task_t *p, runqueue_t *rq)
+{
+       enqueue_task(p, rq->active);
+       rq->nr_running++;
+}
+
 static inline void activate_task(task_t *p, runqueue_t *rq)
 {
-       unsigned long sleep_time = jiffies - p->sleep_timestamp;
-       prio_array_t *array = rq->active;
+       unsigned long sleep_time = jiffies - p->last_run;
 
        if (!rt_task(p) && sleep_time) {
                /*
                 * This code gives a bonus to interactive tasks. We update
                 * an 'average sleep time' value here, based on
-                * sleep_timestamp. The more time a task spends sleeping,
+                * ->last_run. The more time a task spends sleeping,
                 * the higher the average gets - and the higher the priority
                 * boost gets as well.
                 */
                p->sleep_avg += sleep_time;
-               if (p->sleep_avg > MAX_SLEEP_AVG)
+               if (p->sleep_avg > MAX_SLEEP_AVG) {
+                       int ticks = p->sleep_avg - MAX_SLEEP_AVG + current->sleep_avg;
                        p->sleep_avg = MAX_SLEEP_AVG;
-               p->prio = effective_prio(p);
+                       if (ticks > MAX_SLEEP_AVG)
+                               ticks = MAX_SLEEP_AVG;
+                       if (!in_interrupt())
+                               current->sleep_avg = ticks;
+               }
+               p->prio = effective_prio(p);
        }
-       enqueue_task(p, array);
-       nr_running_inc(rq);
+       __activate_task(p, rq);
 }
 
 /*
@@ -479,10 +488,13 @@ repeat_lock_task:
                        }
                        if (old_state == TASK_UNINTERRUPTIBLE)
                                rq->nr_uninterruptible--;
-                       activate_task(p, rq);
-       
-                       if (p->prio < rq->curr->prio)
-                               resched_task(rq->curr);
+                       if (sync)
+                               __activate_task(p, rq);
+                       else {
+                               activate_task(p, rq);
+                               if (p->prio < rq->curr->prio)
+                                       resched_task(rq->curr);
+                       }
                        success = 1;
                }
                p->state = TASK_RUNNING;
@@ -525,8 +537,16 @@ void wake_up_forked_process(task_t * p)
                p->prio = effective_prio(p);
        }
        set_task_cpu(p, smp_processor_id());
-       activate_task(p, rq);
 
+       if (unlikely(!current->array))
+               __activate_task(p, rq);
+       else {
+               p->prio = current->prio;
+               list_add_tail(&p->run_list, &current->run_list);
+               p->array = current->array;
+               p->array->nr_active++;
+               rq->nr_running++;
+       }
        task_rq_unlock(rq, &flags);
 }
 
@@ -953,6 +973,11 @@ static inline void pull_task(runqueue_t *src_rq, prio_array_t *src_array, task_t
         */
        if (p->prio < this_rq->curr->prio)
                set_need_resched();
+       else {
+               if (p->prio == this_rq->curr->prio &&
+                               p->time_slice > this_rq->curr->time_slice)
+                       set_need_resched();
+       }
 }
 
 /*
@@ -1016,7 +1041,7 @@ skip_queue:
         */
 
 #define CAN_MIGRATE_TASK(p,rq,this_cpu)                                        \
-       ((jiffies - (p)->sleep_timestamp > cache_decay_ticks) &&        \
+       ((jiffies - (p)->last_run > cache_decay_ticks) &&       \
                !task_running(rq, p) &&                                 \
                        ((p)->cpus_allowed & (1UL << (this_cpu))))
 
@@ -1076,9 +1101,9 @@ DEFINE_PER_CPU(struct kernel_stat, kstat) = { { 0 } };
  * increasing number of running tasks:
  */
 #define EXPIRED_STARVING(rq) \
-               ((rq)->expired_timestamp && \
+               (STARVATION_LIMIT && ((rq)->expired_timestamp && \
                (jiffies - (rq)->expired_timestamp >= \
-                       STARVATION_LIMIT * ((rq)->nr_running) + 1))
+                       STARVATION_LIMIT * ((rq)->nr_running) + 1)))
 
 /*
  * This function gets called by the timer code, with HZ frequency.
@@ -1201,7 +1226,7 @@ need_resched:
        rq = this_rq();
 
        release_kernel_lock(prev);
-       prev->sleep_timestamp = jiffies;
+       prev->last_run = jiffies;
        spin_lock_irq(&rq->lock);
 
        /*
@@ -1701,7 +1726,7 @@ static int setscheduler(pid_t pid, int policy, struct sched_param *param)
        else
                p->prio = p->static_prio;
        if (array)
-               activate_task(p, task_rq(p));
+               __activate_task(p, task_rq(p));
 
 out_unlock:
        task_rq_unlock(rq, &flags);