]> err.no Git - linux-2.6/blobdiff - kernel/sched.c
sched: remove the 'u64 now' parameter from inc_nr_running()
[linux-2.6] / kernel / sched.c
index 42029634ef5a4a9ef743b7631a99a5da6d5a5afa..bdb683464c0002a088b8e3e779dc1a8831e0ada2 100644 (file)
@@ -318,15 +318,19 @@ static inline int cpu_of(struct rq *rq)
 }
 
 /*
- * Per-runqueue clock, as finegrained as the platform can give us:
+ * Update the per-runqueue clock, as finegrained as the platform can give
+ * us, but without assuming monotonicity, etc.:
  */
-static unsigned long long __rq_clock(struct rq *rq)
+static void __update_rq_clock(struct rq *rq)
 {
        u64 prev_raw = rq->prev_clock_raw;
        u64 now = sched_clock();
        s64 delta = now - prev_raw;
        u64 clock = rq->clock;
 
+#ifdef CONFIG_SCHED_DEBUG
+       WARN_ON_ONCE(cpu_of(rq) != smp_processor_id());
+#endif
        /*
         * Protect against sched_clock() occasionally going backwards:
         */
@@ -349,18 +353,12 @@ static unsigned long long __rq_clock(struct rq *rq)
 
        rq->prev_clock_raw = now;
        rq->clock = clock;
-
-       return clock;
 }
 
-static inline unsigned long long rq_clock(struct rq *rq)
+static void update_rq_clock(struct rq *rq)
 {
-       int this_cpu = smp_processor_id();
-
-       if (this_cpu == cpu_of(rq))
-               return __rq_clock(rq);
-
-       return rq->clock;
+       if (likely(smp_processor_id() == cpu_of(rq)))
+               __update_rq_clock(rq);
 }
 
 /*
@@ -386,9 +384,12 @@ unsigned long long cpu_clock(int cpu)
 {
        unsigned long long now;
        unsigned long flags;
+       struct rq *rq;
 
        local_irq_save(flags);
-       now = rq_clock(cpu_rq(cpu));
+       rq = cpu_rq(cpu);
+       update_rq_clock(rq);
+       now = rq->clock;
        local_irq_restore(flags);
 
        return now;
@@ -745,8 +746,7 @@ static int balance_tasks(struct rq *this_rq, int this_cpu, struct rq *busiest,
                      unsigned long max_nr_move, unsigned long max_load_move,
                      struct sched_domain *sd, enum cpu_idle_type idle,
                      int *all_pinned, unsigned long *load_moved,
-                     int this_best_prio, int best_prio, int best_prio_seen,
-                     struct rq_iterator *iterator);
+                     int *this_best_prio, struct rq_iterator *iterator);
 
 #include "sched_stats.h"
 #include "sched_rt.c"
@@ -782,14 +782,14 @@ static void __update_curr_load(struct rq *rq, struct load_stat *ls)
  * This function is called /before/ updating rq->ls.load
  * and when switching tasks.
  */
