]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/commitdiff
Merge commit 'v2.6.26-rc9' into sched/devel
authorIngo Molnar <mingo@elte.hu>
Mon, 7 Jul 2008 06:01:26 +0000 (08:01 +0200)
committerIngo Molnar <mingo@elte.hu>
Mon, 7 Jul 2008 06:01:26 +0000 (08:01 +0200)
1  2 
kernel/sched.c

diff --combined kernel/sched.c
index 996bc15196a5a51cf0e6b15718e74a94aa14e5eb,94ead43eda62bf8ebb9e054d9cad2a5838fe8f90..827c1b416da6ea9e80cdb8459bd81463f33e1b50
@@@ -74,8 -74,6 +74,8 @@@
  #include <asm/tlb.h>
  #include <asm/irq_regs.h>
  
 +#include "sched_cpupri.h"
 +
  /*
   * Convert user-nice values [ -20 ... 0 ... 19 ]
   * to static priority [ MAX_RT_PRIO..MAX_PRIO-1 ],
@@@ -291,15 -289,15 +291,15 @@@ struct task_group root_task_group
  static DEFINE_PER_CPU(struct sched_entity, init_sched_entity);
  /* Default task group's cfs_rq on each cpu */
  static DEFINE_PER_CPU(struct cfs_rq, init_cfs_rq) ____cacheline_aligned_in_smp;
 -#endif
 +#endif /* CONFIG_FAIR_GROUP_SCHED */
  
  #ifdef CONFIG_RT_GROUP_SCHED
  static DEFINE_PER_CPU(struct sched_rt_entity, init_sched_rt_entity);
  static DEFINE_PER_CPU(struct rt_rq, init_rt_rq) ____cacheline_aligned_in_smp;
 -#endif
 -#else
 +#endif /* CONFIG_RT_GROUP_SCHED */
 +#else /* !CONFIG_FAIR_GROUP_SCHED */
  #define root_task_group init_task_group
 -#endif
 +#endif /* CONFIG_FAIR_GROUP_SCHED */
  
  /* task_group_lock serializes add/remove of task groups and also changes to
   * a task group's cpu shares.
@@@ -309,9 -307,9 +309,9 @@@ static DEFINE_SPINLOCK(task_group_lock)
  #ifdef CONFIG_FAIR_GROUP_SCHED
  #ifdef CONFIG_USER_SCHED
  # define INIT_TASK_GROUP_LOAD (2*NICE_0_LOAD)
 -#else
 +#else /* !CONFIG_USER_SCHED */
  # define INIT_TASK_GROUP_LOAD NICE_0_LOAD
 -#endif
 +#endif /* CONFIG_USER_SCHED */
  
  /*
   * A weight of 0 or 1 can cause arithmetics problems.
@@@ -365,10 -363,6 +365,10 @@@ static inline void set_task_rq(struct t
  #else
  
  static inline void set_task_rq(struct task_struct *p, unsigned int cpu) { }
 +static inline struct task_group *task_group(struct task_struct *p)
 +{
 +      return NULL;
 +}
  
  #endif        /* CONFIG_GROUP_SCHED */
  
@@@ -379,7 -373,6 +379,7 @@@ struct cfs_rq 
  
        u64 exec_clock;
        u64 min_vruntime;
 +      u64 pair_start;
  
        struct rb_root tasks_timeline;
        struct rb_node *rb_leftmost;
         */
        struct list_head leaf_cfs_rq_list;
        struct task_group *tg;  /* group that "owns" this runqueue */
 +
 +#ifdef CONFIG_SMP
 +      /*
 +       * the part of load.weight contributed by tasks
 +       */
 +      unsigned long task_weight;
 +
 +      /*
 +       *   h_load = weight * f(tg)
 +       *
 +       * Where f(tg) is the recursive weight fraction assigned to
 +       * this group.
 +       */
 +      unsigned long h_load;
 +
 +      /*
 +       * this cpu's part of tg->shares
 +       */
 +      unsigned long shares;
 +
 +      /*
 +       * load.weight at the time we set shares
 +       */
 +      unsigned long rq_weight;
 +#endif
  #endif
  };
  
@@@ -484,9 -452,6 +484,9 @@@ struct root_domain 
         */
        cpumask_t rto_mask;
        atomic_t rto_count;
 +#ifdef CONFIG_SMP
 +      struct cpupri cpupri;
 +#endif
  };
  
  /*
@@@ -561,9 -526,6 +561,9 @@@ struct rq 
        int push_cpu;
        /* cpu of this runqueue: */
        int cpu;
 +      int online;
 +
 +      unsigned long avg_load_per_task;
  
        struct task_struct *migration_thread;
        struct list_head migration_queue;
@@@ -786,12 -748,6 +786,12 @@@ late_initcall(sched_init_debug)
   */
  const_debug unsigned int sysctl_sched_nr_migrate = 32;
  
 +/*
 + * ratelimit for updating the group shares.
 + * default: 0.5ms
 + */
 +const_debug unsigned int sysctl_sched_shares_ratelimit = 500000;
 +
  /*
   * period over which we measure -rt task cpu usage in us.
   * default: 1s
@@@ -819,6 -775,82 +819,6 @@@ static inline u64 global_rt_runtime(voi
        return (u64)sysctl_sched_rt_runtime * NSEC_PER_USEC;
  }
  
 -unsigned long long time_sync_thresh = 100000;
 -
 -static DEFINE_PER_CPU(unsigned long long, time_offset);
 -static DEFINE_PER_CPU(unsigned long long, prev_cpu_time);
 -
 -/*
 - * Global lock which we take every now and then to synchronize
 - * the CPUs time. This method is not warp-safe, but it's good
 - * enough to synchronize slowly diverging time sources and thus
 - * it's good enough for tracing:
 - */
 -static DEFINE_SPINLOCK(time_sync_lock);
 -static unsigned long long prev_global_time;
 -
 -static unsigned long long __sync_cpu_clock(unsigned long long time, int cpu)
 -{
 -      /*
 -       * We want this inlined, to not get tracer function calls
 -       * in this critical section:
 -       */
 -      spin_acquire(&time_sync_lock.dep_map, 0, 0, _THIS_IP_);
 -      __raw_spin_lock(&time_sync_lock.raw_lock);
 -
 -      if (time < prev_global_time) {
 -              per_cpu(time_offset, cpu) += prev_global_time - time;
 -              time = prev_global_time;
 -      } else {
 -              prev_global_time = time;
 -      }
 -
 -      __raw_spin_unlock(&time_sync_lock.raw_lock);
 -      spin_release(&time_sync_lock.dep_map, 1, _THIS_IP_);
 -
 -      return time;
 -}
 -
 -static unsigned long long __cpu_clock(int cpu)
 -{
 -      unsigned long long now;
 -
 -      /*
 -       * Only call sched_clock() if the scheduler has already been
 -       * initialized (some code might call cpu_clock() very early):
 -       */
 -      if (unlikely(!scheduler_running))
 -              return 0;
 -
 -      now = sched_clock_cpu(cpu);
 -
 -      return now;
 -}
 -
 -/*
 - * For kernel-internal use: high-speed (but slightly incorrect) per-cpu
 - * clock constructed from sched_clock():
 - */
 -unsigned long long cpu_clock(int cpu)
 -{
 -      unsigned long long prev_cpu_time, time, delta_time;
 -      unsigned long flags;
 -
 -      local_irq_save(flags);
 -      prev_cpu_time = per_cpu(prev_cpu_time, cpu);
 -      time = __cpu_clock(cpu) + per_cpu(time_offset, cpu);
 -      delta_time = time-prev_cpu_time;
 -
 -      if (unlikely(delta_time > time_sync_thresh)) {
 -              time = __sync_cpu_clock(time, cpu);
 -              per_cpu(prev_cpu_time, cpu) = time;
 -      }
 -      local_irq_restore(flags);
 -
 -      return time;
 -}
 -EXPORT_SYMBOL_GPL(cpu_clock);
 -
  #ifndef prepare_arch_switch
  # define prepare_arch_switch(next)    do { } while (0)
  #endif
