trivial: Correct print_tainted routine name in comment
[linux-block.git] / kernel / sched_fair.c
index 280892e9d85e3543564a1397cd51ad82158f7545..990b188803ced00f8b3554bb1fe570b14b716c69 100644 (file)
@@ -513,6 +513,7 @@ static void update_curr(struct cfs_rq *cfs_rq)
        if (entity_is_task(curr)) {
                struct task_struct *curtask = task_of(curr);
 
+               trace_sched_stat_runtime(curtask, delta_exec, curr->vruntime);
                cpuacct_charge(curtask, delta_exec);
                account_group_exec_runtime(curtask, delta_exec);
        }
@@ -711,7 +712,7 @@ place_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, int initial)
 
        if (!initial) {
                /* sleeps upto a single latency don't count. */
-               if (sched_feat(NEW_FAIR_SLEEPERS)) {
+               if (sched_feat(FAIR_SLEEPERS)) {
                        unsigned long thresh = sysctl_sched_latency;
 
                        /*
@@ -725,6 +726,13 @@ place_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, int initial)
                                         task_of(se)->policy != SCHED_IDLE))
                                thresh = calc_delta_fair(thresh, se);
 
+                       /*
+                        * Halve their sleep time's effect, to allow
+                        * for a gentler effect of sleepers:
+                        */
+                       if (sched_feat(GENTLE_FAIR_SLEEPERS))
+                               thresh >>= 1;
+
                        vruntime -= thresh;
                }
        }
@@ -757,10 +765,10 @@ enqueue_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, int wakeup)
 
 static void __clear_buddies(struct cfs_rq *cfs_rq, struct sched_entity *se)
 {
-       if (cfs_rq->last == se)
+       if (!se || cfs_rq->last == se)
                cfs_rq->last = NULL;
 
-       if (cfs_rq->next == se)
+       if (!se || cfs_rq->next == se)
                cfs_rq->next = NULL;
 }
 