-static void update_curr_load(struct rq *rq, u64 now)
+static void update_curr_load(struct rq *rq)
 {
        struct load_stat *ls = &rq->ls;
        u64 start;
 
        start = ls->load_update_start;
-       ls->load_update_start = now;
-       ls->delta_stat += now - start;
+       ls->load_update_start = rq->clock;
+       ls->delta_stat += rq->clock - start;
        /*
         * Stagger updates to ls->delta_fair. Very frequent updates
         * can be expensive.
@@ -798,30 +798,28 @@ static void update_curr_load(struct rq *rq, u64 now)
                __update_curr_load(rq, ls);
 }
 
-static inline void
-inc_load(struct rq *rq, const struct task_struct *p, u64 now)
+static inline void inc_load(struct rq *rq, const struct task_struct *p)
 {
-       update_curr_load(rq, now);
+       update_curr_load(rq);
        update_load_add(&rq->ls.load, p->se.load.weight);
 }
 
-static inline void
-dec_load(struct rq *rq, const struct task_struct *p, u64 now)
+static inline void dec_load(struct rq *rq, const struct task_struct *p)
 {
-       update_curr_load(rq, now);
+       update_curr_load(rq);
        update_load_sub(&rq->ls.load, p->se.load.weight);
 }
 
-static void inc_nr_running(struct task_struct *p, struct rq *rq, u64 now)
+static void inc_nr_running(struct task_struct *p, struct rq *rq)
 {
        rq->nr_running++;
-       inc_load(rq, p, now);
+       inc_load(rq, p);
 }
 
 static void dec_nr_running(struct task_struct *p, struct rq *rq, u64 now)
 {
        rq->nr_running--;
-       dec_load(rq, p, now);
+       dec_load(rq, p);
 }
 
 static void set_load_weight(struct task_struct *p)
@@ -852,14 +850,14 @@ static void
 enqueue_task(struct rq *rq, struct task_struct *p, int wakeup, u64 now)
 {
        sched_info_queued(p);
-       p->sched_class->enqueue_task(rq, p, wakeup, now);
+       p->sched_class->enqueue_task(rq, p, wakeup);
        p->se.on_rq = 1;
 }
 
 static void
 dequeue_task(struct rq *rq, struct task_struct *p, int sleep, u64 now)
 {
-       p->sched_class->dequeue_task(rq, p, sleep, now);
+       p->sched_class->dequeue_task(rq, p, sleep);
        p->se.on_rq = 0;
 }
 
@@ -914,13 +912,16 @@ static int effective_prio(struct task_struct *p)
  */
 static void activate_task(struct rq *rq, struct task_struct *p, int wakeup)
 {
-       u64 now = rq_clock(rq);
+       u64 now;
+
+       update_rq_clock(rq);
+       now = rq->clock;
 
        if (p->state == TASK_UNINTERRUPTIBLE)
                rq->nr_uninterruptible--;
 
        enqueue_task(rq, p, wakeup, now);
-       inc_nr_running(p, rq, now);
+       inc_nr_running(p, rq);
 }
 
 /*
@@ -928,22 +929,24 @@ static void activate_task(struct rq *rq, struct task_struct *p, int wakeup)
  */
 static inline void activate_idle_task(struct task_struct *p, struct rq *rq)
 {
-       u64 now = rq_clock(rq);
+       u64 now;
+
+       update_rq_clock(rq);
+       now = rq->clock;
 
        if (p->state == TASK_UNINTERRUPTIBLE)
                rq->nr_uninterruptible--;
 
        enqueue_task(rq, p, 0, now);
-       inc_nr_running(p, rq, now);
+       inc_nr_running(p, rq);
 }
 
 /*
  * deactivate_task - remove a task from the runqueue.
  */
-static void deactivate_task(struct rq *rq, struct task_struct *p, int sleep)
+static void
+deactivate_task(struct rq *rq, struct task_struct *p, int sleep, u64 now)
 {
-       u64 now = rq_clock(rq);
-
        if (p->state == TASK_UNINTERRUPTIBLE)
                rq->nr_uninterruptible++;
 
@@ -1652,7 +1655,8 @@ void fastcall wake_up_new_task(struct task_struct *p, unsigned long clone_flags)
        rq = task_rq_lock(p, &flags);
        BUG_ON(p->state != TASK_RUNNING);
        this_cpu = smp_processor_id(); /* parent's CPU */
-       now = rq_clock(rq);
+       update_rq_clock(rq);
+       now = rq->clock;
 
        p->prio = effective_prio(p);
 
@@ -1666,8 +1670,8 @@ void fastcall wake_up_new_task(struct task_struct *p, unsigned long clone_flags)
                 * Let the scheduling class do new task startup
                 * management (if any):
                 */
-               p->sched_class->task_new(rq, p, now);
-               inc_nr_running(p, rq, now);
+               p->sched_class->task_new(rq, p);
+               inc_nr_running(p, rq);
        }
        check_preempt_curr(rq, p);
        task_rq_unlock(rq, &flags);
@@ -1954,15 +1958,18 @@ static void update_cpu_load(struct rq *this_rq)
        unsigned long total_load = this_rq->ls.load.weight;
        unsigned long this_load =  total_load;
        struct load_stat *ls = &this_rq->ls;
-       u64 now = __rq_clock(this_rq);
+       u64 now;
        int i, scale;
 
+       __update_rq_clock(this_rq);
+       now = this_rq->clock;
+
        this_rq->nr_load_updates++;
        if (unlikely(!(sysctl_sched_features & SCHED_FEAT_PRECISE_CPU_LOAD)))
                goto do_avg;
 
        /* Update delta_fair/delta_exec fields first */
-       update_curr_load(this_rq, now);
+       update_curr_load(this_rq);
 
        fair_delta64 = ls->delta_fair + 1;
        ls->delta_fair = 0;
@@ -1970,8 +1977,8 @@ static void update_cpu_load(struct rq *this_rq)
        exec_delta64 = ls->delta_exec + 1;
        ls->delta_exec = 0;
 
-       sample_interval64 = now - ls->load_update_last;
-       ls->load_update_last = now;
+       sample_interval64 = this_rq->clock - ls->load_update_last;
+       ls->load_update_last = this_rq->clock;
 
        if ((s64)sample_interval64 < (s64)TICK_NSEC)
                sample_interval64 = TICK_NSEC;
@@ -2122,7 +2129,8 @@ void sched_exec(void)
 static void pull_task(struct rq *src_rq, struct task_struct *p,
                      struct rq *this_rq, int this_cpu)
 {
-       deactivate_task(src_rq, p, 0);
+       update_rq_clock(src_rq);
+       deactivate_task(src_rq, p, 0, src_rq->clock);
        set_task_cpu(p, this_cpu);
        activate_task(this_rq, p, 0);
        /*
@@ -2166,8 +2174,7 @@ static int balance_tasks(struct rq *this_rq, int this_cpu, struct rq *busiest,
                      unsigned long max_nr_move, unsigned long max_load_move,
                      struct sched_domain *sd, enum cpu_idle_type idle,
                      int *all_pinned, unsigned long *load_moved,
-                     int this_best_prio, int best_prio, int best_prio_seen,
-                     struct rq_iterator *iterator)
+                     int *this_best_prio, struct rq_iterator *iterator)
 {
        int pulled = 0, pinned = 0, skip_for_load;
        struct task_struct *p;
@@ -2192,12 +2199,8 @@ next:
         */
        skip_for_load = (p->se.load.weight >> 1) > rem_load_move +
                                                         SCHED_LOAD_SCALE_FUZZ;
-       if (skip_for_load && p->prio < this_best_prio)
-               skip_for_load = !best_prio_seen && p->prio == best_prio;
-       if (skip_for_load ||
+       if ((skip_for_load && p->prio >= *this_best_prio) ||
            !can_migrate_task(p, busiest, this_cpu, sd, idle, &pinned)) {
-
-               best_prio_seen |= p->prio == best_prio;
                p = iterator->next(iterator->arg);
                goto next;
        }
@@ -2211,8 +2214,8 @@ next:
         * and the prescribed amount of weighted load.
         */
        if (pulled < max_nr_move && rem_load_move > 0) {
-               if (p->prio < this_best_prio)
-                       this_best_prio = p->prio;
+               if (p->prio < *this_best_prio)
+                       *this_best_prio = p->prio;
                p = iterator->next(iterator->arg);
                goto next;
        }
@@ -2244,12 +2247,13 @@ static int move_tasks(struct rq *this_rq, int this_cpu, struct rq *busiest,
 {
        struct sched_class *class = sched_class_highest;
        unsigned long total_load_moved = 0;
+       int this_best_prio = this_rq->curr->prio;
 
        do {
                total_load_moved +=
                        class->load_balance(this_rq, this_cpu, busiest,
                                ULONG_MAX, max_load_move - total_load_moved,
-                               sd, idle, all_pinned);
+                               sd, idle, all_pinned, &this_best_prio);
                class = class->next;
        } while (class && max_load_move > total_load_moved);
 
@@ -2267,10 +2271,12 @@ static int move_one_task(struct rq *this_rq, int this_cpu, struct rq *busiest,
                         struct sched_domain *sd, enum cpu_idle_type idle)
 {
        struct sched_class *class;
+       int this_best_prio = MAX_PRIO;
 
        for (class = sched_class_highest; class; class = class->next)
                if (class->load_balance(this_rq, this_cpu, busiest,
-                                       1, ULONG_MAX, sd, idle, NULL))
+                                       1, ULONG_MAX, sd, idle, NULL,
+                                       &this_best_prio))
                        return 1;
 
        return 0;
@@ -3185,8 +3191,7 @@ static int balance_tasks(struct rq *this_rq, int this_cpu, struct rq *busiest,
                      unsigned long max_nr_move, unsigned long max_load_move,
                      struct sched_domain *sd, enum cpu_idle_type idle,
                      int *all_pinned, unsigned long *load_moved,
-                     int this_best_prio, int best_prio, int best_prio_seen,
-                     struct rq_iterator *iterator)
+                     int *this_best_prio, struct rq_iterator *iterator)
 {
        *load_moved = 0;
 
@@ -3212,7 +3217,8 @@ unsigned long long task_sched_runtime(struct task_struct *p)
        rq = task_rq_lock(p, &flags);
        ns = p->se.sum_exec_runtime;
        if (rq->curr == p) {
-               delta_exec = rq_clock(rq) - p->se.exec_start;
+               update_rq_clock(rq);
+               delta_exec = rq->clock - p->se.exec_start;
                if ((s64)delta_exec > 0)
                        ns += delta_exec;
        }
@@ -3392,7 +3398,7 @@ static inline void schedule_debug(struct task_struct *prev)
  * Pick up the highest-prio task:
  */
 static inline struct task_struct *
-pick_next_task(struct rq *rq, struct task_struct *prev, u64 now)
+pick_next_task(struct rq *rq, struct task_struct *prev)
 {
        struct sched_class *class;
        struct task_struct *p;
@@ -3402,14 +3408,14 @@ pick_next_task(struct rq *rq, struct task_struct *prev, u64 now)
         * the fair class we can call that function directly:
         */
        if (likely(rq->nr_running == rq->cfs.nr_running)) {
-               p = fair_sched_class.pick_next_task(rq, now);
+               p = fair_sched_class.pick_next_task(rq);
                if (likely(p))
                        return p;
        }
 
        class = sched_class_highest;
        for ( ; ; ) {
-               p = class->pick_next_task(rq, now);
+               p = class->pick_next_task(rq);
                if (p)
                        return p;
                /*
@@ -3446,13 +3452,15 @@ need_resched_nonpreemptible:
 
        spin_lock_irq(&rq->lock);
        clear_tsk_need_resched(prev);
+       __update_rq_clock(rq);
+       now = rq->clock;
 
        if (prev->state && !(preempt_count() & PREEMPT_ACTIVE)) {
                if (unlikely((prev->state & TASK_INTERRUPTIBLE) &&
                                unlikely(signal_pending(prev)))) {
                        prev->state = TASK_RUNNING;
                } else {
-                       deactivate_task(rq, prev, 1);
+                       deactivate_task(rq, prev, 1, now);
                }
                switch_count = &prev->nvcsw;
        }
@@ -3460,9 +3468,8 @@ need_resched_nonpreemptible:
        if (unlikely(!rq->nr_running))
                idle_balance(cpu, rq);
 
-       now = __rq_clock(rq);
-       prev->sched_class->put_prev_task(rq, prev, now);
-       next = pick_next_task(rq, prev, now);
+       prev->sched_class->put_prev_task(rq, prev);
+       next = pick_next_task(rq, prev);
 
        sched_info_switch(prev, next);
 
@@ -3910,7 +3917,8 @@ void rt_mutex_setprio(struct task_struct *p, int prio)
        BUG_ON(prio < 0 || prio > MAX_PRIO);
 
        rq = task_rq_lock(p, &flags);
-       now = rq_clock(rq);
+       update_rq_clock(rq);
+       now = rq->clock;
 
        oldprio = p->prio;
        on_rq = p->se.on_rq;
@@ -3957,7 +3965,8 @@ void set_user_nice(struct task_struct *p, long nice)
         * the task might be in the middle of scheduling on another CPU.
         */
        rq = task_rq_lock(p, &flags);
-       now = rq_clock(rq);
+       update_rq_clock(rq);
+       now = rq->clock;
        /*
         * The RT priorities are set via sched_setscheduler(), but we still
         * allow the 'normal' nice value to be set - but as expected
@@ -3971,7 +3980,7 @@ void set_user_nice(struct task_struct *p, long nice)
        on_rq = p->se.on_rq;
        if (on_rq) {
                dequeue_task(rq, p, 0, now);
-               dec_load(rq, p, now);
+               dec_load(rq, p);
        }
 
        p->static_prio = NICE_TO_PRIO(nice);
@@ -3982,7 +3991,7 @@ void set_user_nice(struct task_struct *p, long nice)
 
        if (on_rq) {
                enqueue_task(rq, p, 0, now);
-               inc_load(rq, p, now);
+               inc_load(rq, p);
                /*
                 * If the task increased its priority or is running and
                 * lowered its priority, then reschedule its CPU:
@@ -4219,8 +4228,10 @@ recheck:
                goto recheck;
        }
        on_rq = p->se.on_rq;
-       if (on_rq)
-               deactivate_task(rq, p, 0);
+       if (on_rq) {
+               update_rq_clock(rq);
+               deactivate_task(rq, p, 0, rq->clock);
+       }
        oldprio = p->prio;
        __setscheduler(rq, p, policy, param->sched_priority);
        if (on_rq) {
@@ -4473,10 +4484,8 @@ long sched_getaffinity(pid_t pid, cpumask_t *mask)
 out_unlock:
        read_unlock(&tasklist_lock);
        mutex_unlock(&sched_hotcpu_mutex);
-       if (retval)
-               return retval;
 
-       return 0;
+       return retval;
 }
 
 /**
@@ -4974,8 +4983,10 @@ static int __migrate_task(struct task_struct *p, int src_cpu, int dest_cpu)
                goto out;
 
        on_rq = p->se.on_rq;
-       if (on_rq)
-               deactivate_task(rq_src, p, 0);
+       if (on_rq) {
+               update_rq_clock(rq_src);
+               deactivate_task(rq_src, p, 0, rq_src->clock);
+       }
        set_task_cpu(p, dest_cpu);
        if (on_rq) {
                activate_task(rq_dest, p, 0);
@@ -5208,7 +5219,8 @@ static void migrate_dead_tasks(unsigned int dead_cpu)
        for ( ; ; ) {
                if (!rq->nr_running)
                        break;
-               next = pick_next_task(rq, rq->curr, rq_clock(rq));
+               update_rq_clock(rq);
+               next = pick_next_task(rq, rq->curr);
                if (!next)
                        break;
                migrate_dead(dead_cpu, next);
@@ -5220,12 +5232,19 @@ static void migrate_dead_tasks(unsigned int dead_cpu)
 #if defined(CONFIG_SCHED_DEBUG) && defined(CONFIG_SYSCTL)
 
 static struct ctl_table sd_ctl_dir[] = {
-       {CTL_UNNUMBERED, "sched_domain", NULL, 0, 0755, NULL, },
+       {
+               .procname       = "sched_domain",
+               .mode           = 0755,
+       },
        {0,},
 };
 
 static struct ctl_table sd_ctl_root[] = {
-       {CTL_UNNUMBERED, "kernel", NULL, 0, 0755, sd_ctl_dir, },
+       {
+               .procname       = "kernel",
+               .mode           = 0755,
+               .child          = sd_ctl_dir,
+       },
        {0,},
 };
 
@@ -5241,11 +5260,10 @@ static struct ctl_table *sd_alloc_ctl_entry(int n)
 }
 
 static void
-set_table_entry(struct ctl_table *entry, int ctl_name,
+set_table_entry(struct ctl_table *entry,
                const char *procname, void *data, int maxlen,
                mode_t mode, proc_handler *proc_handler)
 {
-       entry->ctl_name = ctl_name;
        entry->procname = procname;
        entry->data = data;
        entry->maxlen = maxlen;
@@ -5258,28 +5276,28 @@ sd_alloc_ctl_domain_table(struct sched_domain *sd)
 {
        struct ctl_table *table = sd_alloc_ctl_entry(14);
 
-       set_table_entry(&table[0], 1, "min_interval", &sd->min_interval,
+       set_table_entry(&table[0], "min_interval", &sd->min_interval,
                sizeof(long), 0644, proc_doulongvec_minmax);
-       set_table_entry(&table[1], 2, "max_interval", &sd->max_interval,
+       set_table_entry(&table[1], "max_interval", &sd->max_interval,
                sizeof(long), 0644, proc_doulongvec_minmax);
-       set_table_entry(&table[2], 3, "busy_idx", &sd->busy_idx,
+       set_table_entry(&table[2], "busy_idx", &sd->busy_idx,
                sizeof(int), 0644, proc_dointvec_minmax);
-       set_table_entry(&table[3], 4, "idle_idx", &sd->idle_idx,
+       set_table_entry(&table[3], "idle_idx", &sd->idle_idx,
                sizeof(int), 0644, proc_dointvec_minmax);
-       set_table_entry(&table[4], 5, "newidle_idx", &sd->newidle_idx,
+       set_table_entry(&table[4], "newidle_idx", &sd->newidle_idx,
                sizeof(int), 0644, proc_dointvec_minmax);
-       set_table_entry(&table[5], 6, "wake_idx", &sd->wake_idx,
+       set_table_entry(&table[5], "wake_idx", &sd->wake_idx,
                sizeof(int), 0644, proc_dointvec_minmax);
-       set_table_entry(&table[6], 7, "forkexec_idx", &sd->forkexec_idx,
+       set_table_entry(&table[6], "forkexec_idx", &sd->forkexec_idx,
                sizeof(int), 0644, proc_dointvec_minmax);
-       set_table_entry(&table[7], 8, "busy_factor", &sd->busy_factor,
+       set_table_entry(&table[7], "busy_factor", &sd->busy_factor,
                sizeof(int), 0644, proc_dointvec_minmax);
-       set_table_entry(&table[8], 9, "imbalance_pct", &sd->imbalance_pct,
+       set_table_entry(&table[8], "imbalance_pct", &sd->imbalance_pct,
                sizeof(int), 0644, proc_dointvec_minmax);
-       set_table_entry(&table[10], 11, "cache_nice_tries",
+       set_table_entry(&table[10], "cache_nice_tries",
                &sd->cache_nice_tries,
                sizeof(int), 0644, proc_dointvec_minmax);
-       set_table_entry(&table[12], 13, "flags", &sd->flags,
+       set_table_entry(&table[12], "flags", &sd->flags,
                sizeof(int), 0644, proc_dointvec_minmax);
 
        return table;
@@ -5299,7 +5317,6 @@ static ctl_table *sd_alloc_ctl_cpu_table(int cpu)
        i = 0;
        for_each_domain(cpu, sd) {
                snprintf(buf, 32, "domain%d", i);
-               entry->ctl_name = i + 1;
                entry->procname = kstrdup(buf, GFP_KERNEL);
                entry->mode = 0755;
                entry->child = sd_alloc_ctl_domain_table(sd);
@@ -5320,7 +5337,6 @@ static void init_sched_domain_sysctl(void)
 
        for (i = 0; i < cpu_num; i++, entry++) {
                snprintf(buf, 32, "cpu%d", i);
-               entry->ctl_name = i + 1;
                entry->procname = kstrdup(buf, GFP_KERNEL);
                entry->mode = 0755;
                entry->child = sd_alloc_ctl_cpu_table(i);
@@ -5389,7 +5405,8 @@ migration_call(struct notifier_block *nfb, unsigned long action, void *hcpu)
                rq->migration_thread = NULL;
                /* Idle task back to normal (off runqueue, low prio) */
                rq = task_rq_lock(rq->idle, &flags);
-               deactivate_task(rq, rq->idle, 0);
+               update_rq_clock(rq);
+               deactivate_task(rq, rq->idle, 0, rq->clock);
                rq->idle->static_prio = MAX_PRIO;
                __setscheduler(rq, rq->idle, SCHED_NORMAL, 0);
                rq->idle->sched_class = &idle_sched_class;
@@ -6627,8 +6644,10 @@ void normalize_rt_tasks(void)
 #endif
 
                on_rq = p->se.on_rq;
-               if (on_rq)
-                       deactivate_task(task_rq(p), p, 0);
+               if (on_rq) {
+                       update_rq_clock(task_rq(p));
+                       deactivate_task(task_rq(p), p, 0, task_rq(p)->clock);
+               }
                __setscheduler(rq, p, SCHED_NORMAL, 0);
                if (on_rq) {
                        activate_task(task_rq(p), p, 0);