@@@ -1281,15 -1313,15 +1281,15 @@@ void wake_up_idle_cpu(int cpu
        if (!tsk_is_polling(rq->idle))
                smp_send_reschedule(cpu);
  }
 -#endif
 +#endif /* CONFIG_NO_HZ */
  
 -#else
 +#else /* !CONFIG_SMP */
  static void __resched_task(struct task_struct *p, int tif_bit)
  {
        assert_spin_locked(&task_rq(p)->lock);
        set_tsk_thread_flag(p, tif_bit);
  }
 -#endif
 +#endif /* CONFIG_SMP */
  
  #if BITS_PER_LONG == 32
  # define WMULT_CONST  (~0UL)
   */
  #define SRR(x, y) (((x) + (1UL << ((y) - 1))) >> (y))
  
 +/*
 + * delta *= weight / lw
 + */
  static unsigned long
  calc_delta_mine(unsigned long delta_exec, unsigned long weight,
                struct load_weight *lw)
        return (unsigned long)min(tmp, (u64)(unsigned long)LONG_MAX);
  }
  
 -static inline unsigned long
 -calc_delta_fair(unsigned long delta_exec, struct load_weight *lw)
 -{
 -      return calc_delta_mine(delta_exec, NICE_0_LOAD, lw);
 -}
 -
  static inline void update_load_add(struct load_weight *lw, unsigned long inc)
  {
        lw->weight += inc;
@@@ -1444,211 -1479,17 +1444,211 @@@ static inline void dec_cpu_load(struct 
  #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);
 -#else /* CONFIG_SMP */
 +
 +static unsigned long cpu_avg_load_per_task(int cpu)
 +{
 +      struct rq *rq = cpu_rq(cpu);
 +
 +      if (rq->nr_running)
 +              rq->avg_load_per_task = rq->load.weight / rq->nr_running;
 +
 +      return rq->avg_load_per_task;
 +}
  
  #ifdef CONFIG_FAIR_GROUP_SCHED
 -static void cfs_rq_set_shares(struct cfs_rq *cfs_rq, unsigned long shares)
 +
 +typedef void (*tg_visitor)(struct task_group *, int, struct sched_domain *);
 +
 +/*
 + * Iterate the full tree, calling @down when first entering a node and @up when
 + * leaving it for the final time.
 + */
 +static void
 +walk_tg_tree(tg_visitor down, tg_visitor up, int cpu, struct sched_domain *sd)
 +{
 +      struct task_group *parent, *child;
 +
 +      rcu_read_lock();
 +      parent = &root_task_group;
 +down:
 +      (*down)(parent, cpu, sd);
 +      list_for_each_entry_rcu(child, &parent->children, siblings) {
 +              parent = child;
 +              goto down;
 +
 +up:
 +              continue;
 +      }
 +      (*up)(parent, cpu, sd);
 +
 +      child = parent;
 +      parent = parent->parent;
 +      if (parent)
 +              goto up;
 +      rcu_read_unlock();
 +}
 +
 +static void __set_se_shares(struct sched_entity *se, unsigned long shares);
 +
 +/*
 + * Calculate and set the cpu's group shares.
 + */
 +static void
 +__update_group_shares_cpu(struct task_group *tg, int cpu,
 +                        unsigned long sd_shares, unsigned long sd_rq_weight)
  {
 +      int boost = 0;
 +      unsigned long shares;
 +      unsigned long rq_weight;
 +
 +      if (!tg->se[cpu])
 +              return;
 +
 +      rq_weight = tg->cfs_rq[cpu]->load.weight;
 +
 +      /*
 +       * If there are currently no tasks on the cpu pretend there is one of
 +       * average load so that when a new task gets to run here it will not
 +       * get delayed by group starvation.
 +       */
 +      if (!rq_weight) {
 +              boost = 1;
 +              rq_weight = NICE_0_LOAD;
 +      }
 +
 +      if (unlikely(rq_weight > sd_rq_weight))
 +              rq_weight = sd_rq_weight;
 +
 +      /*
 +       *           \Sum shares * rq_weight
 +       * shares =  -----------------------
 +       *               \Sum rq_weight
 +       *
 +       */
 +      shares = (sd_shares * rq_weight) / (sd_rq_weight + 1);
 +
 +      /*
 +       * record the actual number of shares, not the boosted amount.
 +       */
 +      tg->cfs_rq[cpu]->shares = boost ? 0 : shares;
 +      tg->cfs_rq[cpu]->rq_weight = rq_weight;
 +
 +      if (shares < MIN_SHARES)
 +              shares = MIN_SHARES;
 +      else if (shares > MAX_SHARES)
 +              shares = MAX_SHARES;
 +
 +      __set_se_shares(tg->se[cpu], shares);
  }
 +
 +/*
 + * Re-compute the task group their per cpu shares over the given domain.
 + * This needs to be done in a bottom-up fashion because the rq weight of a
 + * parent group depends on the shares of its child groups.
 + */
 +static void
 +tg_shares_up(struct task_group *tg, int cpu, struct sched_domain *sd)
 +{
 +      unsigned long rq_weight = 0;
 +      unsigned long shares = 0;
 +      int i;
 +
 +      for_each_cpu_mask(i, sd->span) {
 +              rq_weight += tg->cfs_rq[i]->load.weight;
 +              shares += tg->cfs_rq[i]->shares;
 +      }
 +
 +      if ((!shares && rq_weight) || shares > tg->shares)
 +              shares = tg->shares;
 +
 +      if (!sd->parent || !(sd->parent->flags & SD_LOAD_BALANCE))
 +              shares = tg->shares;
 +
 +      if (!rq_weight)
 +              rq_weight = cpus_weight(sd->span) * NICE_0_LOAD;
 +
 +      for_each_cpu_mask(i, sd->span) {
 +              struct rq *rq = cpu_rq(i);
 +              unsigned long flags;
 +
 +              spin_lock_irqsave(&rq->lock, flags);
 +              __update_group_shares_cpu(tg, i, shares, rq_weight);
 +              spin_unlock_irqrestore(&rq->lock, flags);
 +      }
 +}
 +
 +/*
 + * Compute the cpu's hierarchical load factor for each task group.
 + * This needs to be done in a top-down fashion because the load of a child
 + * group is a fraction of its parents load.
 + */
 +static void
 +tg_load_down(struct task_group *tg, int cpu, struct sched_domain *sd)
 +{
 +      unsigned long load;
 +
 +      if (!tg->parent) {
 +              load = cpu_rq(cpu)->load.weight;
 +      } else {
 +              load = tg->parent->cfs_rq[cpu]->h_load;
 +              load *= tg->cfs_rq[cpu]->shares;
 +              load /= tg->parent->cfs_rq[cpu]->load.weight + 1;
 +      }
 +
 +      tg->cfs_rq[cpu]->h_load = load;
 +}
 +
 +static void
 +tg_nop(struct task_group *tg, int cpu, struct sched_domain *sd)
 +{
 +}
 +
 +static void update_shares(struct sched_domain *sd)
 +{
 +      u64 now = cpu_clock(raw_smp_processor_id());
 +      s64 elapsed = now - sd->last_update;
 +
 +      if (elapsed >= (s64)(u64)sysctl_sched_shares_ratelimit) {
 +              sd->last_update = now;
 +              walk_tg_tree(tg_nop, tg_shares_up, 0, sd);
 +      }
 +}
 +
 +static void update_shares_locked(struct rq *rq, struct sched_domain *sd)
 +{
 +      spin_unlock(&rq->lock);
 +      update_shares(sd);
 +      spin_lock(&rq->lock);
 +}
 +
 +static void update_h_load(int cpu)
 +{
 +      walk_tg_tree(tg_load_down, tg_nop, cpu, NULL);
 +}
 +
 +#else
 +
 +static inline void update_shares(struct sched_domain *sd)
 +{
 +}
 +
 +static inline void update_shares_locked(struct rq *rq, struct sched_domain *sd)
 +{
 +}
 +
  #endif
  
 -#endif /* CONFIG_SMP */
 +#endif
 +
 +#ifdef CONFIG_FAIR_GROUP_SCHED
 +static void cfs_rq_set_shares(struct cfs_rq *cfs_rq, unsigned long shares)
 +{
 +#ifdef CONFIG_SMP
 +      cfs_rq->shares = shares;
 +#endif
 +}
 +#endif
  
  #include "sched_stats.h"
  #include "sched_idletask.c"
  #endif
  
  #define sched_class_highest (&rt_sched_class)
 +#define for_each_class(class) \
 +   for (class = sched_class_highest; class; class = class->next)
  
 -static inline void inc_load(struct rq *rq, const struct task_struct *p)
 -{
 -      update_load_add(&rq->load, p->se.load.weight);
 -}
 -
 -static inline void dec_load(struct rq *rq, const struct task_struct *p)
 -{
 -      update_load_sub(&rq->load, p->se.load.weight);
 -}
 -
 -static void inc_nr_running(struct task_struct *p, struct rq *rq)
 +static void inc_nr_running(struct rq *rq)
  {
        rq->nr_running++;
 -      inc_load(rq, p);
  }
  
 -static void dec_nr_running(struct task_struct *p, struct rq *rq)
 +static void dec_nr_running(struct rq *rq)
  {
        rq->nr_running--;
 -      dec_load(rq, p);
  }
  
  static void set_load_weight(struct task_struct *p)
        p->se.load.inv_weight = prio_to_wmult[p->static_prio - MAX_RT_PRIO];
  }
  
 +static void update_avg(u64 *avg, u64 sample)
 +{
 +      s64 diff = sample - *avg;
 +      *avg += diff >> 3;
 +}
 +
  static void enqueue_task(struct rq *rq, struct task_struct *p, int wakeup)
  {
        sched_info_queued(p);
  
  static void dequeue_task(struct rq *rq, struct task_struct *p, int sleep)
  {
 +      if (sleep && p->se.last_wakeup) {
 +              update_avg(&p->se.avg_overlap,
 +                         p->se.sum_exec_runtime - p->se.last_wakeup);
 +              p->se.last_wakeup = 0;
 +      }
 +
 +      sched_info_dequeued(p);
        p->sched_class->dequeue_task(rq, p, sleep);
        p->se.on_rq = 0;
  }
@@@ -1774,7 -1612,7 +1774,7 @@@ static void activate_task(struct rq *rq
                rq->nr_uninterruptible--;
  
        enqueue_task(rq, p, wakeup);
 -      inc_nr_running(p, rq);
 +      inc_nr_running(rq);
  }
  
  /*
@@@ -1786,7 -1624,7 +1786,7 @@@ static void deactivate_task(struct rq *
                rq->nr_uninterruptible++;
  
        dequeue_task(rq, p, sleep);
 -      dec_nr_running(p, rq);
 +      dec_nr_running(rq);
  }
  
  /**
@@@ -1798,6 -1636,12 +1798,6 @@@ inline int task_curr(const struct task_
        return cpu_curr(task_cpu(p)) == p;
  }
  
 -/* Used instead of source_load when we know the type == 0 */
 -unsigned long weighted_cpuload(const int cpu)
 -{
 -      return cpu_rq(cpu)->load.weight;
 -}
 -
  static inline void __set_task_cpu(struct task_struct *p, unsigned int cpu)
  {
        set_task_rq(p, cpu);
@@@ -1826,12 -1670,6 +1826,12 @@@ static inline void check_class_changed(
  
  #ifdef CONFIG_SMP
  
 +/* Used instead of source_load when we know the type == 0 */
 +static unsigned long weighted_cpuload(const int cpu)
 +{
 +      return cpu_rq(cpu)->load.weight;
 +}
 +
  /*
   * Is this task likely cache-hot:
   */
@@@ -2042,7 -1880,7 +2042,7 @@@ static unsigned long source_load(int cp
        struct rq *rq = cpu_rq(cpu);
        unsigned long total = weighted_cpuload(cpu);
  
 -      if (type == 0)
 +      if (type == 0 || !sched_feat(LB_BIAS))
                return total;
  
        return min(rq->cpu_load[type-1], total);
@@@ -2057,12 -1895,24 +2057,12 @@@ static unsigned long target_load(int cp
        struct rq *rq = cpu_rq(cpu);
        unsigned long total = weighted_cpuload(cpu);
  
 -      if (type == 0)
 +      if (type == 0 || !sched_feat(LB_BIAS))
                return total;
  
        return max(rq->cpu_load[type-1], total);
  }
  
 -/*
 - * Return the average load per task on the cpu's run queue
 - */
 -static unsigned long cpu_avg_load_per_task(int cpu)
 -{
 -      struct rq *rq = cpu_rq(cpu);
 -      unsigned long total = weighted_cpuload(cpu);
 -      unsigned long n = rq->nr_running;
 -
 -      return n ? total / n : SCHED_LOAD_SCALE;
 -}
 -
  /*
   * find_idlest_group finds and returns the least busy CPU group within the
   * domain.
@@@ -2169,9 -2019,6 +2169,9 @@@ static int sched_balance_self(int cpu, 
                        sd = tmp;
        }
  
 +      if (sd)
 +              update_shares(sd);
 +
        while (sd) {
                cpumask_t span, tmpmask;
                struct sched_group *group;
@@@ -2238,22 -2085,6 +2238,22 @@@ static int try_to_wake_up(struct task_s
        if (!sched_feat(SYNC_WAKEUPS))
                sync = 0;
  
 +#ifdef CONFIG_SMP
 +      if (sched_feat(LB_WAKEUP_UPDATE)) {
 +              struct sched_domain *sd;
 +
 +              this_cpu = raw_smp_processor_id();
 +              cpu = task_cpu(p);
 +
 +              for_each_domain(this_cpu, sd) {
 +                      if (cpu_isset(cpu, sd->span)) {
 +                              update_shares(sd);
 +                              break;
 +                      }
 +              }
 +      }
 +#endif
 +
        smp_wmb();
        rq = task_rq_lock(p, &flags);
        old_state = p->state;
                        }
                }
        }
 -#endif
 +#endif /* CONFIG_SCHEDSTATS */
  
  out_activate:
  #endif /* CONFIG_SMP */
@@@ -2326,8 -2157,6 +2326,8 @@@ out_running
                p->sched_class->task_wake_up(rq, p);
  #endif
  out:
 +      current->se.last_wakeup = current->se.sum_exec_runtime;
 +
        task_rq_unlock(rq, &flags);
  
        return success;
@@@ -2448,7 -2277,7 +2448,7 @@@ void wake_up_new_task(struct task_struc
                 * management (if any):
                 */
                p->sched_class->task_new(rq, p);
 -              inc_nr_running(p, rq);
 +              inc_nr_running(rq);
        }
        check_preempt_curr(rq, p);
  #ifdef CONFIG_SMP
@@@ -2502,7 -2331,7 +2502,7 @@@ fire_sched_out_preempt_notifiers(struc
                notifier->ops->sched_out(notifier, next);
  }
  
 -#else
 +#else /* !CONFIG_PREEMPT_NOTIFIERS */
  
  static void fire_sched_in_preempt_notifiers(struct task_struct *curr)
  {
@@@ -2514,7 -2343,7 +2514,7 @@@ fire_sched_out_preempt_notifiers(struc
  {
  }
  
 -#endif
 +#endif /* CONFIG_PREEMPT_NOTIFIERS */
  
  /**
   * prepare_task_switch - prepare to switch tasks
@@@ -2956,7 -2785,7 +2956,7 @@@ balance_tasks(struct rq *this_rq, int t
              enum cpu_idle_type idle, int *all_pinned,
              int *this_best_prio, struct rq_iterator *iterator)
  {
 -      int loops = 0, pulled = 0, pinned = 0, skip_for_load;
 +      int loops = 0, pulled = 0, pinned = 0;
        struct task_struct *p;
        long rem_load_move = max_load_move;
  
  next:
        if (!p || loops++ > sysctl_sched_nr_migrate)
                goto out;
 -      /*
 -       * To help distribute high priority tasks across CPUs we don't
 -       * skip a task if it will be the highest priority task (i.e. smallest
 -       * prio value) on its new queue regardless of its load weight
 -       */
 -      skip_for_load = (p->se.load.weight >> 1) > rem_load_move +
 -                                                       SCHED_LOAD_SCALE_FUZZ;
 -      if ((skip_for_load && p->prio >= *this_best_prio) ||
 +
 +      if ((p->se.load.weight >> 1) > rem_load_move ||
            !can_migrate_task(p, busiest, this_cpu, sd, idle, &pinned)) {
                p = iterator->next(iterator->arg);
                goto next;
@@@ -3028,10 -2863,6 +3028,10 @@@ static int move_tasks(struct rq *this_r
                                max_load_move - total_load_moved,
                                sd, idle, all_pinned, &this_best_prio);
                class = class->next;
 +
 +              if (idle == CPU_NEWLY_IDLE && this_rq->nr_running)
 +                      break;
 +
        } while (class && max_load_move > total_load_moved);
  
        return total_load_moved > 0;
@@@ -3108,7 -2939,6 +3108,7 @@@ find_busiest_group(struct sched_domain 
        max_load = this_load = total_load = total_pwr = 0;
        busiest_load_per_task = busiest_nr_running = 0;
        this_load_per_task = this_nr_running = 0;
 +
        if (idle == CPU_NOT_IDLE)
                load_idx = sd->busy_idx;
        else if (idle == CPU_NEWLY_IDLE)
                int __group_imb = 0;
                unsigned int balance_cpu = -1, first_idle_cpu = 0;
                unsigned long sum_nr_running, sum_weighted_load;
 +              unsigned long sum_avg_load_per_task;
 +              unsigned long avg_load_per_task;
  
                local_group = cpu_isset(this_cpu, group->cpumask);
  
  
                /* Tally up the load of all CPUs in the group */
                sum_weighted_load = sum_nr_running = avg_load = 0;
 +              sum_avg_load_per_task = avg_load_per_task = 0;
 +
                max_cpu_load = 0;
                min_cpu_load = ~0UL;
  
                        avg_load += load;
                        sum_nr_running += rq->nr_running;
                        sum_weighted_load += weighted_cpuload(i);
 +
 +                      sum_avg_load_per_task += cpu_avg_load_per_task(i);
                }
  
                /*
                avg_load = sg_div_cpu_power(group,
                                avg_load * SCHED_LOAD_SCALE);
  
 -              if ((max_cpu_load - min_cpu_load) > SCHED_LOAD_SCALE)
 +
 +              /*
 +               * Consider the group unbalanced when the imbalance is larger
 +               * than the average weight of two tasks.
 +               *
 +               * APZ: with cgroup the avg task weight can vary wildly and
 +               *      might not be a suitable number - should we keep a
 +               *      normalized nr_running number somewhere that negates
 +               *      the hierarchy?
 +               */
 +              avg_load_per_task = sg_div_cpu_power(group,
 +                              sum_avg_load_per_task * SCHED_LOAD_SCALE);
 +
 +              if ((max_cpu_load - min_cpu_load) > 2*avg_load_per_task)
                        __group_imb = 1;
  
                group_capacity = group->__cpu_power / SCHED_LOAD_SCALE;
@@@ -3345,9 -3156,9 +3345,9 @@@ small_imbalance
                        if (busiest_load_per_task > this_load_per_task)
                                imbn = 1;
                } else
 -                      this_load_per_task = SCHED_LOAD_SCALE;
 +                      this_load_per_task = cpu_avg_load_per_task(this_cpu);
  
 -              if (max_load - this_load + SCHED_LOAD_SCALE_FUZZ >=
 +              if (max_load - this_load + 2*busiest_load_per_task >=
                                        busiest_load_per_task * imbn) {
                        *imbalance = busiest_load_per_task;
                        return busiest;
@@@ -3473,7 -3284,6 +3473,7 @@@ static int load_balance(int this_cpu, s
        schedstat_inc(sd, lb_count[idle]);
  
  redo:
 +      update_shares(sd);
        group = find_busiest_group(sd, this_cpu, &imbalance, idle, &sd_idle,
                                   cpus, balance);
  
  
        if (!ld_moved && !sd_idle && sd->flags & SD_SHARE_CPUPOWER &&
            !test_sd_parent(sd, SD_POWERSAVINGS_BALANCE))
 -              return -1;
 -      return ld_moved;
 +              ld_moved = -1;
 +
 +      goto out;
  
  out_balanced:
        schedstat_inc(sd, lb_balanced[idle]);
@@@ -3593,13 -3402,8 +3593,13 @@@ out_one_pinned
  
        if (!sd_idle && sd->flags & SD_SHARE_CPUPOWER &&
            !test_sd_parent(sd, SD_POWERSAVINGS_BALANCE))
 -              return -1;
 -      return 0;
 +              ld_moved = -1;
 +      else
 +              ld_moved = 0;
 +out:
 +      if (ld_moved)
 +              update_shares(sd);
 +      return ld_moved;
  }
  
  /*
@@@ -3634,7 -3438,6 +3634,7 @@@ load_balance_newidle(int this_cpu, stru
  
        schedstat_inc(sd, lb_count[CPU_NEWLY_IDLE]);
  redo:
 +      update_shares_locked(this_rq, sd);
        group = find_busiest_group(sd, this_cpu, &imbalance, CPU_NEWLY_IDLE,
                                   &sd_idle, cpus, NULL);
        if (!group) {
        } else
                sd->nr_balance_failed = 0;
  
 +      update_shares_locked(this_rq, sd);
        return ld_moved;
  
  out_balanced:
@@@ -3870,7 -3672,6 +3870,7 @@@ static void rebalance_domains(int cpu, 
        /* Earliest time when we have to do rebalance again */
        unsigned long next_balance = jiffies + 60*HZ;
        int update_next_balance = 0;
 +      int need_serialize;
        cpumask_t tmp;
  
        for_each_domain(cpu, sd) {
                if (interval > HZ*NR_CPUS/10)
                        interval = HZ*NR_CPUS/10;
  
 +              need_serialize = sd->flags & SD_SERIALIZE;
  
 -              if (sd->flags & SD_SERIALIZE) {
 +              if (need_serialize) {
                        if (!spin_trylock(&balancing))
                                goto out;
                }
                        }
                        sd->last_balance = jiffies;
                }
 -              if (sd->flags & SD_SERIALIZE)
 +              if (need_serialize)
                        spin_unlock(&balancing);
  out:
                if (time_after(next_balance, sd->last_balance + interval)) {
@@@ -4270,7 -4070,6 +4270,7 @@@ static noinline void __schedule_bug(str
                prev->comm, prev->pid, preempt_count());
  
        debug_show_held_locks(prev);
 +      print_modules();
        if (irqs_disabled())
                print_irqtrace_events(prev);
  
@@@ -4344,7 -4143,7 +4344,7 @@@ asmlinkage void __sched schedule(void
        struct task_struct *prev, *next;
        unsigned long *switch_count;
        struct rq *rq;
 -      int cpu;
 +      int cpu, hrtick = sched_feat(HRTICK);
  
  need_resched:
        preempt_disable();
@@@ -4359,8 -4158,7 +4359,8 @@@ need_resched_nonpreemptible
  
        schedule_debug(prev);
  
 -      hrtick_clear(rq);
 +      if (hrtick)
 +              hrtick_clear(rq);
  
        /*
         * Do the rq-clock update outside the rq lock:
        } else
                spin_unlock_irq(&rq->lock);
  
 -      hrtick_set(rq);
 +      if (hrtick)
 +              hrtick_set(rq);
  
        if (unlikely(reacquire_kernel_lock(current) < 0))
                goto need_resched_nonpreemptible;
@@@ -4789,8 -4586,10 +4789,8 @@@ void set_user_nice(struct task_struct *
                goto out_unlock;
        }
        on_rq = p->se.on_rq;
 -      if (on_rq) {
 +      if (on_rq)
                dequeue_task(rq, p, 0);
 -              dec_load(rq, p);
 -      }
  
        p->static_prio = NICE_TO_PRIO(nice);
        set_load_weight(p);
  
        if (on_rq) {
                enqueue_task(rq, p, 0);
 -              inc_load(rq, p);
                /*
                 * If the task increased its priority or is running and
                 * lowered its priority, then reschedule its CPU:
@@@ -5270,6 -5070,24 +5270,6 @@@ asmlinkage long sys_sched_setaffinity(p
        return sched_setaffinity(pid, &new_mask);
  }
  
 -/*
 - * Represents all cpu's present in the system
 - * In systems capable of hotplug, this map could dynamically grow
 - * as new cpu's are detected in the system via any platform specific
 - * method, such as ACPI for e.g.
 - */
 -
 -cpumask_t cpu_present_map __read_mostly;
 -EXPORT_SYMBOL(cpu_present_map);
 -
 -#ifndef CONFIG_SMP
 -cpumask_t cpu_online_map __read_mostly = CPU_MASK_ALL;
 -EXPORT_SYMBOL(cpu_online_map);
 -
 -cpumask_t cpu_possible_map __read_mostly = CPU_MASK_ALL;
 -EXPORT_SYMBOL(cpu_possible_map);
 -#endif
 -
  long sched_getaffinity(pid_t pid, cpumask_t *mask)
  {
        struct task_struct *p;
@@@ -5753,12 -5571,6 +5753,12 @@@ int set_cpus_allowed_ptr(struct task_st
                goto out;
        }
  
 +      if (unlikely((p->flags & PF_THREAD_BOUND) && p != current &&
 +                   !cpus_equal(p->cpus_allowed, *new_mask))) {
 +              ret = -EINVAL;
 +              goto out;
 +      }
 +
        if (p->sched_class->set_cpus_allowed)
                p->sched_class->set_cpus_allowed(p, new_mask);
        else {
@@@ -6075,6 -5887,7 +6075,7 @@@ static void migrate_dead_tasks(unsigne
                next = pick_next_task(rq, rq->curr);
                if (!next)
                        break;
+               next->sched_class->put_prev_task(rq, next);
                migrate_dead(dead_cpu, next);
  
        }
@@@ -6246,36 -6059,6 +6247,36 @@@ static void unregister_sched_domain_sys
  }
  #endif
  
 +static void set_rq_online(struct rq *rq)
 +{
 +      if (!rq->online) {
 +              const struct sched_class *class;
 +
 +              cpu_set(rq->cpu, rq->rd->online);
 +              rq->online = 1;
 +
 +              for_each_class(class) {
 +                      if (class->rq_online)
 +                              class->rq_online(rq);
 +              }
 +      }
 +}
 +
 +static void set_rq_offline(struct rq *rq)
 +{
 +      if (rq->online) {
 +              const struct sched_class *class;
 +
 +              for_each_class(class) {
 +                      if (class->rq_offline)
 +                              class->rq_offline(rq);
 +              }
 +
 +              cpu_clear(rq->cpu, rq->rd->online);
 +              rq->online = 0;
 +      }
 +}
 +
  /*
   * migration_call - callback that gets triggered when a CPU is added.
   * Here we can start up the necessary migration thread for the new CPU.
@@@ -6313,8 -6096,7 +6314,8 @@@ migration_call(struct notifier_block *n
                spin_lock_irqsave(&rq->lock, flags);
                if (rq->rd) {
                        BUG_ON(!cpu_isset(cpu, rq->rd->span));
 -                      cpu_set(cpu, rq->rd->online);
 +
 +                      set_rq_online(rq);
                }
                spin_unlock_irqrestore(&rq->lock, flags);
                break;
                spin_lock_irqsave(&rq->lock, flags);
                if (rq->rd) {
                        BUG_ON(!cpu_isset(cpu, rq->rd->span));
 -                      cpu_clear(cpu, rq->rd->online);
 +                      set_rq_offline(rq);
                }
                spin_unlock_irqrestore(&rq->lock, flags);
                break;
@@@ -6409,28 -6191,6 +6410,28 @@@ void __init migration_init(void
  
  #ifdef CONFIG_SCHED_DEBUG
  
 +static inline const char *sd_level_to_string(enum sched_domain_level lvl)
 +{
 +      switch (lvl) {
 +      case SD_LV_NONE:
 +                      return "NONE";
 +      case SD_LV_SIBLING:
 +                      return "SIBLING";
 +      case SD_LV_MC:
 +                      return "MC";
 +      case SD_LV_CPU:
 +                      return "CPU";
 +      case SD_LV_NODE:
 +                      return "NODE";
 +      case SD_LV_ALLNODES:
 +                      return "ALLNODES";
 +      case SD_LV_MAX:
 +                      return "MAX";
 +
 +      }
 +      return "MAX";
 +}
 +
  static int sched_domain_debug_one(struct sched_domain *sd, int cpu, int level,
                                  cpumask_t *groupmask)
  {
                return -1;
        }
  
 -      printk(KERN_CONT "span %s\n", str);
 +      printk(KERN_CONT "span %s level %s\n",
 +              str, sd_level_to_string(sd->level));
  
        if (!cpu_isset(cpu, sd->span)) {
                printk(KERN_ERR "ERROR: domain->span does not contain "
@@@ -6535,9 -6294,9 +6536,9 @@@ static void sched_domain_debug(struct s
        }
        kfree(groupmask);
  }
 -#else
 +#else /* !CONFIG_SCHED_DEBUG */
  # define sched_domain_debug(sd, cpu) do { } while (0)
 -#endif
 +#endif /* CONFIG_SCHED_DEBUG */
  
  static int sd_degenerate(struct sched_domain *sd)
  {
@@@ -6597,16 -6356,20 +6598,16 @@@ sd_parent_degenerate(struct sched_domai
  static void rq_attach_root(struct rq *rq, struct root_domain *rd)
  {
        unsigned long flags;
 -      const struct sched_class *class;
  
        spin_lock_irqsave(&rq->lock, flags);
  
        if (rq->rd) {
                struct root_domain *old_rd = rq->rd;
  
 -              for (class = sched_class_highest; class; class = class->next) {
 -                      if (class->leave_domain)
 -                              class->leave_domain(rq);
 -              }
 +              if (cpu_isset(rq->cpu, old_rd->online))
 +                      set_rq_offline(rq);
  
                cpu_clear(rq->cpu, old_rd->span);
 -              cpu_clear(rq->cpu, old_rd->online);
  
                if (atomic_dec_and_test(&old_rd->refcount))
                        kfree(old_rd);
  
        cpu_set(rq->cpu, rd->span);
        if (cpu_isset(rq->cpu, cpu_online_map))
 -              cpu_set(rq->cpu, rd->online);
 -
 -      for (class = sched_class_highest; class; class = class->next) {
 -              if (class->join_domain)
 -                      class->join_domain(rq);
 -      }
 +              set_rq_online(rq);
  
        spin_unlock_irqrestore(&rq->lock, flags);
  }
@@@ -6628,8 -6396,6 +6629,8 @@@ static void init_rootdomain(struct root
  
        cpus_clear(rd->span);
        cpus_clear(rd->online);
 +
 +      cpupri_init(&rd->cpupri);
  }
  
  static void init_defrootdomain(void)
@@@ -6824,7 -6590,7 +6825,7 @@@ static void sched_domain_node_span(int 
                cpus_or(*span, *span, *nodemask);
        }
  }
 -#endif
 +#endif /* CONFIG_NUMA */
  
  int sched_smt_power_savings = 0, sched_mc_power_savings = 0;
  
@@@ -6843,7 -6609,7 +6844,7 @@@ cpu_to_cpu_group(int cpu, const cpumask
                *sg = &per_cpu(sched_group_cpus, cpu);
        return cpu;
  }
 -#endif
 +#endif /* CONFIG_SCHED_SMT */
  
  /*
   * multi-core sched-domains:
  #ifdef CONFIG_SCHED_MC
  static DEFINE_PER_CPU(struct sched_domain, core_domains);
  static DEFINE_PER_CPU(struct sched_group, sched_group_core);
 -#endif
 +#endif /* CONFIG_SCHED_MC */
  
  #if defined(CONFIG_SCHED_MC) && defined(CONFIG_SCHED_SMT)
  static int
@@@ -6953,7 -6719,7 +6954,7 @@@ static void init_numa_sched_groups_powe
                sg = sg->next;
        } while (sg != group_head);
  }
 -#endif
 +#endif /* CONFIG_NUMA */
  
  #ifdef CONFIG_NUMA
  /* Free memory allocated for various sched_group structures */
@@@ -6990,11 -6756,11 +6991,11 @@@ next_sg
                sched_group_nodes_bycpu[cpu] = NULL;
        }
  }
 -#else
 +#else /* !CONFIG_NUMA */
  static void free_sched_groups(const cpumask_t *cpu_map, cpumask_t *nodemask)
  {
  }
 -#endif
 +#endif /* CONFIG_NUMA */
  
  /*
   * Initialize sched groups cpu_power.
@@@ -7703,7 -7469,7 +7704,7 @@@ int sched_create_sysfs_power_savings_en
  #endif
        return err;
  }
 -#endif
 +#endif /* CONFIG_SCHED_MC || CONFIG_SCHED_SMT */
  
  /*
   * Force a reinitialization of the sched domains hierarchy. The domains
  static int update_sched_domains(struct notifier_block *nfb,
                                unsigned long action, void *hcpu)
  {
 +      int cpu = (int)(long)hcpu;
 +
        switch (action) {
 -      case CPU_UP_PREPARE:
 -      case CPU_UP_PREPARE_FROZEN:
        case CPU_DOWN_PREPARE:
        case CPU_DOWN_PREPARE_FROZEN:
 +              disable_runtime(cpu_rq(cpu));
 +              /* fall-through */
 +      case CPU_UP_PREPARE:
 +      case CPU_UP_PREPARE_FROZEN:
                detach_destroy_domains(&cpu_online_map);
                free_sched_domains();
                return NOTIFY_OK;
  
 -      case CPU_UP_CANCELED:
 -      case CPU_UP_CANCELED_FROZEN:
 +
        case CPU_DOWN_FAILED:
        case CPU_DOWN_FAILED_FROZEN:
        case CPU_ONLINE:
        case CPU_ONLINE_FROZEN:
 +              enable_runtime(cpu_rq(cpu));
 +              /* fall-through */
 +      case CPU_UP_CANCELED:
 +      case CPU_UP_CANCELED_FROZEN:
        case CPU_DEAD:
        case CPU_DEAD_FROZEN:
                /*
@@@ -7935,8 -7694,8 +7936,8 @@@ void __init sched_init(void
  
                root_task_group.cfs_rq = (struct cfs_rq **)ptr;
                ptr += nr_cpu_ids * sizeof(void **);
 -#endif
 -#endif
 +#endif /* CONFIG_USER_SCHED */
 +#endif /* CONFIG_FAIR_GROUP_SCHED */
  #ifdef CONFIG_RT_GROUP_SCHED
                init_task_group.rt_se = (struct sched_rt_entity **)ptr;
                ptr += nr_cpu_ids * sizeof(void **);
  
                root_task_group.rt_rq = (struct rt_rq **)ptr;
                ptr += nr_cpu_ids * sizeof(void **);
 -#endif
 -#endif
 +#endif /* CONFIG_USER_SCHED */
 +#endif /* CONFIG_RT_GROUP_SCHED */
        }
  
  #ifdef CONFIG_SMP
  #ifdef CONFIG_USER_SCHED
        init_rt_bandwidth(&root_task_group.rt_bandwidth,
                        global_rt_period(), RUNTIME_INF);
 -#endif
 -#endif
 +#endif /* CONFIG_USER_SCHED */
 +#endif /* CONFIG_RT_GROUP_SCHED */
  
  #ifdef CONFIG_GROUP_SCHED
        list_add(&init_task_group.list, &task_groups);
        INIT_LIST_HEAD(&root_task_group.children);
        init_task_group.parent = &root_task_group;
        list_add(&init_task_group.siblings, &root_task_group.children);
 -#endif
 -#endif
 +#endif /* CONFIG_USER_SCHED */
 +#endif /* CONFIG_GROUP_SCHED */
  
        for_each_possible_cpu(i) {
                struct rq *rq;
                rq->next_balance = jiffies;
                rq->push_cpu = 0;
                rq->cpu = i;
 +              rq->online = 0;
                rq->migration_thread = NULL;
                INIT_LIST_HEAD(&rq->migration_queue);
                rq_attach_root(rq, &def_root_domain);
@@@ -8299,7 -8057,7 +8300,7 @@@ static inline void unregister_fair_sche
  {
        list_del_rcu(&tg->cfs_rq[cpu]->leaf_cfs_rq_list);
  }
 -#else
 +#else /* !CONFG_FAIR_GROUP_SCHED */
  static inline void free_fair_sched_group(struct task_group *tg)
  {
  }
@@@ -8317,7 -8075,7 +8318,7 @@@ static inline void register_fair_sched_
  static inline void unregister_fair_sched_group(struct task_group *tg, int cpu)
  {
  }
 -#endif
 +#endif /* CONFIG_FAIR_GROUP_SCHED */
  
  #ifdef CONFIG_RT_GROUP_SCHED
  static void free_rt_sched_group(struct task_group *tg)
@@@ -8388,7 -8146,7 +8389,7 @@@ static inline void unregister_rt_sched_
  {
        list_del_rcu(&tg->rt_rq[cpu]->leaf_rt_rq_list);
  }
 -#else
 +#else /* !CONFIG_RT_GROUP_SCHED */
  static inline void free_rt_sched_group(struct task_group *tg)
  {
  }
@@@ -8406,7 -8164,7 +8407,7 @@@ static inline void register_rt_sched_gr
  static inline void unregister_rt_sched_group(struct task_group *tg, int cpu)
  {
  }
 -#endif
 +#endif /* CONFIG_RT_GROUP_SCHED */
  
  #ifdef CONFIG_GROUP_SCHED
  static void free_sched_group(struct task_group *tg)
@@@ -8517,14 -8275,17 +8518,14 @@@ void sched_move_task(struct task_struc
  
        task_rq_unlock(rq, &flags);
  }
 -#endif
 +#endif /* CONFIG_GROUP_SCHED */
  
  #ifdef CONFIG_FAIR_GROUP_SCHED
 -static void set_se_shares(struct sched_entity *se, unsigned long shares)
 +static void __set_se_shares(struct sched_entity *se, unsigned long shares)
  {
        struct cfs_rq *cfs_rq = se->cfs_rq;
 -      struct rq *rq = cfs_rq->rq;
        int on_rq;
  
 -      spin_lock_irq(&rq->lock);
 -
        on_rq = se->on_rq;
        if (on_rq)
                dequeue_entity(cfs_rq, se, 0);
  
        if (on_rq)
                enqueue_entity(cfs_rq, se, 0);
 +}
  
 -      spin_unlock_irq(&rq->lock);
 +static void set_se_shares(struct sched_entity *se, unsigned long shares)
 +{
 +      struct cfs_rq *cfs_rq = se->cfs_rq;
 +      struct rq *rq = cfs_rq->rq;
 +      unsigned long flags;
 +
 +      spin_lock_irqsave(&rq->lock, flags);
 +      __set_se_shares(se, shares);
 +      spin_unlock_irqrestore(&rq->lock, flags);
  }
  
  static DEFINE_MUTEX(shares_mutex);
@@@ -8583,13 -8335,8 +8584,13 @@@ int sched_group_set_shares(struct task_
         * w/o tripping rebalance_share or load_balance_fair.
         */
        tg->shares = shares;
 -      for_each_possible_cpu(i)
 +      for_each_possible_cpu(i) {
 +              /*
 +               * force a rebalance
 +               */
 +              cfs_rq_set_shares(tg->cfs_rq[i], 0);
                set_se_shares(tg->se[i], shares);
 +      }
  
        /*
         * Enable load balance activity on this group, by inserting it back on
@@@ -8628,7 -8375,7 +8629,7 @@@ static unsigned long to_ratio(u64 perio
  #ifdef CONFIG_CGROUP_SCHED
  static int __rt_schedulable(struct task_group *tg, u64 period, u64 runtime)
  {
 -      struct task_group *tgi, *parent = tg ? tg->parent : NULL;
 +      struct task_group *tgi, *parent = tg->parent;
        unsigned long total = 0;
  
        if (!parent) {
        }
        rcu_read_unlock();
  
 -      return total + to_ratio(period, runtime) <
 +      return total + to_ratio(period, runtime) <=
                to_ratio(ktime_to_ns(parent->rt_bandwidth.rt_period),
                                parent->rt_bandwidth.rt_runtime);
  }
@@@ -8755,6 -8502,9 +8756,9 @@@ int sched_group_set_rt_period(struct ta
        rt_period = (u64)rt_period_us * NSEC_PER_USEC;
        rt_runtime = tg->rt_bandwidth.rt_runtime;
  
+       if (rt_period == 0)
+               return -EINVAL;
        return tg_set_bandwidth(tg, rt_period, rt_runtime);
  }
  
@@@ -8769,21 -8519,16 +8773,21 @@@ long sched_group_rt_period(struct task_
  
  static int sched_rt_global_constraints(void)
  {
 +      struct task_group *tg = &root_task_group;
 +      u64 rt_runtime, rt_period;
        int ret = 0;
  
 +      rt_period = ktime_to_ns(tg->rt_bandwidth.rt_period);
 +      rt_runtime = tg->rt_bandwidth.rt_runtime;
 +
        mutex_lock(&rt_constraints_mutex);
 -      if (!__rt_schedulable(NULL, 1, 0))
 +      if (!__rt_schedulable(tg, rt_period, rt_runtime))
                ret = -EINVAL;
        mutex_unlock(&rt_constraints_mutex);
  
        return ret;
  }
 -#else
 +#else /* !CONFIG_RT_GROUP_SCHED */
  static int sched_rt_global_constraints(void)
  {
        unsigned long flags;
  
        return 0;
  }
 -#endif
 +#endif /* CONFIG_RT_GROUP_SCHED */
  
  int sched_rt_handler(struct ctl_table *table, int write,
                struct file *filp, void __user *buffer, size_t *lenp,
@@@ -8909,7 -8654,7 +8913,7 @@@ static u64 cpu_shares_read_u64(struct c
  
        return (u64) tg->shares;
  }
 -#endif
 +#endif /* CONFIG_FAIR_GROUP_SCHED */
  
  #ifdef CONFIG_RT_GROUP_SCHED
  static int cpu_rt_runtime_write(struct cgroup *cgrp, struct cftype *cft,
@@@ -8933,7 -8678,7 +8937,7 @@@ static u64 cpu_rt_period_read_uint(stru
  {
        return sched_group_rt_period(cgroup_tg(cgrp));
  }
 -#endif
 +#endif /* CONFIG_RT_GROUP_SCHED */
  
  static struct cftype cpu_files[] = {
  #ifdef CONFIG_FAIR_GROUP_SCHED