@@ -1241,26 +1249,11 @@ static int wake_affine(struct sched_domain *sd, struct task_struct *p, int sync)
  */
 static struct sched_group *
 find_idlest_group(struct sched_domain *sd, struct task_struct *p,
-                 int this_cpu, int flag)
+                 int this_cpu, int load_idx)
 {
        struct sched_group *idlest = NULL, *this = NULL, *group = sd->groups;
        unsigned long min_load = ULONG_MAX, this_load = 0;
        int imbalance = 100 + (sd->imbalance_pct-100)/2;
-       int load_idx = 0;
-
-       switch (flag) {
-       case SD_BALANCE_FORK:
-       case SD_BALANCE_EXEC:
-               load_idx = sd->forkexec_idx;
-               break;
-
-       case SD_BALANCE_WAKE:
-               load_idx = sd->wake_idx;
-               break;
-
-       default:
-               break;
-       }
 
        do {
                unsigned long load, avg_load;
@@ -1339,14 +1332,15 @@ find_idlest_cpu(struct sched_group *group, struct task_struct *p, int this_cpu)
  *
  * preempt must be disabled.
  */
-static int select_task_rq_fair(struct task_struct *p, int sd_flag, int flags)
+static int select_task_rq_fair(struct task_struct *p, int sd_flag, int wake_flags)
 {
-       struct sched_domain *tmp, *sd = NULL;
+       struct sched_domain *tmp, *affine_sd = NULL, *sd = NULL;
        int cpu = smp_processor_id();
        int prev_cpu = task_cpu(p);
        int new_cpu = cpu;
        int want_affine = 0;
-       int sync = flags & WF_SYNC;
+       int want_sd = 1;
+       int sync = wake_flags & WF_SYNC;
 
        if (sd_flag & SD_BALANCE_WAKE) {
                if (sched_feat(AFFINE_WAKEUPS))
@@ -1360,7 +1354,7 @@ static int select_task_rq_fair(struct task_struct *p, int sd_flag, int flags)
                 * If power savings logic is enabled for a domain, see if we
                 * are not overloaded, if so, don't balance wider.
                 */
-               if (tmp->flags & SD_POWERSAVINGS_BALANCE) {
+               if (tmp->flags & (SD_POWERSAVINGS_BALANCE|SD_PREFER_LOCAL)) {
                        unsigned long power = 0;
                        unsigned long nr_running = 0;
                        unsigned long capacity;
@@ -1373,41 +1367,51 @@ static int select_task_rq_fair(struct task_struct *p, int sd_flag, int flags)
 
                        capacity = DIV_ROUND_CLOSEST(power, SCHED_LOAD_SCALE);
 
-                       if (nr_running/2 < capacity)
-                               break;
-               }
+                       if (tmp->flags & SD_POWERSAVINGS_BALANCE)
+                               nr_running /= 2;
 
-               switch (sd_flag) {
-               case SD_BALANCE_WAKE:
-                       if (!sched_feat(LB_WAKEUP_UPDATE))
-                               break;
-               case SD_BALANCE_FORK:
-               case SD_BALANCE_EXEC:
-                       if (root_task_group_empty())
-                               break;
-                       update_shares(tmp);
-               default:
-                       break;
+                       if (nr_running < capacity)
+                               want_sd = 0;
                }
 
                if (want_affine && (tmp->flags & SD_WAKE_AFFINE) &&
                    cpumask_test_cpu(prev_cpu, sched_domain_span(tmp))) {
 
-                       if (wake_affine(tmp, p, sync)) {
-                               new_cpu = cpu;
-                               goto out;
-                       }
-
+                       affine_sd = tmp;
                        want_affine = 0;
                }
 
+               if (!want_sd && !want_affine)
+                       break;
+
                if (!(tmp->flags & sd_flag))
                        continue;
 
-               sd = tmp;
+               if (want_sd)
+                       sd = tmp;
+       }
+
+       if (sched_feat(LB_SHARES_UPDATE)) {
+               /*
+                * Pick the largest domain to update shares over
+                */
+               tmp = sd;
+               if (affine_sd && (!tmp ||
+                                 cpumask_weight(sched_domain_span(affine_sd)) >
+                                 cpumask_weight(sched_domain_span(sd))))
+                       tmp = affine_sd;
+
+               if (tmp)
+                       update_shares(tmp);
+       }
+
+       if (affine_sd && wake_affine(affine_sd, p, sync)) {
+               new_cpu = cpu;
+               goto out;
        }
 
        while (sd) {
+               int load_idx = sd->forkexec_idx;
                struct sched_group *group;
                int weight;
 
@@ -1416,7 +1420,10 @@ static int select_task_rq_fair(struct task_struct *p, int sd_flag, int flags)
                        continue;
                }
 
-               group = find_idlest_group(sd, p, cpu, sd_flag);
+               if (sd_flag & SD_BALANCE_WAKE)
+                       load_idx = sd->wake_idx;
+
+               group = find_idlest_group(sd, p, cpu, load_idx);
                if (!group) {
                        sd = sd->child;
                        continue;
@@ -1557,12 +1564,12 @@ static void set_next_buddy(struct sched_entity *se)
 /*
  * Preempt the current task with a newly woken task if needed:
  */
-static void check_preempt_wakeup(struct rq *rq, struct task_struct *p, int flags)
+static void check_preempt_wakeup(struct rq *rq, struct task_struct *p, int wake_flags)
 {
        struct task_struct *curr = rq->curr;
        struct sched_entity *se = &curr->se, *pse = &p->se;
        struct cfs_rq *cfs_rq = task_cfs_rq(curr);
-       int sync = flags & WF_SYNC;
+       int sync = wake_flags & WF_SYNC;
 
        update_curr(cfs_rq);
 
@@ -1588,7 +1595,7 @@ static void check_preempt_wakeup(struct rq *rq, struct task_struct *p, int flags
         */
        if (sched_feat(LAST_BUDDY) && likely(se->on_rq && curr != rq->idle))
                set_last_buddy(se);
-       if (sched_feat(NEXT_BUDDY) && !(flags & WF_FORK))
+       if (sched_feat(NEXT_BUDDY) && !(wake_flags & WF_FORK))
                set_next_buddy(pse);
 
        /*
@@ -1611,9 +1618,6 @@ static void check_preempt_wakeup(struct rq *rq, struct task_struct *p, int flags
                return;
        }
 
-       if (!sched_feat(WAKEUP_PREEMPT))
-               return;
-
        if ((sched_feat(WAKEUP_SYNC) && sync) ||
            (sched_feat(WAKEUP_OVERLAP) &&
             (se->avg_overlap < sysctl_sched_migration_cost &&
@@ -1622,6 +1626,17 @@ static void check_preempt_wakeup(struct rq *rq, struct task_struct *p, int flags
                return;
        }
 
+       if (sched_feat(WAKEUP_RUNNING)) {
+               if (pse->avg_running < se->avg_running) {
+                       set_next_buddy(pse);
+                       resched_task(curr);
+                       return;
+               }
+       }
+
+       if (!sched_feat(WAKEUP_PREEMPT))
+               return;
+
        find_matching_se(&se, &pse);
 
        BUG_ON(!pse);
@@ -1644,8 +1659,13 @@ static struct task_struct *pick_next_task_fair(struct rq *rq)
                /*
                 * If se was a buddy, clear it so that it will have to earn
                 * the favour again.
+                *
+                * If se was not a buddy, clear the buddies because neither
+                * was elegible to run, let them earn it again.
+                *
+                * IOW. unconditionally clear buddies.
                 */
-               __clear_buddies(cfs_rq, se);
+               __clear_buddies(cfs_rq, NULL);
                set_next_entity(cfs_rq, se);
                cfs_rq = group_cfs_rq(se);
        } while (cfs_rq);