update_load_sub(&rq->load, load);
 }
 
+#ifdef CONFIG_SMP
+static unsigned long source_load(int cpu, int type);
+static unsigned long target_load(int cpu, int type);
+static unsigned long cpu_avg_load_per_task(int cpu);
+static int task_hot(struct task_struct *p, u64 now, struct sched_domain *sd);
+#endif /* CONFIG_SMP */
+
 #include "sched_stats.h"
 #include "sched_idletask.c"
 #include "sched_fair.c"
 /*
  * Is this task likely cache-hot:
  */
-static inline int
+static int
 task_hot(struct task_struct *p, u64 now, struct sched_domain *sd)
 {
        s64 delta;
 /*
  * Return the average load per task on the cpu's run queue
  */
-static inline unsigned long cpu_avg_load_per_task(int cpu)
+static unsigned long cpu_avg_load_per_task(int cpu)
 {
        struct rq *rq = cpu_rq(cpu);
        unsigned long total = weighted_cpuload(cpu);
 
 #endif /* CONFIG_SMP */
 
-/*
- * wake_idle() will wake a task on an idle cpu if task->cpu is
- * not idle and an idle cpu is available.  The span of cpus to
- * search starts with cpus closest then further out as needed,
- * so we always favor a closer, idle cpu.
- *
- * Returns the CPU we should wake onto.
- */
-#if defined(ARCH_HAS_SCHED_WAKE_IDLE)
-static int wake_idle(int cpu, struct task_struct *p)
-{
-       cpumask_t tmp;
-       struct sched_domain *sd;
-       int i;
-
-       /*
-        * If it is idle, then it is the best cpu to run this task.
-        *
-        * This cpu is also the best, if it has more than one task already.
-        * Siblings must be also busy(in most cases) as they didn't already
-        * pickup the extra load from this cpu and hence we need not check
-        * sibling runqueue info. This will avoid the checks and cache miss
-        * penalities associated with that.
-        */
-       if (idle_cpu(cpu) || cpu_rq(cpu)->nr_running > 1)
-               return cpu;
-
-       for_each_domain(cpu, sd) {
-               if (sd->flags & SD_WAKE_IDLE) {
-                       cpus_and(tmp, sd->span, p->cpus_allowed);
-                       for_each_cpu_mask(i, tmp) {
-                               if (idle_cpu(i)) {
-                                       if (i != task_cpu(p)) {
-                                               schedstat_inc(p,
-                                                       se.nr_wakeups_idle);
-                                       }
-                                       return i;
-                               }
-                       }
-               } else {
-                       break;
-               }
-       }
-       return cpu;
-}
-#else
-static inline int wake_idle(int cpu, struct task_struct *p)
-{
-       return cpu;
-}
-#endif
-
 /***
  * try_to_wake_up - wake up a thread
  * @p: the to-be-woken-up thread
        long old_state;
        struct rq *rq;
 #ifdef CONFIG_SMP
-       struct sched_domain *sd, *this_sd = NULL;
-       unsigned long load, this_load;
        int new_cpu;
 #endif
 
        if (unlikely(task_running(rq, p)))
                goto out_activate;
 
-       new_cpu = cpu;
-
-       schedstat_inc(rq, ttwu_count);
-       if (cpu == this_cpu) {
-               schedstat_inc(rq, ttwu_local);
-               goto out_set_cpu;
-       }
-
-       for_each_domain(this_cpu, sd) {
-               if (cpu_isset(cpu, sd->span)) {
-                       schedstat_inc(sd, ttwu_wake_remote);
-                       this_sd = sd;
-                       break;
-               }
-       }
-
-       if (unlikely(!cpu_isset(this_cpu, p->cpus_allowed)))
-               goto out_set_cpu;
-
-       /*
-        * Check for affine wakeup and passive balancing possibilities.
-        */
-       if (this_sd) {
-               int idx = this_sd->wake_idx;
-               unsigned int imbalance;
-
-               imbalance = 100 + (this_sd->imbalance_pct - 100) / 2;
-
-               load = source_load(cpu, idx);
-               this_load = target_load(this_cpu, idx);
-
-               new_cpu = this_cpu; /* Wake to this CPU if we can */
-
-               if (this_sd->flags & SD_WAKE_AFFINE) {
-                       unsigned long tl = this_load;
-                       unsigned long tl_per_task;
-
-                       /*
-                        * Attract cache-cold tasks on sync wakeups:
-                        */
-                       if (sync && !task_hot(p, rq->clock, this_sd))
-                               goto out_set_cpu;
-
-                       schedstat_inc(p, se.nr_wakeups_affine_attempts);
-                       tl_per_task = cpu_avg_load_per_task(this_cpu);
-
-                       /*
-                        * If sync wakeup then subtract the (maximum possible)
-                        * effect of the currently running task from the load
-                        * of the current CPU:
-                        */
-                       if (sync)
-                               tl -= current->se.load.weight;
-
-                       if ((tl <= load &&
-                               tl + target_load(cpu, idx) <= tl_per_task) ||
-                              100*(tl + p->se.load.weight) <= imbalance*load) {
-                               /*
-                                * This domain has SD_WAKE_AFFINE and
-                                * p is cache cold in this domain, and
-                                * there is no bad imbalance.
-                                */
-                               schedstat_inc(this_sd, ttwu_move_affine);
-                               schedstat_inc(p, se.nr_wakeups_affine);
-                               goto out_set_cpu;
-                       }
-               }
-
-               /*
-                * Start passive balancing when half the imbalance_pct
-                * limit is reached.
-                */
-               if (this_sd->flags & SD_WAKE_BALANCE) {
-                       if (imbalance*this_load <= 100*load) {
-                               schedstat_inc(this_sd, ttwu_move_balance);
-                               schedstat_inc(p, se.nr_wakeups_passive);
-                               goto out_set_cpu;
-                       }
-               }
-       }
-
-       new_cpu = cpu; /* Could not wake to this_cpu. Wake to cpu instead */
-out_set_cpu:
-       new_cpu = wake_idle(new_cpu, p);
+       new_cpu = p->sched_class->select_task_rq(p, sync);
        if (new_cpu != cpu) {
                set_task_cpu(p, new_cpu);
                task_rq_unlock(rq, &flags);
                cpu = task_cpu(p);
        }
 
+#ifdef CONFIG_SCHEDSTATS
+       schedstat_inc(rq, ttwu_count);
+       if (cpu == this_cpu)
+               schedstat_inc(rq, ttwu_local);
+       else {
+               struct sched_domain *sd;
+               for_each_domain(this_cpu, sd) {
+                       if (cpu_isset(cpu, sd->span)) {
+                               schedstat_inc(sd, ttwu_wake_remote);
+                               break;
+                       }
+               }
+       }
+
+#endif
+
+
 out_activate:
 #endif /* CONFIG_SMP */
        schedstat_inc(p, se.nr_wakeups);
 
        se->vruntime = rightmost->vruntime + 1;
 }
 
+/*
+ * wake_idle() will wake a task on an idle cpu if task->cpu is
+ * not idle and an idle cpu is available.  The span of cpus to
+ * search starts with cpus closest then further out as needed,
+ * so we always favor a closer, idle cpu.
+ *
+ * Returns the CPU we should wake onto.
+ */
+#if defined(ARCH_HAS_SCHED_WAKE_IDLE)
+static int wake_idle(int cpu, struct task_struct *p)
+{
+       cpumask_t tmp;
+       struct sched_domain *sd;
+       int i;
+
+       /*
+        * If it is idle, then it is the best cpu to run this task.
+        *
+        * This cpu is also the best, if it has more than one task already.
+        * Siblings must be also busy(in most cases) as they didn't already
+        * pickup the extra load from this cpu and hence we need not check
+        * sibling runqueue info. This will avoid the checks and cache miss
+        * penalities associated with that.
+        */
+       if (idle_cpu(cpu) || cpu_rq(cpu)->nr_running > 1)
+               return cpu;
+
+       for_each_domain(cpu, sd) {
+               if (sd->flags & SD_WAKE_IDLE) {
+                       cpus_and(tmp, sd->span, p->cpus_allowed);
+                       for_each_cpu_mask(i, tmp) {
+                               if (idle_cpu(i)) {
+                                       if (i != task_cpu(p)) {
+                                               schedstat_inc(p,
+                                                      se.nr_wakeups_idle);
+                                       }
+                                       return i;
+                               }
+                       }
+               } else {
+                       break;
+               }
+       }
+       return cpu;
+}
+#else
+static inline int wake_idle(int cpu, struct task_struct *p)
+{
+       return cpu;
+}
+#endif
+
+#ifdef CONFIG_SMP
+static int select_task_rq_fair(struct task_struct *p, int sync)
+{
+       int cpu, this_cpu;
+       struct rq *rq;
+       struct sched_domain *sd, *this_sd = NULL;
+       int new_cpu;
+
+       cpu      = task_cpu(p);
+       rq       = task_rq(p);
+       this_cpu = smp_processor_id();
+       new_cpu  = cpu;
+
+       for_each_domain(this_cpu, sd) {
+               if (cpu_isset(cpu, sd->span)) {
+                       this_sd = sd;
+                       break;
+               }
+       }
+
+       if (unlikely(!cpu_isset(this_cpu, p->cpus_allowed)))
+               goto out_set_cpu;
+
+       /*
+        * Check for affine wakeup and passive balancing possibilities.
+        */
+       if (this_sd) {
+               int idx = this_sd->wake_idx;
+               unsigned int imbalance;
+               unsigned long load, this_load;
+
+               imbalance = 100 + (this_sd->imbalance_pct - 100) / 2;
+
+               load = source_load(cpu, idx);
+               this_load = target_load(this_cpu, idx);
+
+               new_cpu = this_cpu; /* Wake to this CPU if we can */
+
+               if (this_sd->flags & SD_WAKE_AFFINE) {
+                       unsigned long tl = this_load;
+                       unsigned long tl_per_task;
+
+                       /*
+                        * Attract cache-cold tasks on sync wakeups:
+                        */
+                       if (sync && !task_hot(p, rq->clock, this_sd))
+                               goto out_set_cpu;
+
+                       schedstat_inc(p, se.nr_wakeups_affine_attempts);
+                       tl_per_task = cpu_avg_load_per_task(this_cpu);
+
+                       /*
+                        * If sync wakeup then subtract the (maximum possible)
+                        * effect of the currently running task from the load
+                        * of the current CPU:
+                        */
+                       if (sync)
+                               tl -= current->se.load.weight;
+
+                       if ((tl <= load &&
+                               tl + target_load(cpu, idx) <= tl_per_task) ||
+                              100*(tl + p->se.load.weight) <= imbalance*load) {
+                               /*
+                                * This domain has SD_WAKE_AFFINE and
+                                * p is cache cold in this domain, and
+                                * there is no bad imbalance.
+                                */
+                               schedstat_inc(this_sd, ttwu_move_affine);
+                               schedstat_inc(p, se.nr_wakeups_affine);
+                               goto out_set_cpu;
+                       }
+               }
+
+               /*
+                * Start passive balancing when half the imbalance_pct
+                * limit is reached.
+                */
+               if (this_sd->flags & SD_WAKE_BALANCE) {
+                       if (imbalance*this_load <= 100*load) {
+                               schedstat_inc(this_sd, ttwu_move_balance);
+                               schedstat_inc(p, se.nr_wakeups_passive);
+                               goto out_set_cpu;
+                       }
+               }
+       }
+
+       new_cpu = cpu; /* Could not wake to this_cpu. Wake to cpu instead */
+out_set_cpu:
+       return wake_idle(new_cpu, p);
+}
+#endif /* CONFIG_SMP */
+
+
 /*
  * Preempt the current task with a newly woken task if needed:
  */
        .enqueue_task           = enqueue_task_fair,
        .dequeue_task           = dequeue_task_fair,
        .yield_task             = yield_task_fair,
+#ifdef CONFIG_SMP
+       .select_task_rq         = select_task_rq_fair,
+#endif /* CONFIG_SMP */
 
        .check_preempt_curr     = check_preempt_wakeup,