]> nv-tegra.nvidia Code Review - linux-2.6.git/blobdiff - kernel/sched.c
Remove argument from open_softirq which is always NULL
[linux-2.6.git] / kernel / sched.c
index ba4c88088f62c53ab8ec414e3d77da65b1cd9f67..56ea3a203a5ae46c194bd8aa5220c5c927844bf9 100644 (file)
 #include <linux/unistd.h>
 #include <linux/pagemap.h>
 #include <linux/hrtimer.h>
+#include <linux/tick.h>
+#include <linux/bootmem.h>
+#include <linux/debugfs.h>
+#include <linux/ctype.h>
 
 #include <asm/tlb.h>
 #include <asm/irq_regs.h>
 
-/*
- * Scheduler clock - returns current time in nanosec units.
- * This is default implementation.
- * Architectures and sub-architectures can override this.
- */
-unsigned long long __attribute__((weak)) sched_clock(void)
-{
-       return (unsigned long long)jiffies * (NSEC_PER_SEC / HZ);
-}
-
 /*
  * Convert user-nice values [ -20 ... 0 ... 19 ]
  * to static priority [ MAX_RT_PRIO..MAX_PRIO-1 ],
@@ -114,6 +108,11 @@ unsigned long long __attribute__((weak)) sched_clock(void)
  */
 #define DEF_TIMESLICE          (100 * HZ / 1000)
 
+/*
+ * single value that denotes runtime == period, ie unlimited time.
+ */
+#define RUNTIME_INF    ((u64)~0ULL)
+
 #ifdef CONFIG_SMP
 /*
  * Divide a load by a sched group cpu_power : (load / sg->__cpu_power)
@@ -155,7 +154,91 @@ struct rt_prio_array {
        struct list_head queue[MAX_RT_PRIO];
 };
 
-#ifdef CONFIG_FAIR_GROUP_SCHED
+struct rt_bandwidth {
+       /* nests inside the rq lock: */
+       spinlock_t              rt_runtime_lock;
+       ktime_t                 rt_period;
+       u64                     rt_runtime;
+       struct hrtimer          rt_period_timer;
+};
+
+static struct rt_bandwidth def_rt_bandwidth;
+
+static int do_sched_rt_period_timer(struct rt_bandwidth *rt_b, int overrun);
+
+static enum hrtimer_restart sched_rt_period_timer(struct hrtimer *timer)
+{
+       struct rt_bandwidth *rt_b =
+               container_of(timer, struct rt_bandwidth, rt_period_timer);
+       ktime_t now;
+       int overrun;
+       int idle = 0;
+
+       for (;;) {
+               now = hrtimer_cb_get_time(timer);
+               overrun = hrtimer_forward(timer, now, rt_b->rt_period);
+
+               if (!overrun)
+                       break;
+
+               idle = do_sched_rt_period_timer(rt_b, overrun);
+       }
+
+       return idle ? HRTIMER_NORESTART : HRTIMER_RESTART;
+}
+
+static
+void init_rt_bandwidth(struct rt_bandwidth *rt_b, u64 period, u64 runtime)
+{
+       rt_b->rt_period = ns_to_ktime(period);
+       rt_b->rt_runtime = runtime;
+
+       spin_lock_init(&rt_b->rt_runtime_lock);
+
+       hrtimer_init(&rt_b->rt_period_timer,
+                       CLOCK_MONOTONIC, HRTIMER_MODE_REL);
+       rt_b->rt_period_timer.function = sched_rt_period_timer;
+       rt_b->rt_period_timer.cb_mode = HRTIMER_CB_IRQSAFE_NO_SOFTIRQ;
+}
+
+static void start_rt_bandwidth(struct rt_bandwidth *rt_b)
+{
+       ktime_t now;
+
+       if (rt_b->rt_runtime == RUNTIME_INF)
+               return;
+
+       if (hrtimer_active(&rt_b->rt_period_timer))
+               return;
+
+       spin_lock(&rt_b->rt_runtime_lock);
+       for (;;) {
+               if (hrtimer_active(&rt_b->rt_period_timer))
+                       break;
+
+               now = hrtimer_cb_get_time(&rt_b->rt_period_timer);
+               hrtimer_forward(&rt_b->rt_period_timer, now, rt_b->rt_period);
+               hrtimer_start(&rt_b->rt_period_timer,
+                             rt_b->rt_period_timer.expires,
+                             HRTIMER_MODE_ABS);
+       }
+       spin_unlock(&rt_b->rt_runtime_lock);
+}
+
+#ifdef CONFIG_RT_GROUP_SCHED
+static void destroy_rt_bandwidth(struct rt_bandwidth *rt_b)
+{
+       hrtimer_cancel(&rt_b->rt_period_timer);
+}
+#endif
+
+/*
+ * sched_domains_mutex serializes calls to arch_init_sched_domains,
+ * detach_destroy_domains and partition_sched_domains.
+ */
+static DEFINE_MUTEX(sched_domains_mutex);
+
+#ifdef CONFIG_GROUP_SCHED
 
 #include <linux/cgroup.h>
 
@@ -165,118 +248,93 @@ static LIST_HEAD(task_groups);
 
 /* task group related information */
 struct task_group {
-#ifdef CONFIG_FAIR_CGROUP_SCHED
+#ifdef CONFIG_CGROUP_SCHED
        struct cgroup_subsys_state css;
 #endif
+
+#ifdef CONFIG_FAIR_GROUP_SCHED
        /* schedulable entities of this group on each cpu */
        struct sched_entity **se;
        /* runqueue "owned" by this group on each cpu */
        struct cfs_rq **cfs_rq;
+       unsigned long shares;
+#endif
 
+#ifdef CONFIG_RT_GROUP_SCHED
        struct sched_rt_entity **rt_se;
        struct rt_rq **rt_rq;
 
-       unsigned int rt_ratio;
-
-       /*
-        * shares assigned to a task group governs how much of cpu bandwidth
-        * is allocated to the group. The more shares a group has, the more is
-        * the cpu bandwidth allocated to it.
-        *
-        * For ex, lets say that there are three task groups, A, B and C which
-        * have been assigned shares 1000, 2000 and 3000 respectively. Then,
-        * cpu bandwidth allocated by the scheduler to task groups A, B and C
-        * should be:
-        *
-        *      Bw(A) = 1000/(1000+2000+3000) * 100 = 16.66%
-        *      Bw(B) = 2000/(1000+2000+3000) * 100 = 33.33%
-        *      Bw(C) = 3000/(1000+2000+3000) * 100 = 50%
-        *
-        * The weight assigned to a task group's schedulable entities on every
-        * cpu (task_group.se[a_cpu]->load.weight) is derived from the task
-        * group's shares. For ex: lets say that task group A has been
-        * assigned shares of 1000 and there are two CPUs in a system. Then,
-        *
-        *  tg_A->se[0]->load.weight = tg_A->se[1]->load.weight = 1000;
-        *
-        * Note: It's not necessary that each of a task's group schedulable
-        *       entity have the same weight on all CPUs. If the group
-        *       has 2 of its tasks on CPU0 and 1 task on CPU1, then a
-        *       better distribution of weight could be:
-        *
-        *      tg_A->se[0]->load.weight = 2/3 * 2000 = 1333
-        *      tg_A->se[1]->load.weight = 1/2 * 2000 =  667
-        *
-        * rebalance_shares() is responsible for distributing the shares of a
-        * task groups like this among the group's schedulable entities across
-        * cpus.
-        *
-        */
-       unsigned long shares;
+       struct rt_bandwidth rt_bandwidth;
+#endif
 
        struct rcu_head rcu;
        struct list_head list;
+
+       struct task_group *parent;
+       struct list_head siblings;
+       struct list_head children;
 };
 
+#ifdef CONFIG_USER_SCHED
+
+/*
+ * Root task group.
+ *     Every UID task group (including init_task_group aka UID-0) will
+ *     be a child to this group.
+ */
+struct task_group root_task_group;
+
+#ifdef CONFIG_FAIR_GROUP_SCHED
 /* Default task group's sched entity on each cpu */
 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
 
+#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;
-
-static struct sched_entity *init_sched_entity_p[NR_CPUS];
-static struct cfs_rq *init_cfs_rq_p[NR_CPUS];
-
-static struct sched_rt_entity *init_sched_rt_entity_p[NR_CPUS];
-static struct rt_rq *init_rt_rq_p[NR_CPUS];
-
-/* task_group_mutex serializes add/remove of task groups and also changes to
- * a task group's cpu shares.
- */
-static DEFINE_MUTEX(task_group_mutex);
-
-/* doms_cur_mutex serializes access to doms_cur[] array */
-static DEFINE_MUTEX(doms_cur_mutex);
-
-#ifdef CONFIG_SMP
-/* kernel thread that runs rebalance_shares() periodically */
-static struct task_struct *lb_monitor_task;
-static int load_balance_monitor(void *unused);
+#endif
+#else
+#define root_task_group init_task_group
 #endif
 
-static void set_se_shares(struct sched_entity *se, unsigned long shares);
-
-/* Default task group.
- *     Every task in system belong to this group at bootup.
+/* task_group_lock serializes add/remove of task groups and also changes to
+ * a task group's cpu shares.
  */
-struct task_group init_task_group = {
-       .se     = init_sched_entity_p,
-       .cfs_rq = init_cfs_rq_p,
-
-       .rt_se  = init_sched_rt_entity_p,
-       .rt_rq  = init_rt_rq_p,
-};
+static DEFINE_SPINLOCK(task_group_lock);
 
-#ifdef CONFIG_FAIR_USER_SCHED
+#ifdef CONFIG_FAIR_GROUP_SCHED
+#ifdef CONFIG_USER_SCHED
 # define INIT_TASK_GROUP_LOAD  (2*NICE_0_LOAD)
 #else
 # define INIT_TASK_GROUP_LOAD  NICE_0_LOAD
 #endif
 
-#define MIN_GROUP_SHARES       2
+/*
+ * A weight of 0, 1 or ULONG_MAX can cause arithmetics problems.
+ * (The default weight is 1024 - so there's no practical
+ *  limitation from this.)
+ */
+#define MIN_SHARES     2
+#define MAX_SHARES     (ULONG_MAX - 1)
 
 static int init_task_group_load = INIT_TASK_GROUP_LOAD;
+#endif
+
+/* Default task group.
+ *     Every task in system belong to this group at bootup.
+ */
+struct task_group init_task_group;
 
 /* return group to which a task belongs */
 static inline struct task_group *task_group(struct task_struct *p)
 {
        struct task_group *tg;
 
-#ifdef CONFIG_FAIR_USER_SCHED
+#ifdef CONFIG_USER_SCHED
        tg = p->user->tg;
-#elif defined(CONFIG_FAIR_CGROUP_SCHED)
+#elif defined(CONFIG_CGROUP_SCHED)
        tg = container_of(task_subsys_state(p, cpu_cgroup_subsys_id),
                                struct task_group, css);
 #else
@@ -288,42 +346,22 @@ static inline struct task_group *task_group(struct task_struct *p)
 /* Change a task's cfs_rq and parent entity if it moves across CPUs/groups */
 static inline void set_task_rq(struct task_struct *p, unsigned int cpu)
 {
+#ifdef CONFIG_FAIR_GROUP_SCHED
        p->se.cfs_rq = task_group(p)->cfs_rq[cpu];
        p->se.parent = task_group(p)->se[cpu];
+#endif
 
+#ifdef CONFIG_RT_GROUP_SCHED
        p->rt.rt_rq  = task_group(p)->rt_rq[cpu];
        p->rt.parent = task_group(p)->rt_se[cpu];
-}
-
-static inline void lock_task_group_list(void)
-{
-       mutex_lock(&task_group_mutex);
-}
-
-static inline void unlock_task_group_list(void)
-{
-       mutex_unlock(&task_group_mutex);
-}
-
-static inline void lock_doms_cur(void)
-{
-       mutex_lock(&doms_cur_mutex);
-}
-
-static inline void unlock_doms_cur(void)
-{
-       mutex_unlock(&doms_cur_mutex);
+#endif
 }
 
 #else
 
 static inline void set_task_rq(struct task_struct *p, unsigned int cpu) { }
-static inline void lock_task_group_list(void) { }
-static inline void unlock_task_group_list(void) { }
-static inline void lock_doms_cur(void) { }
-static inline void unlock_doms_cur(void) { }
 
-#endif /* CONFIG_FAIR_GROUP_SCHED */
+#endif /* CONFIG_GROUP_SCHED */
 
 /* CFS-related fields in a runqueue */
 struct cfs_rq {
@@ -335,11 +373,15 @@ struct cfs_rq {
 
        struct rb_root tasks_timeline;
        struct rb_node *rb_leftmost;
-       struct rb_node *rb_load_balance_curr;
-       /* 'curr' points to currently running entity on this cfs_rq.
+
+       struct list_head tasks;
+       struct list_head *balance_iterator;
+
+       /*
+        * 'curr' points to currently running entity on this cfs_rq.
         * It is set to NULL otherwise (i.e when none are currently running).
         */
-       struct sched_entity *curr;
+       struct sched_entity *curr, *next;
 
        unsigned long nr_spread_over;
 
@@ -356,6 +398,43 @@ struct cfs_rq {
         */
        struct list_head leaf_cfs_rq_list;
        struct task_group *tg;  /* group that "owns" this runqueue */
+
+#ifdef CONFIG_SMP
+       unsigned long task_weight;
+       unsigned long shares;
+       /*
+        * We need space to build a sched_domain wide view of the full task
+        * group tree, in order to avoid depending on dynamic memory allocation
+        * during the load balancing we place this in the per cpu task group
+        * hierarchy. This limits the load balancing to one instance per cpu,
+        * but more should not be needed anyway.
+        */
+       struct aggregate_struct {
+               /*
+                *   load = weight(cpus) * f(tg)
+                *
+                * Where f(tg) is the recursive weight fraction assigned to
+                * this group.
+                */
+               unsigned long load;
+
+               /*
+                * part of the group weight distributed to this span.
+                */
+               unsigned long shares;
+
+               /*
+                * The sum of all runqueue weights within this span.
+                */
+               unsigned long rq_weight;
+
+               /*
+                * Weight contributed by tasks; this is the part we can
+                * influence by moving tasks around.
+                */
+               unsigned long task_weight;
+       } aggregate;
+#endif
 #endif
 };
 
@@ -363,7 +442,7 @@ struct cfs_rq {
 struct rt_rq {
        struct rt_prio_array active;
        unsigned long rt_nr_running;
-#if defined CONFIG_SMP || defined CONFIG_FAIR_GROUP_SCHED
+#if defined CONFIG_SMP || defined CONFIG_RT_GROUP_SCHED
        int highest_prio; /* highest queued rt task prio */
 #endif
 #ifdef CONFIG_SMP
@@ -372,8 +451,13 @@ struct rt_rq {
 #endif
        int rt_throttled;
        u64 rt_time;
+       u64 rt_runtime;
+       /* Nests inside the rq lock: */
+       spinlock_t rt_runtime_lock;
+
+#ifdef CONFIG_RT_GROUP_SCHED
+       unsigned long rt_nr_boosted;
 
-#ifdef CONFIG_FAIR_GROUP_SCHED
        struct rq *rq;
        struct list_head leaf_rt_rq_list;
        struct task_group *tg;
@@ -432,6 +516,7 @@ struct rq {
        unsigned long cpu_load[CPU_LOAD_IDX_MAX];
        unsigned char idle_at_tick;
 #ifdef CONFIG_NO_HZ
+       unsigned long last_tick_seen;
        unsigned char in_nohz_recently;
 #endif
        /* capture load from *all* tasks on this cpu: */
@@ -441,12 +526,12 @@ struct rq {
 
        struct cfs_rq cfs;
        struct rt_rq rt;
-       u64 rt_period_expire;
-       int rt_throttled;
 
 #ifdef CONFIG_FAIR_GROUP_SCHED
        /* list of leaf cfs_rq on this cpu: */
        struct list_head leaf_cfs_rq_list;
+#endif
+#ifdef CONFIG_RT_GROUP_SCHED
        struct list_head leaf_rt_rq_list;
 #endif
 
@@ -462,13 +547,7 @@ struct rq {
        unsigned long next_balance;
        struct mm_struct *prev_mm;
 
-       u64 clock, prev_clock_raw;
-       s64 clock_max_delta;
-
-       unsigned int clock_warps, clock_overflows, clock_underflows;
-       u64 idle_clock;
-       unsigned int clock_deep_idle_events;
-       u64 tick_timestamp;
+       u64 clock;
 
        atomic_t nr_iowait;
 
@@ -533,53 +612,6 @@ static inline int cpu_of(struct rq *rq)
 #endif
 }
 
-/*
- * Update the per-runqueue clock, as finegrained as the platform can give
- * us, but without assuming monotonicity, etc.:
- */
-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:
-        */
-       if (unlikely(delta < 0)) {
-               clock++;
-               rq->clock_warps++;
-       } else {
-               /*
-                * Catch too large forward jumps too:
-                */
-               if (unlikely(clock + delta > rq->tick_timestamp + TICK_NSEC)) {
-                       if (clock < rq->tick_timestamp + TICK_NSEC)
-                               clock = rq->tick_timestamp + TICK_NSEC;
-                       else
-                               clock++;
-                       rq->clock_overflows++;
-               } else {
-                       if (unlikely(delta > rq->clock_max_delta))
-                               rq->clock_max_delta = delta;
-                       clock += delta;
-               }
-       }
-
-       rq->prev_clock_raw = now;
-       rq->clock = clock;
-}
-
-static void update_rq_clock(struct rq *rq)
-{
-       if (likely(smp_processor_id() == cpu_of(rq)))
-               __update_rq_clock(rq);
-}
-
 /*
  * The domain tree (rq->sd) is protected by RCU's quiescent state transition.
  * See detach_destroy_domains: synchronize_sched for details.
@@ -595,21 +627,9 @@ static void update_rq_clock(struct rq *rq)
 #define task_rq(p)             cpu_rq(task_cpu(p))
 #define cpu_curr(cpu)          (cpu_rq(cpu)->curr)
 
-unsigned long rt_needs_cpu(int cpu)
+static inline void update_rq_clock(struct rq *rq)
 {
-       struct rq *rq = cpu_rq(cpu);
-       u64 delta;
-
-       if (!rq->rt_throttled)
-               return 0;
-
-       if (rq->clock > rq->rt_period_expire)
-               return 1;
-
-       delta = rq->rt_period_expire - rq->clock;
-       do_div(delta, NSEC_PER_SEC / HZ);
-
-       return (unsigned long)delta;
+       rq->clock = sched_clock_cpu(cpu_of(rq));
 }
 
 /*
@@ -624,26 +644,137 @@ unsigned long rt_needs_cpu(int cpu)
 /*
  * Debugging: various feature bits
  */
+
+#define SCHED_FEAT(name, enabled)      \
+       __SCHED_FEAT_##name ,
+
 enum {
-       SCHED_FEAT_NEW_FAIR_SLEEPERS    = 1,
-       SCHED_FEAT_WAKEUP_PREEMPT       = 2,
-       SCHED_FEAT_START_DEBIT          = 4,
-       SCHED_FEAT_TREE_AVG             = 8,
-       SCHED_FEAT_APPROX_AVG           = 16,
-       SCHED_FEAT_HRTICK               = 32,
-       SCHED_FEAT_DOUBLE_TICK          = 64,
+#include "sched_features.h"
 };
 
+#undef SCHED_FEAT
+
+#define SCHED_FEAT(name, enabled)      \
+       (1UL << __SCHED_FEAT_##name) * enabled |
+
 const_debug unsigned int sysctl_sched_features =
-               SCHED_FEAT_NEW_FAIR_SLEEPERS    * 1 |
-               SCHED_FEAT_WAKEUP_PREEMPT       * 1 |
-               SCHED_FEAT_START_DEBIT          * 1 |
-               SCHED_FEAT_TREE_AVG             * 0 |
-               SCHED_FEAT_APPROX_AVG           * 0 |
-               SCHED_FEAT_HRTICK               * 1 |
-               SCHED_FEAT_DOUBLE_TICK          * 0;
+#include "sched_features.h"
+       0;
+
+#undef SCHED_FEAT
+
+#ifdef CONFIG_SCHED_DEBUG
+#define SCHED_FEAT(name, enabled)      \
+       #name ,
+
+static __read_mostly char *sched_feat_names[] = {
+#include "sched_features.h"
+       NULL
+};
+
+#undef SCHED_FEAT
+
+static int sched_feat_open(struct inode *inode, struct file *filp)
+{
+       filp->private_data = inode->i_private;
+       return 0;
+}
+
+static ssize_t
+sched_feat_read(struct file *filp, char __user *ubuf,
+               size_t cnt, loff_t *ppos)
+{
+       char *buf;
+       int r = 0;
+       int len = 0;
+       int i;
+
+       for (i = 0; sched_feat_names[i]; i++) {
+               len += strlen(sched_feat_names[i]);
+               len += 4;
+       }
+
+       buf = kmalloc(len + 2, GFP_KERNEL);
+       if (!buf)
+               return -ENOMEM;
+
+       for (i = 0; sched_feat_names[i]; i++) {
+               if (sysctl_sched_features & (1UL << i))
+                       r += sprintf(buf + r, "%s ", sched_feat_names[i]);
+               else
+                       r += sprintf(buf + r, "NO_%s ", sched_feat_names[i]);
+       }
+
+       r += sprintf(buf + r, "\n");
+       WARN_ON(r >= len + 2);
+
+       r = simple_read_from_buffer(ubuf, cnt, ppos, buf, r);
 
-#define sched_feat(x) (sysctl_sched_features & SCHED_FEAT_##x)
+       kfree(buf);
+
+       return r;
+}
+
+static ssize_t
+sched_feat_write(struct file *filp, const char __user *ubuf,
+               size_t cnt, loff_t *ppos)
+{
+       char buf[64];
+       char *cmp = buf;
+       int neg = 0;
+       int i;
+
+       if (cnt > 63)
+               cnt = 63;
+
+       if (copy_from_user(&buf, ubuf, cnt))
+               return -EFAULT;
+
+       buf[cnt] = 0;
+
+       if (strncmp(buf, "NO_", 3) == 0) {
+               neg = 1;
+               cmp += 3;
+       }
+
+       for (i = 0; sched_feat_names[i]; i++) {
+               int len = strlen(sched_feat_names[i]);
+
+               if (strncmp(cmp, sched_feat_names[i], len) == 0) {
+                       if (neg)
+                               sysctl_sched_features &= ~(1UL << i);
+                       else
+                               sysctl_sched_features |= (1UL << i);
+                       break;
+               }
+       }
+
+       if (!sched_feat_names[i])
+               return -EINVAL;
+
+       filp->f_pos += cnt;
+
+       return cnt;
+}
+
+static struct file_operations sched_feat_fops = {
+       .open   = sched_feat_open,
+       .read   = sched_feat_read,
+       .write  = sched_feat_write,
+};
+
+static __init int sched_init_debug(void)
+{
+       debugfs_create_file("sched_features", 0644, NULL, NULL,
+                       &sched_feat_fops);
+
+       return 0;
+}
+late_initcall(sched_init_debug);
+
+#endif
+
+#define sched_feat(x) (sysctl_sched_features & (1UL << __SCHED_FEAT_##x))
 
 /*
  * Number of tasks to iterate in a single balance run.
@@ -652,44 +783,107 @@ const_debug unsigned int sysctl_sched_features =
 const_debug unsigned int sysctl_sched_nr_migrate = 32;
 
 /*
- * period over which we measure -rt task cpu usage in ms.
+ * period over which we measure -rt task cpu usage in us.
  * default: 1s
  */
-const_debug unsigned int sysctl_sched_rt_period = 1000;
+unsigned int sysctl_sched_rt_period = 1000000;
 
-#define SCHED_RT_FRAC_SHIFT    16
-#define SCHED_RT_FRAC          (1UL << SCHED_RT_FRAC_SHIFT)
+static __read_mostly int scheduler_running;
 
 /*
- * ratio of time -rt tasks may consume.
- * default: 95%
+ * part of the period that we allow rt tasks to run in us.
+ * default: 0.95s
  */
-const_debug unsigned int sysctl_sched_rt_ratio = 62259;
+int sysctl_sched_rt_runtime = 950000;
+
+static inline u64 global_rt_period(void)
+{
+       return (u64)sysctl_sched_rt_period * NSEC_PER_USEC;
+}
+
+static inline u64 global_rt_runtime(void)
+{
+       if (sysctl_sched_rt_period < 0)
+               return RUNTIME_INF;
+
+       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);
 
 /*
- * For kernel-internal use: high-speed (but slightly incorrect) per-cpu
- * clock constructed from sched_clock():
+ * 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:
  */
-unsigned long long cpu_clock(int cpu)
+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;
-       unsigned long flags;
-       struct rq *rq;
 
-       local_irq_save(flags);
-       rq = cpu_rq(cpu);
        /*
         * Only call sched_clock() if the scheduler has already been
         * initialized (some code might call cpu_clock() very early):
         */
-       if (rq->idle)
-               update_rq_clock(rq);
-       now = rq->clock;
-       local_irq_restore(flags);
+       if (unlikely(!scheduler_running))
+               return 0;
+
+       now = sched_clock_cpu(cpu);
 
        return now;
 }
-EXPORT_SYMBOL_GPL(cpu_clock);
+
+/*
+ * 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)
@@ -836,43 +1030,6 @@ static struct rq *this_rq_lock(void)
        return rq;
 }
 
-/*
- * We are going deep-idle (irqs are disabled):
- */
-void sched_clock_idle_sleep_event(void)
-{
-       struct rq *rq = cpu_rq(smp_processor_id());
-
-       spin_lock(&rq->lock);
-       __update_rq_clock(rq);
-       spin_unlock(&rq->lock);
-       rq->clock_deep_idle_events++;
-}
-EXPORT_SYMBOL_GPL(sched_clock_idle_sleep_event);
-
-/*
- * We just idled delta nanoseconds (called with irqs disabled):
- */
-void sched_clock_idle_wakeup_event(u64 delta_ns)
-{
-       struct rq *rq = cpu_rq(smp_processor_id());
-       u64 now = sched_clock();
-
-       rq->idle_clock += delta_ns;
-       /*
-        * Override the previous timestamp and ignore all
-        * sched_clock() deltas that occured while we idled,
-        * and use the PM-provided delta_ns to advance the
-        * rq clock:
-        */
-       spin_lock(&rq->lock);
-       rq->prev_clock_raw = now;
-       rq->clock += delta_ns;
-       spin_unlock(&rq->lock);
-       touch_softlockup_watchdog();
-}
-EXPORT_SYMBOL_GPL(sched_clock_idle_wakeup_event);
-
 static void __resched_task(struct task_struct *p, int tif_bit);
 
 static inline void resched_task(struct task_struct *p)
@@ -908,6 +1065,7 @@ static inline void resched_rq(struct rq *rq)
 enum {
        HRTICK_SET,             /* re-programm hrtick_timer */
        HRTICK_RESET,           /* not a new slice */
+       HRTICK_BLOCK,           /* stop hrtick operations */
 };
 
 /*
@@ -919,6 +1077,8 @@ static inline int hrtick_enabled(struct rq *rq)
 {
        if (!sched_feat(HRTICK))
                return 0;
+       if (unlikely(test_bit(HRTICK_BLOCK, &rq->hrtick_flags)))
+               return 0;
        return hrtimer_is_hres_active(&rq->hrtick_timer);
 }
 
@@ -994,14 +1154,70 @@ static enum hrtimer_restart hrtick(struct hrtimer *timer)
        WARN_ON_ONCE(cpu_of(rq) != smp_processor_id());
 
        spin_lock(&rq->lock);
-       __update_rq_clock(rq);
+       update_rq_clock(rq);
        rq->curr->sched_class->task_tick(rq, rq->curr, 1);
        spin_unlock(&rq->lock);
 
        return HRTIMER_NORESTART;
 }
 
-static inline void init_rq_hrtick(struct rq *rq)
+static void hotplug_hrtick_disable(int cpu)
+{
+       struct rq *rq = cpu_rq(cpu);
+       unsigned long flags;
+
+       spin_lock_irqsave(&rq->lock, flags);
+       rq->hrtick_flags = 0;
+       __set_bit(HRTICK_BLOCK, &rq->hrtick_flags);
+       spin_unlock_irqrestore(&rq->lock, flags);
+
+       hrtick_clear(rq);
+}
+
+static void hotplug_hrtick_enable(int cpu)
+{
+       struct rq *rq = cpu_rq(cpu);
+       unsigned long flags;
+
+       spin_lock_irqsave(&rq->lock, flags);
+       __clear_bit(HRTICK_BLOCK, &rq->hrtick_flags);
+       spin_unlock_irqrestore(&rq->lock, flags);
+}
+
+static int
+hotplug_hrtick(struct notifier_block *nfb, unsigned long action, void *hcpu)
+{
+       int cpu = (int)(long)hcpu;
+
+       switch (action) {
+       case CPU_UP_CANCELED:
+       case CPU_UP_CANCELED_FROZEN:
+       case CPU_DOWN_PREPARE:
+       case CPU_DOWN_PREPARE_FROZEN:
+       case CPU_DEAD:
+       case CPU_DEAD_FROZEN:
+               hotplug_hrtick_disable(cpu);
+               return NOTIFY_OK;
+
+       case CPU_UP_PREPARE:
+       case CPU_UP_PREPARE_FROZEN:
+       case CPU_DOWN_FAILED:
+       case CPU_DOWN_FAILED_FROZEN:
+       case CPU_ONLINE:
+       case CPU_ONLINE_FROZEN:
+               hotplug_hrtick_enable(cpu);
+               return NOTIFY_OK;
+       }
+
+       return NOTIFY_DONE;
+}
+
+static void init_hrtick(void)
+{
+       hotcpu_notifier(hotplug_hrtick, 0);
+}
+
+static void init_rq_hrtick(struct rq *rq)
 {
        rq->hrtick_flags = 0;
        hrtimer_init(&rq->hrtick_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
@@ -1038,6 +1254,10 @@ static inline void init_rq_hrtick(struct rq *rq)
 void hrtick_resched(void)
 {
 }
+
+static inline void init_hrtick(void)
+{
+}
 #endif
 
 /*
@@ -1084,6 +1304,49 @@ static void resched_cpu(int cpu)
        resched_task(cpu_curr(cpu));
        spin_unlock_irqrestore(&rq->lock, flags);
 }
+
+#ifdef CONFIG_NO_HZ
+/*
+ * When add_timer_on() enqueues a timer into the timer wheel of an
+ * idle CPU then this timer might expire before the next timer event
+ * which is scheduled to wake up that CPU. In case of a completely
+ * idle system the next event might even be infinite time into the
+ * future. wake_up_idle_cpu() ensures that the CPU is woken up and
+ * leaves the inner idle loop so the newly added timer is taken into
+ * account when the CPU goes back to idle and evaluates the timer
+ * wheel for the next timer event.
+ */
+void wake_up_idle_cpu(int cpu)
+{
+       struct rq *rq = cpu_rq(cpu);
+
+       if (cpu == smp_processor_id())
+               return;
+
+       /*
+        * This is safe, as this function is called with the timer
+        * wheel base lock of (cpu) held. When the CPU is on the way
+        * to idle and has not yet set rq->curr to idle then it will
+        * be serialized on the timer wheel base lock and take the new
+        * timer into account automatically.
+        */
+       if (rq->curr != rq->idle)
+               return;
+
+       /*
+        * We can set TIF_RESCHED on the idle task of the other CPU
+        * lockless. The worst case is that the other CPU runs the
+        * idle task through an additional NOOP schedule()
+        */
+       set_tsk_thread_flag(rq->idle, TIF_NEED_RESCHED);
+
+       /* NEED_RESCHED must be visible before we test polling */
+       smp_mb();
+       if (!tsk_is_polling(rq->idle))
+               smp_send_reschedule(cpu);
+}
+#endif
+
 #else
 static void __resched_task(struct task_struct *p, int tif_bit)
 {
@@ -1105,14 +1368,17 @@ static void __resched_task(struct task_struct *p, int tif_bit)
  */
 #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)
 {
        u64 tmp;
 
-       if (unlikely(!lw->inv_weight))
-               lw->inv_weight = (WMULT_CONST - lw->weight/2) / lw->weight + 1;
+       if (!lw->inv_weight)
+               lw->inv_weight = 1 + (WMULT_CONST-lw->weight/2)/(lw->weight+1);
 
        tmp = (u64)delta_exec * weight;
        /*
@@ -1127,20 +1393,16 @@ calc_delta_mine(unsigned long delta_exec, unsigned long weight,
        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;
+       lw->inv_weight = 0;
 }
 
 static inline void update_load_sub(struct load_weight *lw, unsigned long dec)
 {
        lw->weight -= dec;
+       lw->inv_weight = 0;
 }
 
 /*
@@ -1243,139 +1505,467 @@ 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"
-#include "sched_rt.c"
-#ifdef CONFIG_SCHED_DEBUG
-# include "sched_debug.c"
-#endif
+#ifdef CONFIG_FAIR_GROUP_SCHED
 
-#define sched_class_highest (&rt_sched_class)
+/*
+ * Group load balancing.
+ *
+ * We calculate a few balance domain wide aggregate numbers; load and weight.
+ * Given the pictures below, and assuming each item has equal weight:
+ *
+ *         root          1 - thread
+ *         / | \         A - group
+ *        A  1  B
+ *       /|\   / \
+ *      C 2 D 3   4
+ *      |   |
+ *      5   6
+ *
+ * load:
+ *    A and B get 1/3-rd of the total load. C and D get 1/3-rd of A's 1/3-rd,
+ *    which equals 1/9-th of the total load.
+ *
+ * shares:
+ *    The weight of this group on the selected cpus.
+ *
+ * rq_weight:
+ *    Direct sum of all the cpu's their rq weight, e.g. A would get 3 while
+ *    B would get 2.
+ *
+ * task_weight:
+ *    Part of the rq_weight contributed by tasks; all groups except B would
+ *    get 1, B gets 2.
+ */
 
-static void inc_nr_running(struct task_struct *p, struct rq *rq)
+static inline struct aggregate_struct *
+aggregate(struct task_group *tg, struct sched_domain *sd)
 {
-       rq->nr_running++;
+       return &tg->cfs_rq[sd->first_cpu]->aggregate;
 }
 
-static void dec_nr_running(struct task_struct *p, struct rq *rq)
-{
-       rq->nr_running--;
-}
+typedef void (*aggregate_func)(struct task_group *, struct sched_domain *);
 
-static void set_load_weight(struct task_struct *p)
+/*
+ * Iterate the full tree, calling @down when first entering a node and @up when
+ * leaving it for the final time.
+ */
+static
+void aggregate_walk_tree(aggregate_func down, aggregate_func up,
+                        struct sched_domain *sd)
 {
-       if (task_has_rt_policy(p)) {
-               p->se.load.weight = prio_to_weight[0] * 2;
-               p->se.load.inv_weight = prio_to_wmult[0] >> 1;
-               return;
-       }
+       struct task_group *parent, *child;
 
-       /*
-        * SCHED_IDLE tasks get minimal weight:
-        */
-       if (p->policy == SCHED_IDLE) {
-               p->se.load.weight = WEIGHT_IDLEPRIO;
-               p->se.load.inv_weight = WMULT_IDLEPRIO;
-               return;
-       }
-
-       p->se.load.weight = prio_to_weight[p->static_prio - MAX_RT_PRIO];
-       p->se.load.inv_weight = prio_to_wmult[p->static_prio - MAX_RT_PRIO];
+       rcu_read_lock();
+       parent = &root_task_group;
+down:
+       (*down)(parent, sd);
+       list_for_each_entry_rcu(child, &parent->children, siblings) {
+               parent = child;
+               goto down;
+
+up:
+               continue;
+       }
+       (*up)(parent, sd);
+
+       child = parent;
+       parent = parent->parent;
+       if (parent)
+               goto up;
+       rcu_read_unlock();
 }
 
-static void enqueue_task(struct rq *rq, struct task_struct *p, int wakeup)
+/*
+ * Calculate the aggregate runqueue weight.
+ */
+static
+void aggregate_group_weight(struct task_group *tg, struct sched_domain *sd)
 {
-       sched_info_queued(p);
-       p->sched_class->enqueue_task(rq, p, wakeup);
-       p->se.on_rq = 1;
-}
+       unsigned long rq_weight = 0;
+       unsigned long task_weight = 0;
+       int i;
 
-static void dequeue_task(struct rq *rq, struct task_struct *p, int sleep)
-{
-       p->sched_class->dequeue_task(rq, p, sleep);
-       p->se.on_rq = 0;
+       for_each_cpu_mask(i, sd->span) {
+               rq_weight += tg->cfs_rq[i]->load.weight;
+               task_weight += tg->cfs_rq[i]->task_weight;
+       }
+
+       aggregate(tg, sd)->rq_weight = rq_weight;
+       aggregate(tg, sd)->task_weight = task_weight;
 }
 
 /*
- * __normal_prio - return the priority that is based on the static prio
+ * Compute the weight of this group on the given cpus.
  */
-static inline int __normal_prio(struct task_struct *p)
+static
+void aggregate_group_shares(struct task_group *tg, struct sched_domain *sd)
 {
-       return p->static_prio;
+       unsigned long shares = 0;
+       int i;
+
+       for_each_cpu_mask(i, sd->span)
+               shares += tg->cfs_rq[i]->shares;
+
+       if ((!shares && aggregate(tg, sd)->rq_weight) || shares > tg->shares)
+               shares = tg->shares;
+
+       aggregate(tg, sd)->shares = shares;
 }
 
 /*
- * Calculate the expected normal priority: i.e. priority
- * without taking RT-inheritance into account. Might be
- * boosted by interactivity modifiers. Changes upon fork,
- * setprio syscalls, and whenever the interactivity
- * estimator recalculates.
+ * Compute the load fraction assigned to this group, relies on the aggregate
+ * weight and this group's parent's load, i.e. top-down.
  */
-static inline int normal_prio(struct task_struct *p)
+static
+void aggregate_group_load(struct task_group *tg, struct sched_domain *sd)
 {
-       int prio;
+       unsigned long load;
 
-       if (task_has_rt_policy(p))
-               prio = MAX_RT_PRIO-1 - p->rt_priority;
-       else
-               prio = __normal_prio(p);
-       return prio;
+       if (!tg->parent) {
+               int i;
+
+               load = 0;
+               for_each_cpu_mask(i, sd->span)
+                       load += cpu_rq(i)->load.weight;
+
+       } else {
+               load = aggregate(tg->parent, sd)->load;
+
+               /*
+                * shares is our weight in the parent's rq so
+                * shares/parent->rq_weight gives our fraction of the load
+                */
+               load *= aggregate(tg, sd)->shares;
+               load /= aggregate(tg->parent, sd)->rq_weight + 1;
+       }
+
+       aggregate(tg, sd)->load = load;
 }
 
+static void __set_se_shares(struct sched_entity *se, unsigned long shares);
+
 /*
- * Calculate the current priority, i.e. the priority
- * taken into account by the scheduler. This value might
- * be boosted by RT tasks, or might be boosted by
- * interactivity modifiers. Will be RT if the task got
- * RT-boosted. If not then it returns p->normal_prio.
+ * Calculate and set the cpu's group shares.
  */
-static int effective_prio(struct task_struct *p)
+static void
+__update_group_shares_cpu(struct task_group *tg, struct sched_domain *sd,
+                         int tcpu)
 {
-       p->normal_prio = normal_prio(p);
+       int boost = 0;
+       unsigned long shares;
+       unsigned long rq_weight;
+
+       if (!tg->se[tcpu])
+               return;
+
+       rq_weight = tg->cfs_rq[tcpu]->load.weight;
+
        /*
-        * If we are RT tasks or we were boosted to RT priority,
-        * keep the priority unchanged. Otherwise, update priority
-        * to the normal priority:
+        * 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 (!rt_prio(p->prio))
-               return p->normal_prio;
-       return p->prio;
-}
+       if (!rq_weight) {
+               boost = 1;
+               rq_weight = NICE_0_LOAD;
+       }
 
-/*
- * activate_task - move a task to the runqueue.
- */
-static void activate_task(struct rq *rq, struct task_struct *p, int wakeup)
-{
-       if (p->state == TASK_UNINTERRUPTIBLE)
-               rq->nr_uninterruptible--;
+       /*
+        *           \Sum shares * rq_weight
+        * shares =  -----------------------
+        *               \Sum rq_weight
+        *
+        */
+       shares = aggregate(tg, sd)->shares * rq_weight;
+       shares /= aggregate(tg, sd)->rq_weight + 1;
 
-       enqueue_task(rq, p, wakeup);
-       inc_nr_running(p, rq);
+       /*
+        * record the actual number of shares, not the boosted amount.
+        */
+       tg->cfs_rq[tcpu]->shares = boost ? 0 : shares;
+
+       if (shares < MIN_SHARES)
+               shares = MIN_SHARES;
+       else if (shares > MAX_SHARES)
+               shares = MAX_SHARES;
+
+       __set_se_shares(tg->se[tcpu], shares);
 }
 
 /*
- * deactivate_task - remove a task from the runqueue.
+ * Re-adjust the weights on the cpu the task came from and on the cpu the
+ * task went to.
  */
-static void deactivate_task(struct rq *rq, struct task_struct *p, int sleep)
+static void
+__move_group_shares(struct task_group *tg, struct sched_domain *sd,
+                   int scpu, int dcpu)
 {
-       if (p->state == TASK_UNINTERRUPTIBLE)
-               rq->nr_uninterruptible++;
+       unsigned long shares;
 
-       dequeue_task(rq, p, sleep);
-       dec_nr_running(p, rq);
+       shares = tg->cfs_rq[scpu]->shares + tg->cfs_rq[dcpu]->shares;
+
+       __update_group_shares_cpu(tg, sd, scpu);
+       __update_group_shares_cpu(tg, sd, dcpu);
+
+       /*
+        * ensure we never loose shares due to rounding errors in the
+        * above redistribution.
+        */
+       shares -= tg->cfs_rq[scpu]->shares + tg->cfs_rq[dcpu]->shares;
+       if (shares)
+               tg->cfs_rq[dcpu]->shares += shares;
 }
 
-/**
- * task_curr - is this task currently executing on a CPU?
- * @p: the task in question.
+/*
+ * Because changing a group's shares changes the weight of the super-group
+ * we need to walk up the tree and change all shares until we hit the root.
  */
-inline int task_curr(const struct task_struct *p)
+static void
+move_group_shares(struct task_group *tg, struct sched_domain *sd,
+                 int scpu, int dcpu)
 {
-       return cpu_curr(task_cpu(p)) == p;
+       while (tg) {
+               __move_group_shares(tg, sd, scpu, dcpu);
+               tg = tg->parent;
+       }
+}
+
+static
+void aggregate_group_set_shares(struct task_group *tg, struct sched_domain *sd)
+{
+       unsigned long shares = aggregate(tg, sd)->shares;
+       int i;
+
+       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, sd, i);
+               spin_unlock_irqrestore(&rq->lock, flags);
+       }
+
+       aggregate_group_shares(tg, sd);
+
+       /*
+        * ensure we never loose shares due to rounding errors in the
+        * above redistribution.
+        */
+       shares -= aggregate(tg, sd)->shares;
+       if (shares) {
+               tg->cfs_rq[sd->first_cpu]->shares += shares;
+               aggregate(tg, sd)->shares += shares;
+       }
+}
+
+/*
+ * Calculate the accumulative weight and recursive load of each task group
+ * while walking down the tree.
+ */
+static
+void aggregate_get_down(struct task_group *tg, struct sched_domain *sd)
+{
+       aggregate_group_weight(tg, sd);
+       aggregate_group_shares(tg, sd);
+       aggregate_group_load(tg, sd);
+}
+
+/*
+ * Rebalance the cpu shares while walking back up the tree.
+ */
+static
+void aggregate_get_up(struct task_group *tg, struct sched_domain *sd)
+{
+       aggregate_group_set_shares(tg, sd);
+}
+
+static DEFINE_PER_CPU(spinlock_t, aggregate_lock);
+
+static void __init init_aggregate(void)
+{
+       int i;
+
+       for_each_possible_cpu(i)
+               spin_lock_init(&per_cpu(aggregate_lock, i));
+}
+
+static int get_aggregate(struct sched_domain *sd)
+{
+       if (!spin_trylock(&per_cpu(aggregate_lock, sd->first_cpu)))
+               return 0;
+
+       aggregate_walk_tree(aggregate_get_down, aggregate_get_up, sd);
+       return 1;
+}
+
+static void put_aggregate(struct sched_domain *sd)
+{
+       spin_unlock(&per_cpu(aggregate_lock, sd->first_cpu));
+}
+
+static void cfs_rq_set_shares(struct cfs_rq *cfs_rq, unsigned long shares)
+{
+       cfs_rq->shares = shares;
+}
+
+#else
+
+static inline void init_aggregate(void)
+{
+}
+
+static inline int get_aggregate(struct sched_domain *sd)
+{
+       return 0;
+}
+
+static inline void put_aggregate(struct sched_domain *sd)
+{
+}
+#endif
+
+#else /* CONFIG_SMP */
+
+#ifdef CONFIG_FAIR_GROUP_SCHED
+static void cfs_rq_set_shares(struct cfs_rq *cfs_rq, unsigned long shares)
+{
+}
+#endif
+
+#endif /* CONFIG_SMP */
+
+#include "sched_stats.h"
+#include "sched_idletask.c"
+#include "sched_fair.c"
+#include "sched_rt.c"
+#ifdef CONFIG_SCHED_DEBUG
+# include "sched_debug.c"
+#endif
+
+#define sched_class_highest (&rt_sched_class)
+
+static void inc_nr_running(struct rq *rq)
+{
+       rq->nr_running++;
+}
+
+static void dec_nr_running(struct rq *rq)
+{
+       rq->nr_running--;
+}
+
+static void set_load_weight(struct task_struct *p)
+{
+       if (task_has_rt_policy(p)) {
+               p->se.load.weight = prio_to_weight[0] * 2;
+               p->se.load.inv_weight = prio_to_wmult[0] >> 1;
+               return;
+       }
+
+       /*
+        * SCHED_IDLE tasks get minimal weight:
+        */
+       if (p->policy == SCHED_IDLE) {
+               p->se.load.weight = WEIGHT_IDLEPRIO;
+               p->se.load.inv_weight = WMULT_IDLEPRIO;
+               return;
+       }
+
+       p->se.load.weight = prio_to_weight[p->static_prio - MAX_RT_PRIO];
+       p->se.load.inv_weight = prio_to_wmult[p->static_prio - MAX_RT_PRIO];
+}
+
+static void enqueue_task(struct rq *rq, struct task_struct *p, int wakeup)
+{
+       sched_info_queued(p);
+       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)
+{
+       p->sched_class->dequeue_task(rq, p, sleep);
+       p->se.on_rq = 0;
+}
+
+/*
+ * __normal_prio - return the priority that is based on the static prio
+ */
+static inline int __normal_prio(struct task_struct *p)
+{
+       return p->static_prio;
+}
+
+/*
+ * Calculate the expected normal priority: i.e. priority
+ * without taking RT-inheritance into account. Might be
+ * boosted by interactivity modifiers. Changes upon fork,
+ * setprio syscalls, and whenever the interactivity
+ * estimator recalculates.
+ */
+static inline int normal_prio(struct task_struct *p)
+{
+       int prio;
+
+       if (task_has_rt_policy(p))
+               prio = MAX_RT_PRIO-1 - p->rt_priority;
+       else
+               prio = __normal_prio(p);
+       return prio;
+}
+
+/*
+ * Calculate the current priority, i.e. the priority
+ * taken into account by the scheduler. This value might
+ * be boosted by RT tasks, or might be boosted by
+ * interactivity modifiers. Will be RT if the task got
+ * RT-boosted. If not then it returns p->normal_prio.
+ */
+static int effective_prio(struct task_struct *p)
+{
+       p->normal_prio = normal_prio(p);
+       /*
+        * If we are RT tasks or we were boosted to RT priority,
+        * keep the priority unchanged. Otherwise, update priority
+        * to the normal priority:
+        */
+       if (!rt_prio(p->prio))
+               return p->normal_prio;
+       return p->prio;
+}
+
+/*
+ * activate_task - move a task to the runqueue.
+ */
+static void activate_task(struct rq *rq, struct task_struct *p, int wakeup)
+{
+       if (task_contributes_to_load(p))
+               rq->nr_uninterruptible--;
+
+       enqueue_task(rq, p, wakeup);
+       inc_nr_running(rq);
+}
+
+/*
+ * deactivate_task - remove a task from the runqueue.
+ */
+static void deactivate_task(struct rq *rq, struct task_struct *p, int sleep)
+{
+       if (task_contributes_to_load(p))
+               rq->nr_uninterruptible++;
+
+       dequeue_task(rq, p, sleep);
+       dec_nr_running(rq);
+}
+
+/**
+ * task_curr - is this task currently executing on a CPU?
+ * @p: the task in question.
+ */
+inline int task_curr(const struct task_struct *p)
+{
+       return cpu_curr(task_cpu(p)) == p;
 }
 
 /* Used instead of source_load when we know the type == 0 */
@@ -1420,6 +2010,12 @@ task_hot(struct task_struct *p, u64 now, struct sched_domain *sd)
 {
        s64 delta;
 
+       /*
+        * Buddy candidates are cache hot:
+        */
+       if (sched_feat(CACHE_HOT_BUDDY) && (&p->se == cfs_rq_of(&p->se)->next))
+               return 1;
+
        if (p->sched_class != &fair_sched_class)
                return 0;
 
@@ -1707,17 +2303,17 @@ find_idlest_group(struct sched_domain *sd, struct task_struct *p, int this_cpu)
  * find_idlest_cpu - find the idlest cpu among the cpus in group.
  */
 static int
-find_idlest_cpu(struct sched_group *group, struct task_struct *p, int this_cpu)
+find_idlest_cpu(struct sched_group *group, struct task_struct *p, int this_cpu,
+               cpumask_t *tmp)
 {
-       cpumask_t tmp;
        unsigned long load, min_load = ULONG_MAX;
        int idlest = -1;
        int i;
 
        /* Traverse only the allowed CPUs */
-       cpus_and(tmp, group->cpumask, p->cpus_allowed);
+       cpus_and(*tmp, group->cpumask, p->cpus_allowed);
 
-       for_each_cpu_mask(i, tmp) {
+       for_each_cpu_mask(i, *tmp) {
                load = weighted_cpuload(i);
 
                if (load < min_load || (load == min_load && i == this_cpu)) {
@@ -1756,7 +2352,7 @@ static int sched_balance_self(int cpu, int flag)
        }
 
        while (sd) {
-               cpumask_t span;
+               cpumask_t span, tmpmask;
                struct sched_group *group;
                int new_cpu, weight;
 
@@ -1772,7 +2368,7 @@ static int sched_balance_self(int cpu, int flag)
                        continue;
                }
 
-               new_cpu = find_idlest_cpu(group, t, cpu);
+               new_cpu = find_idlest_cpu(group, t, cpu, &tmpmask);
                if (new_cpu == -1 || new_cpu == cpu) {
                        /* Now try balancing at a lower domain level of cpu */
                        sd = sd->child;
@@ -1818,6 +2414,10 @@ static int try_to_wake_up(struct task_struct *p, unsigned int state, int sync)
        long old_state;
        struct rq *rq;
 
+       if (!sched_feat(SYNC_WAKEUPS))
+               sync = 0;
+
+       smp_wmb();
        rq = task_rq_lock(p, &flags);
        old_state = p->state;
        if (!(old_state & state))
@@ -1878,10 +2478,11 @@ out_activate:
                schedstat_inc(p, se.nr_wakeups_remote);
        update_rq_clock(rq);
        activate_task(rq, p, 1);
-       check_preempt_curr(rq, p);
        success = 1;
 
 out_running:
+       check_preempt_curr(rq, p);
+
        p->state = TASK_RUNNING;
 #ifdef CONFIG_SMP
        if (p->sched_class->task_wake_up)
@@ -1893,14 +2494,13 @@ out:
        return success;
 }
 
-int fastcall wake_up_process(struct task_struct *p)
+int wake_up_process(struct task_struct *p)
 {
-       return try_to_wake_up(p, TASK_STOPPED | TASK_TRACED |
-                                TASK_INTERRUPTIBLE | TASK_UNINTERRUPTIBLE, 0);
+       return try_to_wake_up(p, TASK_ALL, 0);
 }
 EXPORT_SYMBOL(wake_up_process);
 
-int fastcall wake_up_state(struct task_struct *p, unsigned int state)
+int wake_up_state(struct task_struct *p, unsigned int state)
 {
        return try_to_wake_up(p, state, 0);
 }
@@ -1916,6 +2516,8 @@ static void __sched_fork(struct task_struct *p)
        p->se.exec_start                = 0;
        p->se.sum_exec_runtime          = 0;
        p->se.prev_sum_exec_runtime     = 0;
+       p->se.last_wakeup               = 0;
+       p->se.avg_overlap               = 0;
 
 #ifdef CONFIG_SCHEDSTATS
        p->se.wait_start                = 0;
@@ -1931,6 +2533,7 @@ static void __sched_fork(struct task_struct *p)
 
        INIT_LIST_HEAD(&p->rt.run_list);
        p->se.on_rq = 0;
+       INIT_LIST_HEAD(&p->se.group_node);
 
 #ifdef CONFIG_PREEMPT_NOTIFIERS
        INIT_HLIST_HEAD(&p->preempt_notifiers);
@@ -1987,7 +2590,7 @@ void sched_fork(struct task_struct *p, int clone_flags)
  * that must be done for every newly created context, then puts the task
  * on the runqueue and wakes it.
  */
-void fastcall wake_up_new_task(struct task_struct *p, unsigned long clone_flags)
+void wake_up_new_task(struct task_struct *p, unsigned long clone_flags)
 {
        unsigned long flags;
        struct rq *rq;
@@ -2006,7 +2609,7 @@ void fastcall wake_up_new_task(struct task_struct *p, unsigned long clone_flags)
                 * 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
@@ -2650,7 +3253,7 @@ static int move_one_task(struct rq *this_rq, int this_cpu, struct rq *busiest,
 static struct sched_group *
 find_busiest_group(struct sched_domain *sd, int this_cpu,
                   unsigned long *imbalance, enum cpu_idle_type idle,
-                  int *sd_idle, cpumask_t *cpus, int *balance)
+                  int *sd_idle, const cpumask_t *cpus, int *balance)
 {
        struct sched_group *busiest = NULL, *this = NULL, *group = sd->groups;
        unsigned long max_load, avg_load, total_load, this_load, total_pwr;
@@ -2951,7 +3554,7 @@ ret:
  */
 static struct rq *
 find_busiest_queue(struct sched_group *group, enum cpu_idle_type idle,
-                  unsigned long imbalance, cpumask_t *cpus)
+                  unsigned long imbalance, const cpumask_t *cpus)
 {
        struct rq *busiest = NULL, *rq;
        unsigned long max_load = 0;
@@ -2990,14 +3593,18 @@ find_busiest_queue(struct sched_group *group, enum cpu_idle_type idle,
  */
 static int load_balance(int this_cpu, struct rq *this_rq,
                        struct sched_domain *sd, enum cpu_idle_type idle,
-                       int *balance)
+                       int *balance, cpumask_t *cpus)
 {
        int ld_moved, all_pinned = 0, active_balance = 0, sd_idle = 0;
        struct sched_group *group;
        unsigned long imbalance;
        struct rq *busiest;
-       cpumask_t cpus = CPU_MASK_ALL;
        unsigned long flags;
+       int unlock_aggregate;
+
+       cpus_setall(*cpus);
+
+       unlock_aggregate = get_aggregate(sd);
 
        /*
         * When power savings policy is enabled for the parent domain, idle
@@ -3013,7 +3620,7 @@ static int load_balance(int this_cpu, struct rq *this_rq,
 
 redo:
        group = find_busiest_group(sd, this_cpu, &imbalance, idle, &sd_idle,
-                                  &cpus, balance);
+                                  cpus, balance);
 
        if (*balance == 0)
                goto out_balanced;
@@ -3023,7 +3630,7 @@ redo:
                goto out_balanced;
        }
 
-       busiest = find_busiest_queue(group, idle, imbalance, &cpus);
+       busiest = find_busiest_queue(group, idle, imbalance, cpus);
        if (!busiest) {
                schedstat_inc(sd, lb_nobusyq[idle]);
                goto out_balanced;
@@ -3056,8 +3663,8 @@ redo:
 
                /* All tasks on this runqueue were pinned by CPU affinity */
                if (unlikely(all_pinned)) {
-                       cpu_clear(cpu_of(busiest), cpus);
-                       if (!cpus_empty(cpus))
+                       cpu_clear(cpu_of(busiest), *cpus);
+                       if (!cpus_empty(*cpus))
                                goto redo;
                        goto out_balanced;
                }
@@ -3114,8 +3721,9 @@ redo:
 
        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]);
@@ -3130,8 +3738,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 (unlock_aggregate)
+               put_aggregate(sd);
+       return ld_moved;
 }
 
 /*
@@ -3142,7 +3755,8 @@ out_one_pinned:
  * this_rq is locked.
  */
 static int
-load_balance_newidle(int this_cpu, struct rq *this_rq, struct sched_domain *sd)
+load_balance_newidle(int this_cpu, struct rq *this_rq, struct sched_domain *sd,
+                       cpumask_t *cpus)
 {
        struct sched_group *group;
        struct rq *busiest = NULL;
@@ -3150,7 +3764,8 @@ load_balance_newidle(int this_cpu, struct rq *this_rq, struct sched_domain *sd)
        int ld_moved = 0;
        int sd_idle = 0;
        int all_pinned = 0;
-       cpumask_t cpus = CPU_MASK_ALL;
+
+       cpus_setall(*cpus);
 
        /*
         * When power savings policy is enabled for the parent domain, idle
@@ -3165,14 +3780,13 @@ load_balance_newidle(int this_cpu, struct rq *this_rq, struct sched_domain *sd)
        schedstat_inc(sd, lb_count[CPU_NEWLY_IDLE]);
 redo:
        group = find_busiest_group(sd, this_cpu, &imbalance, CPU_NEWLY_IDLE,
-                                  &sd_idle, &cpus, NULL);
+                                  &sd_idle, cpus, NULL);
        if (!group) {
                schedstat_inc(sd, lb_nobusyg[CPU_NEWLY_IDLE]);
                goto out_balanced;
        }
 
-       busiest = find_busiest_queue(group, CPU_NEWLY_IDLE, imbalance,
-                               &cpus);
+       busiest = find_busiest_queue(group, CPU_NEWLY_IDLE, imbalance, cpus);
        if (!busiest) {
                schedstat_inc(sd, lb_nobusyq[CPU_NEWLY_IDLE]);
                goto out_balanced;
@@ -3194,8 +3808,8 @@ redo:
                spin_unlock(&busiest->lock);
 
                if (unlikely(all_pinned)) {
-                       cpu_clear(cpu_of(busiest), cpus);
-                       if (!cpus_empty(cpus))
+                       cpu_clear(cpu_of(busiest), *cpus);
+                       if (!cpus_empty(*cpus))
                                goto redo;
                }
        }
@@ -3229,6 +3843,7 @@ static void idle_balance(int this_cpu, struct rq *this_rq)
        struct sched_domain *sd;
        int pulled_task = -1;
        unsigned long next_balance = jiffies + HZ;
+       cpumask_t tmpmask;
 
        for_each_domain(this_cpu, sd) {
                unsigned long interval;
@@ -3238,8 +3853,8 @@ static void idle_balance(int this_cpu, struct rq *this_rq)
 
                if (sd->flags & SD_BALANCE_NEWIDLE)
                        /* If we've pulled tasks over stop searching: */
-                       pulled_task = load_balance_newidle(this_cpu,
-                                                               this_rq, sd);
+                       pulled_task = load_balance_newidle(this_cpu, this_rq,
+                                                          sd, &tmpmask);
 
                interval = msecs_to_jiffies(sd->balance_interval);
                if (time_after(next_balance, sd->last_balance + interval))
@@ -3398,6 +4013,7 @@ static void rebalance_domains(int cpu, enum cpu_idle_type idle)
        /* Earliest time when we have to do rebalance again */
        unsigned long next_balance = jiffies + 60*HZ;
        int update_next_balance = 0;
+       cpumask_t tmp;
 
        for_each_domain(cpu, sd) {
                if (!(sd->flags & SD_LOAD_BALANCE))
@@ -3421,7 +4037,7 @@ static void rebalance_domains(int cpu, enum cpu_idle_type idle)
                }
 
                if (time_after_eq(jiffies, sd->last_balance + interval)) {
-                       if (load_balance(cpu, rq, sd, idle, &balance)) {
+                       if (load_balance(cpu, rq, sd, idle, &balance, &tmp)) {
                                /*
                                 * We've pulled tasks over so either we're no
                                 * longer idle, or one of our SMT siblings is
@@ -3537,7 +4153,7 @@ static inline void trigger_load_balance(struct rq *rq, int cpu)
                         */
                        int ilb = first_cpu(nohz.cpu_mask);
 
-                       if (ilb != NR_CPUS)
+                       if (ilb < nr_cpu_ids)
                                resched_cpu(ilb);
                }
        }
@@ -3664,8 +4280,10 @@ void account_system_time(struct task_struct *p, int hardirq_offset,
        struct rq *rq = this_rq();
        cputime64_t tmp;
 
-       if ((p->flags & PF_VCPU) && (irq_count() - hardirq_offset == 0))
-               return account_guest_time(p, cputime);
+       if ((p->flags & PF_VCPU) && (irq_count() - hardirq_offset == 0)) {
+               account_guest_time(p, cputime);
+               return;
+       }
 
        p->stime = cputime_add(p->stime, cputime);
 
@@ -3729,21 +4347,13 @@ void scheduler_tick(void)
        int cpu = smp_processor_id();
        struct rq *rq = cpu_rq(cpu);
        struct task_struct *curr = rq->curr;
-       u64 next_tick = rq->tick_timestamp + TICK_NSEC;
+
+       sched_clock_tick();
 
        spin_lock(&rq->lock);
-       __update_rq_clock(rq);
-       /*
-        * Let rq->clock advance by at least TICK_NSEC:
-        */
-       if (unlikely(rq->clock < next_tick)) {
-               rq->clock = next_tick;
-               rq->clock_underflows++;
-       }
-       rq->tick_timestamp = rq->clock;
+       update_rq_clock(rq);
        update_cpu_load(rq);
        curr->sched_class->task_tick(rq, curr, 0);
-       update_sched_rt_period(rq);
        spin_unlock(&rq->lock);
 
 #ifdef CONFIG_SMP
@@ -3754,7 +4364,7 @@ void scheduler_tick(void)
 
 #if defined(CONFIG_PREEMPT) && defined(CONFIG_DEBUG_PREEMPT)
 
-void fastcall add_preempt_count(int val)
+void __kprobes add_preempt_count(int val)
 {
        /*
         * Underflow?
@@ -3770,7 +4380,7 @@ void fastcall add_preempt_count(int val)
 }
 EXPORT_SYMBOL(add_preempt_count);
 
-void fastcall sub_preempt_count(int val)
+void __kprobes sub_preempt_count(int val)
 {
        /*
         * Underflow?
@@ -3872,7 +4482,7 @@ pick_next_task(struct rq *rq, struct task_struct *prev)
 asmlinkage void __sched schedule(void)
 {
        struct task_struct *prev, *next;
-       long *switch_count;
+       unsigned long *switch_count;
        struct rq *rq;
        int cpu;
 
@@ -3895,13 +4505,13 @@ need_resched_nonpreemptible:
         * Do the rq-clock update outside the rq lock:
         */
        local_irq_disable();
-       __update_rq_clock(rq);
+       update_rq_clock(rq);
        spin_lock(&rq->lock);
        clear_tsk_need_resched(prev);
 
        if (prev->state && !(preempt_count() & PREEMPT_ACTIVE)) {
                if (unlikely((prev->state & TASK_INTERRUPTIBLE) &&
-                               unlikely(signal_pending(prev)))) {
+                               signal_pending(prev))) {
                        prev->state = TASK_RUNNING;
                } else {
                        deactivate_task(rq, prev, 1);
@@ -3920,9 +4530,9 @@ need_resched_nonpreemptible:
        prev->sched_class->put_prev_task(rq, prev);
        next = pick_next_task(rq, prev);
 
-       sched_info_switch(prev, next);
-
        if (likely(prev != next)) {
+               sched_info_switch(prev, next);
+
                rq->nr_switches++;
                rq->curr = next;
                ++*switch_count;
@@ -3957,8 +4567,6 @@ EXPORT_SYMBOL(schedule);
 asmlinkage void __sched preempt_schedule(void)
 {
        struct thread_info *ti = current_thread_info();
-       struct task_struct *task = current;
-       int saved_lock_depth;
 
        /*
         * If there is a non-zero preempt_count or interrupts are disabled,
@@ -3969,16 +4577,7 @@ asmlinkage void __sched preempt_schedule(void)
 
        do {
                add_preempt_count(PREEMPT_ACTIVE);
-
-               /*
-                * We keep the big kernel semaphore locked, but we
-                * clear ->lock_depth so that schedule() doesnt
-                * auto-release the semaphore:
-                */
-               saved_lock_depth = task->lock_depth;
-               task->lock_depth = -1;
                schedule();
-               task->lock_depth = saved_lock_depth;
                sub_preempt_count(PREEMPT_ACTIVE);
 
                /*
@@ -3999,26 +4598,15 @@ EXPORT_SYMBOL(preempt_schedule);
 asmlinkage void __sched preempt_schedule_irq(void)
 {
        struct thread_info *ti = current_thread_info();
-       struct task_struct *task = current;
-       int saved_lock_depth;
 
        /* Catch callers which need to be fixed */
        BUG_ON(ti->preempt_count || !irqs_disabled());
 
        do {
                add_preempt_count(PREEMPT_ACTIVE);
-
-               /*
-                * We keep the big kernel semaphore locked, but we
-                * clear ->lock_depth so that schedule() doesnt
-                * auto-release the semaphore:
-                */
-               saved_lock_depth = task->lock_depth;
-               task->lock_depth = -1;
                local_irq_enable();
                schedule();
                local_irq_disable();
-               task->lock_depth = saved_lock_depth;
                sub_preempt_count(PREEMPT_ACTIVE);
 
                /*
@@ -4068,7 +4656,7 @@ static void __wake_up_common(wait_queue_head_t *q, unsigned int mode,
  * @nr_exclusive: how many wake-one or wake-many threads to wake up
  * @key: is directly passed to the wakeup function
  */
-void fastcall __wake_up(wait_queue_head_t *q, unsigned int mode,
+void __wake_up(wait_queue_head_t *q, unsigned int mode,
                        int nr_exclusive, void *key)
 {
        unsigned long flags;
@@ -4082,7 +4670,7 @@ EXPORT_SYMBOL(__wake_up);
 /*
  * Same as __wake_up but called with the spinlock in wait_queue_head_t held.
  */
-void fastcall __wake_up_locked(wait_queue_head_t *q, unsigned int mode)
+void __wake_up_locked(wait_queue_head_t *q, unsigned int mode)
 {
        __wake_up_common(q, mode, 1, 0, NULL);
 }
@@ -4100,7 +4688,7 @@ void fastcall __wake_up_locked(wait_queue_head_t *q, unsigned int mode)
  *
  * On UP it can prevent extra preemption.
  */
-void fastcall
+void
 __wake_up_sync(wait_queue_head_t *q, unsigned int mode, int nr_exclusive)
 {
        unsigned long flags;
@@ -4124,8 +4712,7 @@ void complete(struct completion *x)
 
        spin_lock_irqsave(&x->wait.lock, flags);
        x->done++;
-       __wake_up_common(&x->wait, TASK_UNINTERRUPTIBLE | TASK_INTERRUPTIBLE,
-                        1, 0, NULL);
+       __wake_up_common(&x->wait, TASK_NORMAL, 1, 0, NULL);
        spin_unlock_irqrestore(&x->wait.lock, flags);
 }
 EXPORT_SYMBOL(complete);
@@ -4136,8 +4723,7 @@ void complete_all(struct completion *x)
 
        spin_lock_irqsave(&x->wait.lock, flags);
        x->done += UINT_MAX/2;
-       __wake_up_common(&x->wait, TASK_UNINTERRUPTIBLE | TASK_INTERRUPTIBLE,
-                        0, 0, NULL);
+       __wake_up_common(&x->wait, TASK_NORMAL, 0, 0, NULL);
        spin_unlock_irqrestore(&x->wait.lock, flags);
 }
 EXPORT_SYMBOL(complete_all);
@@ -4151,8 +4737,10 @@ do_wait_for_common(struct completion *x, long timeout, int state)
                wait.flags |= WQ_FLAG_EXCLUSIVE;
                __add_wait_queue_tail(&x->wait, &wait);
                do {
-                       if (state == TASK_INTERRUPTIBLE &&
-                           signal_pending(current)) {
+                       if ((state == TASK_INTERRUPTIBLE &&
+                            signal_pending(current)) ||
+                           (state == TASK_KILLABLE &&
+                            fatal_signal_pending(current))) {
                                __remove_wait_queue(&x->wait, &wait);
                                return -ERESTARTSYS;
                        }
@@ -4212,6 +4800,15 @@ wait_for_completion_interruptible_timeout(struct completion *x,
 }
 EXPORT_SYMBOL(wait_for_completion_interruptible_timeout);
 
+int __sched wait_for_completion_killable(struct completion *x)
+{
+       long t = wait_for_common(x, MAX_SCHEDULE_TIMEOUT, TASK_KILLABLE);
+       if (t == -ERESTARTSYS)
+               return t;
+       return 0;
+}
+EXPORT_SYMBOL(wait_for_completion_killable);
+
 static long __sched
 sleep_on_common(wait_queue_head_t *q, int state, long timeout)
 {
@@ -4285,11 +4882,10 @@ void rt_mutex_setprio(struct task_struct *p, int prio)
        oldprio = p->prio;
        on_rq = p->se.on_rq;
        running = task_current(rq, p);
-       if (on_rq) {
+       if (on_rq)
                dequeue_task(rq, p, 0);
-               if (running)
-                       p->sched_class->put_prev_task(rq, p);
-       }
+       if (running)
+               p->sched_class->put_prev_task(rq, p);
 
        if (rt_prio(prio))
                p->sched_class = &rt_sched_class;
@@ -4298,10 +4894,9 @@ void rt_mutex_setprio(struct task_struct *p, int prio)
 
        p->prio = prio;
 
+       if (running)
+               p->sched_class->set_curr_task(rq);
        if (on_rq) {
-               if (running)
-                       p->sched_class->set_curr_task(rq);
-
                enqueue_task(rq, p, 0);
 
                check_class_changed(rq, p, prev_class, oldprio, running);
@@ -4436,7 +5031,7 @@ int task_nice(const struct task_struct *p)
 {
        return TASK_NICE(p);
 }
-EXPORT_SYMBOL_GPL(task_nice);
+EXPORT_SYMBOL(task_nice);
 
 /**
  * idle_cpu - is a given cpu idle currently?
@@ -4563,6 +5158,15 @@ recheck:
                        return -EPERM;
        }
 
+#ifdef CONFIG_RT_GROUP_SCHED
+       /*
+        * Do not allow realtime tasks into groups that have no runtime
+        * assigned.
+        */
+       if (rt_policy(policy) && task_group(p)->rt_bandwidth.rt_runtime == 0)
+               return -EPERM;
+#endif
+
        retval = security_task_setscheduler(p, policy, param);
        if (retval)
                return retval;
@@ -4586,19 +5190,17 @@ recheck:
        update_rq_clock(rq);
        on_rq = p->se.on_rq;
        running = task_current(rq, p);
-       if (on_rq) {
+       if (on_rq)
                deactivate_task(rq, p, 0);
-               if (running)
-                       p->sched_class->put_prev_task(rq, p);
-       }
+       if (running)
+               p->sched_class->put_prev_task(rq, p);
 
        oldprio = p->prio;
        __setscheduler(rq, p, policy, param->sched_priority);
 
+       if (running)
+               p->sched_class->set_curr_task(rq);
        if (on_rq) {
-               if (running)
-                       p->sched_class->set_curr_task(rq);
-
                activate_task(rq, p, 0);
 
                check_class_changed(rq, p, prev_class, oldprio, running);
@@ -4723,9 +5325,10 @@ out_unlock:
        return retval;
 }
 
-long sched_setaffinity(pid_t pid, cpumask_t new_mask)
+long sched_setaffinity(pid_t pid, const cpumask_t *in_mask)
 {
        cpumask_t cpus_allowed;
+       cpumask_t new_mask = *in_mask;
        struct task_struct *p;
        int retval;
 
@@ -4756,13 +5359,13 @@ long sched_setaffinity(pid_t pid, cpumask_t new_mask)
        if (retval)
                goto out_unlock;
 
-       cpus_allowed = cpuset_cpus_allowed(p);
+       cpuset_cpus_allowed(p, &cpus_allowed);
        cpus_and(new_mask, new_mask, cpus_allowed);
  again:
-       retval = set_cpus_allowed(p, new_mask);
+       retval = set_cpus_allowed_ptr(p, &new_mask);
 
        if (!retval) {
-               cpus_allowed = cpuset_cpus_allowed(p);
+               cpuset_cpus_allowed(p, &cpus_allowed);
                if (!cpus_subset(new_mask, cpus_allowed)) {
                        /*
                         * We must have raced with a concurrent cpuset
@@ -4806,7 +5409,7 @@ asmlinkage long sys_sched_setaffinity(pid_t pid, unsigned int len,
        if (retval)
                return retval;
 
-       return sched_setaffinity(pid, new_mask);
+       return sched_setaffinity(pid, &new_mask);
 }
 
 /*
@@ -4922,7 +5525,6 @@ static void __cond_resched(void)
        } while (need_resched());
 }
 
-#if !defined(CONFIG_PREEMPT) || defined(CONFIG_PREEMPT_VOLUNTARY)
 int __sched _cond_resched(void)
 {
        if (need_resched() && !(preempt_count() & PREEMPT_ACTIVE) &&
@@ -4933,7 +5535,6 @@ int __sched _cond_resched(void)
        return 0;
 }
 EXPORT_SYMBOL(_cond_resched);
-#endif
 
 /*
  * cond_resched_lock() - if a reschedule is pending, drop the given lock,
@@ -5105,7 +5706,7 @@ long sys_sched_rr_get_interval(pid_t pid, struct timespec __user *interval)
        time_slice = 0;
        if (p->policy == SCHED_RR) {
                time_slice = DEF_TIMESLICE;
-       } else {
+       } else if (p->policy != SCHED_FIFO) {
                struct sched_entity *se = &p->se;
                unsigned long flags;
                struct rq *rq;
@@ -5228,8 +5829,11 @@ void __cpuinit init_idle(struct task_struct *idle, int cpu)
        spin_unlock_irqrestore(&rq->lock, flags);
 
        /* Set the preempt count _outside_ the spinlocks! */
+#if defined(CONFIG_PREEMPT)
+       task_thread_info(idle)->preempt_count = (idle->lock_depth >= 0);
+#else
        task_thread_info(idle)->preempt_count = 0;
-
+#endif
        /*
         * The idle tasks have their own, simple scheduling class:
         */
@@ -5268,7 +5872,6 @@ static inline void sched_init_granularity(void)
                sysctl_sched_latency = limit;
 
        sysctl_sched_wakeup_granularity *= factor;
-       sysctl_sched_batch_wakeup_granularity *= factor;
 }
 
 #ifdef CONFIG_SMP
@@ -5297,7 +5900,7 @@ static inline void sched_init_granularity(void)
  * task must not exit() & deallocate itself prematurely. The
  * call is not atomic; no spinlocks may be held.
  */
-int set_cpus_allowed(struct task_struct *p, cpumask_t new_mask)
+int set_cpus_allowed_ptr(struct task_struct *p, const cpumask_t *new_mask)
 {
        struct migration_req req;
        unsigned long flags;
@@ -5305,23 +5908,23 @@ int set_cpus_allowed(struct task_struct *p, cpumask_t new_mask)
        int ret = 0;
 
        rq = task_rq_lock(p, &flags);
-       if (!cpus_intersects(new_mask, cpu_online_map)) {
+       if (!cpus_intersects(*new_mask, cpu_online_map)) {
                ret = -EINVAL;
                goto out;
        }
 
        if (p->sched_class->set_cpus_allowed)
-               p->sched_class->set_cpus_allowed(p, &new_mask);
+               p->sched_class->set_cpus_allowed(p, new_mask);
        else {
-               p->cpus_allowed = new_mask;
-               p->rt.nr_cpus_allowed = cpus_weight(new_mask);
+               p->cpus_allowed = *new_mask;
+               p->rt.nr_cpus_allowed = cpus_weight(*new_mask);
        }
 
        /* Can the task run on the task's current CPU? If so, we're done */
-       if (cpu_isset(task_cpu(p), new_mask))
+       if (cpu_isset(task_cpu(p), *new_mask))
                goto out;
 
-       if (migrate_task(p, any_online_cpu(new_mask), &req)) {
+       if (migrate_task(p, any_online_cpu(*new_mask), &req)) {
                /* Need help from migration thread: drop lock and wait. */
                task_rq_unlock(rq, &flags);
                wake_up_process(rq->migration_thread);
@@ -5334,7 +5937,7 @@ out:
 
        return ret;
 }
-EXPORT_SYMBOL_GPL(set_cpus_allowed);
+EXPORT_SYMBOL_GPL(set_cpus_allowed_ptr);
 
 /*
  * Move (not current) task off this cpu, onto dest cpu. We're doing
@@ -5472,12 +6075,14 @@ static void move_task_off_dead_cpu(int dead_cpu, struct task_struct *p)
                dest_cpu = any_online_cpu(mask);
 
                /* On any allowed CPU? */
-               if (dest_cpu == NR_CPUS)
+               if (dest_cpu >= nr_cpu_ids)
                        dest_cpu = any_online_cpu(p->cpus_allowed);
 
                /* No more Mr. Nice Guy. */
-               if (dest_cpu == NR_CPUS) {
-                       cpumask_t cpus_allowed = cpuset_cpus_allowed_locked(p);
+               if (dest_cpu >= nr_cpu_ids) {
+                       cpumask_t cpus_allowed;
+
+                       cpuset_cpus_allowed_locked(p, &cpus_allowed);
                        /*
                         * Try to stay on the same cpuset, where the
                         * current cpuset may be a subset of all cpus.
@@ -5513,7 +6118,7 @@ static void move_task_off_dead_cpu(int dead_cpu, struct task_struct *p)
  */
 static void migrate_nr_uninterruptible(struct rq *rq_src)
 {
-       struct rq *rq_dest = cpu_rq(any_online_cpu(CPU_MASK_ALL));
+       struct rq *rq_dest = cpu_rq(any_online_cpu(*CPU_MASK_ALL_PTR));
        unsigned long flags;
 
        local_irq_save(flags);
@@ -5886,7 +6491,8 @@ migration_call(struct notifier_block *nfb, unsigned long action, void *hcpu)
                spin_unlock_irq(&rq->lock);
                break;
 
-       case CPU_DOWN_PREPARE:
+       case CPU_DYING:
+       case CPU_DYING_FROZEN:
                /* Update our root-domain */
                rq = cpu_rq(cpu);
                spin_lock_irqsave(&rq->lock, flags);
@@ -5924,20 +6530,16 @@ void __init migration_init(void)
 
 #ifdef CONFIG_SMP
 
-/* Number of possible processor ids */
-int nr_cpu_ids __read_mostly = NR_CPUS;
-EXPORT_SYMBOL(nr_cpu_ids);
-
 #ifdef CONFIG_SCHED_DEBUG
 
-static int sched_domain_debug_one(struct sched_domain *sd, int cpu, int level)
+static int sched_domain_debug_one(struct sched_domain *sd, int cpu, int level,
+                                 cpumask_t *groupmask)
 {
        struct sched_group *group = sd->groups;
-       cpumask_t groupmask;
-       char str[NR_CPUS];
+       char str[256];
 
-       cpumask_scnprintf(str, NR_CPUS, sd->span);
-       cpus_clear(groupmask);
+       cpulist_scnprintf(str, sizeof(str), sd->span);
+       cpus_clear(*groupmask);
 
        printk(KERN_DEBUG "%*s domain %d: ", level, "", level);
 
@@ -5981,25 +6583,25 @@ static int sched_domain_debug_one(struct sched_domain *sd, int cpu, int level)
                        break;
                }
 
-               if (cpus_intersects(groupmask, group->cpumask)) {
+               if (cpus_intersects(*groupmask, group->cpumask)) {
                        printk(KERN_CONT "\n");
                        printk(KERN_ERR "ERROR: repeated CPUs\n");
                        break;
                }
 
-               cpus_or(groupmask, groupmask, group->cpumask);
+               cpus_or(*groupmask, *groupmask, group->cpumask);
 
-               cpumask_scnprintf(str, NR_CPUS, group->cpumask);
+               cpulist_scnprintf(str, sizeof(str), group->cpumask);
                printk(KERN_CONT " %s", str);
 
                group = group->next;
        } while (group != sd->groups);
        printk(KERN_CONT "\n");
 
-       if (!cpus_equal(sd->span, groupmask))
+       if (!cpus_equal(sd->span, *groupmask))
                printk(KERN_ERR "ERROR: groups don't span domain->span\n");
 
-       if (sd->parent && !cpus_subset(groupmask, sd->parent->span))
+       if (sd->parent && !cpus_subset(*groupmask, sd->parent->span))
                printk(KERN_ERR "ERROR: parent span is not a superset "
                        "of domain->span\n");
        return 0;
@@ -6007,6 +6609,7 @@ static int sched_domain_debug_one(struct sched_domain *sd, int cpu, int level)
 
 static void sched_domain_debug(struct sched_domain *sd, int cpu)
 {
+       cpumask_t *groupmask;
        int level = 0;
 
        if (!sd) {
@@ -6016,14 +6619,21 @@ static void sched_domain_debug(struct sched_domain *sd, int cpu)
 
        printk(KERN_DEBUG "CPU%d attaching sched-domain:\n", cpu);
 
+       groupmask = kmalloc(sizeof(cpumask_t), GFP_KERNEL);
+       if (!groupmask) {
+               printk(KERN_DEBUG "Cannot load-balance (out of memory)\n");
+               return;
+       }
+
        for (;;) {
-               if (sched_domain_debug_one(sd, cpu, level))
+               if (sched_domain_debug_one(sd, cpu, level, groupmask))
                        break;
                level++;
                sd = sd->parent;
                if (!sd)
                        break;
        }
+       kfree(groupmask);
 }
 #else
 # define sched_domain_debug(sd, cpu) do { } while (0)
@@ -6211,30 +6821,33 @@ __setup("isolcpus=", isolated_cpu_setup);
  * and ->cpu_power to 0.
  */
 static void
-init_sched_build_groups(cpumask_t span, const cpumask_t *cpu_map,
+init_sched_build_groups(const cpumask_t *span, const cpumask_t *cpu_map,
                        int (*group_fn)(int cpu, const cpumask_t *cpu_map,
-                                       struct sched_group **sg))
+                                       struct sched_group **sg,
+                                       cpumask_t *tmpmask),
+                       cpumask_t *covered, cpumask_t *tmpmask)
 {
        struct sched_group *first = NULL, *last = NULL;
-       cpumask_t covered = CPU_MASK_NONE;
        int i;
 
-       for_each_cpu_mask(i, span) {
+       cpus_clear(*covered);
+
+       for_each_cpu_mask(i, *span) {
                struct sched_group *sg;
-               int group = group_fn(i, cpu_map, &sg);
+               int group = group_fn(i, cpu_map, &sg, tmpmask);
                int j;
 
-               if (cpu_isset(i, covered))
+               if (cpu_isset(i, *covered))
                        continue;
 
-               sg->cpumask = CPU_MASK_NONE;
+               cpus_clear(sg->cpumask);
                sg->__cpu_power = 0;
 
-               for_each_cpu_mask(j, span) {
-                       if (group_fn(j, cpu_map, NULL) != group)
+               for_each_cpu_mask(j, *span) {
+                       if (group_fn(j, cpu_map, NULL, tmpmask) != group)
                                continue;
 
-                       cpu_set(j, covered);
+                       cpu_set(j, *covered);
                        cpu_set(j, sg->cpumask);
                }
                if (!first)
@@ -6260,7 +6873,7 @@ init_sched_build_groups(cpumask_t span, const cpumask_t *cpu_map,
  *
  * Should use nodemask_t.
  */
-static int find_next_best_node(int node, unsigned long *used_nodes)
+static int find_next_best_node(int node, nodemask_t *used_nodes)
 {
        int i, n, val, min_val, best_node = 0;
 
@@ -6274,7 +6887,7 @@ static int find_next_best_node(int node, unsigned long *used_nodes)
                        continue;
 
                /* Skip already used nodes */
-               if (test_bit(n, used_nodes))
+               if (node_isset(n, *used_nodes))
                        continue;
 
                /* Simple min distance search */
@@ -6286,40 +6899,37 @@ static int find_next_best_node(int node, unsigned long *used_nodes)
                }
        }
 
-       set_bit(best_node, used_nodes);
+       node_set(best_node, *used_nodes);
        return best_node;
 }
 
 /**
  * sched_domain_node_span - get a cpumask for a node's sched_domain
  * @node: node whose cpumask we're constructing
- * @size: number of nodes to include in this span
+ * @span: resulting cpumask
  *
  * Given a node, construct a good cpumask for its sched_domain to span. It
  * should be one that prevents unnecessary balancing, but also spreads tasks
  * out optimally.
  */
-static cpumask_t sched_domain_node_span(int node)
+static void sched_domain_node_span(int node, cpumask_t *span)
 {
-       DECLARE_BITMAP(used_nodes, MAX_NUMNODES);
-       cpumask_t span, nodemask;
+       nodemask_t used_nodes;
+       node_to_cpumask_ptr(nodemask, node);
        int i;
 
-       cpus_clear(span);
-       bitmap_zero(used_nodes, MAX_NUMNODES);
+       cpus_clear(*span);
+       nodes_clear(used_nodes);
 
-       nodemask = node_to_cpumask(node);
-       cpus_or(span, span, nodemask);
-       set_bit(node, used_nodes);
+       cpus_or(*span, *span, *nodemask);
+       node_set(node, used_nodes);
 
        for (i = 1; i < SD_NODES_PER_DOMAIN; i++) {
-               int next_node = find_next_best_node(node, used_nodes);
+               int next_node = find_next_best_node(node, &used_nodes);
 
-               nodemask = node_to_cpumask(next_node);
-               cpus_or(span, span, nodemask);
+               node_to_cpumask_ptr_next(nodemask, next_node);
+               cpus_or(*span, *span, *nodemask);
        }
-
-       return span;
 }
 #endif
 
@@ -6333,7 +6943,8 @@ static DEFINE_PER_CPU(struct sched_domain, cpu_domains);
 static DEFINE_PER_CPU(struct sched_group, sched_group_cpus);
 
 static int
-cpu_to_cpu_group(int cpu, const cpumask_t *cpu_map, struct sched_group **sg)
+cpu_to_cpu_group(int cpu, const cpumask_t *cpu_map, struct sched_group **sg,
+                cpumask_t *unused)
 {
        if (sg)
                *sg = &per_cpu(sched_group_cpus, cpu);
@@ -6351,19 +6962,22 @@ static DEFINE_PER_CPU(struct sched_group, sched_group_core);
 
 #if defined(CONFIG_SCHED_MC) && defined(CONFIG_SCHED_SMT)
 static int
-cpu_to_core_group(int cpu, const cpumask_t *cpu_map, struct sched_group **sg)
+cpu_to_core_group(int cpu, const cpumask_t *cpu_map, struct sched_group **sg,
+                 cpumask_t *mask)
 {
        int group;
-       cpumask_t mask = per_cpu(cpu_sibling_map, cpu);
-       cpus_and(mask, mask, *cpu_map);
-       group = first_cpu(mask);
+
+       *mask = per_cpu(cpu_sibling_map, cpu);
+       cpus_and(*mask, *mask, *cpu_map);
+       group = first_cpu(*mask);
        if (sg)
                *sg = &per_cpu(sched_group_core, group);
        return group;
 }
 #elif defined(CONFIG_SCHED_MC)
 static int
-cpu_to_core_group(int cpu, const cpumask_t *cpu_map, struct sched_group **sg)
+cpu_to_core_group(int cpu, const cpumask_t *cpu_map, struct sched_group **sg,
+                 cpumask_t *unused)
 {
        if (sg)
                *sg = &per_cpu(sched_group_core, cpu);
@@ -6375,17 +6989,18 @@ static DEFINE_PER_CPU(struct sched_domain, phys_domains);
 static DEFINE_PER_CPU(struct sched_group, sched_group_phys);
 
 static int
-cpu_to_phys_group(int cpu, const cpumask_t *cpu_map, struct sched_group **sg)
+cpu_to_phys_group(int cpu, const cpumask_t *cpu_map, struct sched_group **sg,
+                 cpumask_t *mask)
 {
        int group;
 #ifdef CONFIG_SCHED_MC
-       cpumask_t mask = cpu_coregroup_map(cpu);
-       cpus_and(mask, mask, *cpu_map);
-       group = first_cpu(mask);
+       *mask = cpu_coregroup_map(cpu);
+       cpus_and(*mask, *mask, *cpu_map);
+       group = first_cpu(*mask);
 #elif defined(CONFIG_SCHED_SMT)
-       cpumask_t mask = per_cpu(cpu_sibling_map, cpu);
-       cpus_and(mask, mask, *cpu_map);
-       group = first_cpu(mask);
+       *mask = per_cpu(cpu_sibling_map, cpu);
+       cpus_and(*mask, *mask, *cpu_map);
+       group = first_cpu(*mask);
 #else
        group = cpu;
 #endif
@@ -6401,19 +7016,19 @@ cpu_to_phys_group(int cpu, const cpumask_t *cpu_map, struct sched_group **sg)
  * gets dynamically allocated.
  */
 static DEFINE_PER_CPU(struct sched_domain, node_domains);
-static struct sched_group **sched_group_nodes_bycpu[NR_CPUS];
+static struct sched_group ***sched_group_nodes_bycpu;
 
 static DEFINE_PER_CPU(struct sched_domain, allnodes_domains);
 static DEFINE_PER_CPU(struct sched_group, sched_group_allnodes);
 
 static int cpu_to_allnodes_group(int cpu, const cpumask_t *cpu_map,
-                                struct sched_group **sg)
+                                struct sched_group **sg, cpumask_t *nodemask)
 {
-       cpumask_t nodemask = node_to_cpumask(cpu_to_node(cpu));
        int group;
 
-       cpus_and(nodemask, nodemask, *cpu_map);
-       group = first_cpu(nodemask);
+       *nodemask = node_to_cpumask(cpu_to_node(cpu));
+       cpus_and(*nodemask, *nodemask, *cpu_map);
+       group = first_cpu(*nodemask);
 
        if (sg)
                *sg = &per_cpu(sched_group_allnodes, group);
@@ -6449,7 +7064,7 @@ static void init_numa_sched_groups_power(struct sched_group *group_head)
 
 #ifdef CONFIG_NUMA
 /* Free memory allocated for various sched_group structures */
-static void free_sched_groups(const cpumask_t *cpu_map)
+static void free_sched_groups(const cpumask_t *cpu_map, cpumask_t *nodemask)
 {
        int cpu, i;
 
@@ -6461,11 +7076,11 @@ static void free_sched_groups(const cpumask_t *cpu_map)
                        continue;
 
                for (i = 0; i < MAX_NUMNODES; i++) {
-                       cpumask_t nodemask = node_to_cpumask(i);
                        struct sched_group *oldsg, *sg = sched_group_nodes[i];
 
-                       cpus_and(nodemask, nodemask, *cpu_map);
-                       if (cpus_empty(nodemask))
+                       *nodemask = node_to_cpumask(i);
+                       cpus_and(*nodemask, *nodemask, *cpu_map);
+                       if (cpus_empty(*nodemask))
                                continue;
 
                        if (sg == NULL)
@@ -6483,7 +7098,7 @@ next_sg:
        }
 }
 #else
-static void free_sched_groups(const cpumask_t *cpu_map)
+static void free_sched_groups(const cpumask_t *cpu_map, cpumask_t *nodemask)
 {
 }
 #endif
@@ -6540,14 +7155,107 @@ static void init_sched_groups_power(int cpu, struct sched_domain *sd)
        } while (group != child->groups);
 }
 
+/*
+ * Initializers for schedule domains
+ * Non-inlined to reduce accumulated stack pressure in build_sched_domains()
+ */
+
+#define        SD_INIT(sd, type)       sd_init_##type(sd)
+#define SD_INIT_FUNC(type)     \
+static noinline void sd_init_##type(struct sched_domain *sd)   \
+{                                                              \
+       memset(sd, 0, sizeof(*sd));                             \
+       *sd = SD_##type##_INIT;                                 \
+       sd->level = SD_LV_##type;                               \
+}
+
+SD_INIT_FUNC(CPU)
+#ifdef CONFIG_NUMA
+ SD_INIT_FUNC(ALLNODES)
+ SD_INIT_FUNC(NODE)
+#endif
+#ifdef CONFIG_SCHED_SMT
+ SD_INIT_FUNC(SIBLING)
+#endif
+#ifdef CONFIG_SCHED_MC
+ SD_INIT_FUNC(MC)
+#endif
+
+/*
+ * To minimize stack usage kmalloc room for cpumasks and share the
+ * space as the usage in build_sched_domains() dictates.  Used only
+ * if the amount of space is significant.
+ */
+struct allmasks {
+       cpumask_t tmpmask;                      /* make this one first */
+       union {
+               cpumask_t nodemask;
+               cpumask_t this_sibling_map;
+               cpumask_t this_core_map;
+       };
+       cpumask_t send_covered;
+
+#ifdef CONFIG_NUMA
+       cpumask_t domainspan;
+       cpumask_t covered;
+       cpumask_t notcovered;
+#endif
+};
+
+#if    NR_CPUS > 128
+#define        SCHED_CPUMASK_ALLOC             1
+#define        SCHED_CPUMASK_FREE(v)           kfree(v)
+#define        SCHED_CPUMASK_DECLARE(v)        struct allmasks *v
+#else
+#define        SCHED_CPUMASK_ALLOC             0
+#define        SCHED_CPUMASK_FREE(v)
+#define        SCHED_CPUMASK_DECLARE(v)        struct allmasks _v, *v = &_v
+#endif
+
+#define        SCHED_CPUMASK_VAR(v, a)         cpumask_t *v = (cpumask_t *) \
+                       ((unsigned long)(a) + offsetof(struct allmasks, v))
+
+static int default_relax_domain_level = -1;
+
+static int __init setup_relax_domain_level(char *str)
+{
+       default_relax_domain_level = simple_strtoul(str, NULL, 0);
+       return 1;
+}
+__setup("relax_domain_level=", setup_relax_domain_level);
+
+static void set_domain_attribute(struct sched_domain *sd,
+                                struct sched_domain_attr *attr)
+{
+       int request;
+
+       if (!attr || attr->relax_domain_level < 0) {
+               if (default_relax_domain_level < 0)
+                       return;
+               else
+                       request = default_relax_domain_level;
+       } else
+               request = attr->relax_domain_level;
+       if (request < sd->level) {
+               /* turn off idle balance on this domain */
+               sd->flags &= ~(SD_WAKE_IDLE|SD_BALANCE_NEWIDLE);
+       } else {
+               /* turn on idle balance on this domain */
+               sd->flags |= (SD_WAKE_IDLE_FAR|SD_BALANCE_NEWIDLE);
+       }
+}
+
 /*
  * Build sched domains for a given set of cpus and attach the sched domains
  * to the individual cpus
  */
-static int build_sched_domains(const cpumask_t *cpu_map)
+static int __build_sched_domains(const cpumask_t *cpu_map,
+                                struct sched_domain_attr *attr)
 {
        int i;
        struct root_domain *rd;
+       SCHED_CPUMASK_DECLARE(allmasks);
+       cpumask_t *tmpmask;
 #ifdef CONFIG_NUMA
        struct sched_group **sched_group_nodes = NULL;
        int sd_allnodes = 0;
@@ -6561,39 +7269,65 @@ static int build_sched_domains(const cpumask_t *cpu_map)
                printk(KERN_WARNING "Can not alloc sched group node list\n");
                return -ENOMEM;
        }
-       sched_group_nodes_bycpu[first_cpu(*cpu_map)] = sched_group_nodes;
 #endif
 
        rd = alloc_rootdomain();
        if (!rd) {
                printk(KERN_WARNING "Cannot alloc root domain\n");
+#ifdef CONFIG_NUMA
+               kfree(sched_group_nodes);
+#endif
                return -ENOMEM;
        }
 
+#if SCHED_CPUMASK_ALLOC
+       /* get space for all scratch cpumask variables */
+       allmasks = kmalloc(sizeof(*allmasks), GFP_KERNEL);
+       if (!allmasks) {
+               printk(KERN_WARNING "Cannot alloc cpumask array\n");
+               kfree(rd);
+#ifdef CONFIG_NUMA
+               kfree(sched_group_nodes);
+#endif
+               return -ENOMEM;
+       }
+#endif
+       tmpmask = (cpumask_t *)allmasks;
+
+
+#ifdef CONFIG_NUMA
+       sched_group_nodes_bycpu[first_cpu(*cpu_map)] = sched_group_nodes;
+#endif
+
        /*
         * Set up domains for cpus specified by the cpu_map.
         */
        for_each_cpu_mask(i, *cpu_map) {
                struct sched_domain *sd = NULL, *p;
-               cpumask_t nodemask = node_to_cpumask(cpu_to_node(i));
+               SCHED_CPUMASK_VAR(nodemask, allmasks);
 
-               cpus_and(nodemask, nodemask, *cpu_map);
+               *nodemask = node_to_cpumask(cpu_to_node(i));
+               cpus_and(*nodemask, *nodemask, *cpu_map);
 
 #ifdef CONFIG_NUMA
                if (cpus_weight(*cpu_map) >
-                               SD_NODES_PER_DOMAIN*cpus_weight(nodemask)) {
+                               SD_NODES_PER_DOMAIN*cpus_weight(*nodemask)) {
                        sd = &per_cpu(allnodes_domains, i);
-                       *sd = SD_ALLNODES_INIT;
+                       SD_INIT(sd, ALLNODES);
+                       set_domain_attribute(sd, attr);
                        sd->span = *cpu_map;
-                       cpu_to_allnodes_group(i, cpu_map, &sd->groups);
+                       sd->first_cpu = first_cpu(sd->span);
+                       cpu_to_allnodes_group(i, cpu_map, &sd->groups, tmpmask);
                        p = sd;
                        sd_allnodes = 1;
                } else
                        p = NULL;
 
                sd = &per_cpu(node_domains, i);
-               *sd = SD_NODE_INIT;
-               sd->span = sched_domain_node_span(cpu_to_node(i));
+               SD_INIT(sd, NODE);
+               set_domain_attribute(sd, attr);
+               sched_domain_node_span(cpu_to_node(i), &sd->span);
+               sd->first_cpu = first_cpu(sd->span);
                sd->parent = p;
                if (p)
                        p->child = sd;
@@ -6602,94 +7336,120 @@ static int build_sched_domains(const cpumask_t *cpu_map)
 
                p = sd;
                sd = &per_cpu(phys_domains, i);
-               *sd = SD_CPU_INIT;
-               sd->span = nodemask;
+               SD_INIT(sd, CPU);
+               set_domain_attribute(sd, attr);
+               sd->span = *nodemask;
+               sd->first_cpu = first_cpu(sd->span);
                sd->parent = p;
                if (p)
                        p->child = sd;
-               cpu_to_phys_group(i, cpu_map, &sd->groups);
+               cpu_to_phys_group(i, cpu_map, &sd->groups, tmpmask);
 
 #ifdef CONFIG_SCHED_MC
                p = sd;
                sd = &per_cpu(core_domains, i);
-               *sd = SD_MC_INIT;
+               SD_INIT(sd, MC);
+               set_domain_attribute(sd, attr);
                sd->span = cpu_coregroup_map(i);
+               sd->first_cpu = first_cpu(sd->span);
                cpus_and(sd->span, sd->span, *cpu_map);
                sd->parent = p;
                p->child = sd;
-               cpu_to_core_group(i, cpu_map, &sd->groups);
+               cpu_to_core_group(i, cpu_map, &sd->groups, tmpmask);
 #endif
 
 #ifdef CONFIG_SCHED_SMT
                p = sd;
                sd = &per_cpu(cpu_domains, i);
-               *sd = SD_SIBLING_INIT;
+               SD_INIT(sd, SIBLING);
+               set_domain_attribute(sd, attr);
                sd->span = per_cpu(cpu_sibling_map, i);
+               sd->first_cpu = first_cpu(sd->span);
                cpus_and(sd->span, sd->span, *cpu_map);
                sd->parent = p;
                p->child = sd;
-               cpu_to_cpu_group(i, cpu_map, &sd->groups);
+               cpu_to_cpu_group(i, cpu_map, &sd->groups, tmpmask);
 #endif
        }
 
 #ifdef CONFIG_SCHED_SMT
        /* Set up CPU (sibling) groups */
        for_each_cpu_mask(i, *cpu_map) {
-               cpumask_t this_sibling_map = per_cpu(cpu_sibling_map, i);
-               cpus_and(this_sibling_map, this_sibling_map, *cpu_map);
-               if (i != first_cpu(this_sibling_map))
+               SCHED_CPUMASK_VAR(this_sibling_map, allmasks);
+               SCHED_CPUMASK_VAR(send_covered, allmasks);
+
+               *this_sibling_map = per_cpu(cpu_sibling_map, i);
+               cpus_and(*this_sibling_map, *this_sibling_map, *cpu_map);
+               if (i != first_cpu(*this_sibling_map))
                        continue;
 
                init_sched_build_groups(this_sibling_map, cpu_map,
-                                       &cpu_to_cpu_group);
+                                       &cpu_to_cpu_group,
+                                       send_covered, tmpmask);
        }
 #endif
 
 #ifdef CONFIG_SCHED_MC
        /* Set up multi-core groups */
        for_each_cpu_mask(i, *cpu_map) {
-               cpumask_t this_core_map = cpu_coregroup_map(i);
-               cpus_and(this_core_map, this_core_map, *cpu_map);
-               if (i != first_cpu(this_core_map))
+               SCHED_CPUMASK_VAR(this_core_map, allmasks);
+               SCHED_CPUMASK_VAR(send_covered, allmasks);
+
+               *this_core_map = cpu_coregroup_map(i);
+               cpus_and(*this_core_map, *this_core_map, *cpu_map);
+               if (i != first_cpu(*this_core_map))
                        continue;
+
                init_sched_build_groups(this_core_map, cpu_map,
-                                       &cpu_to_core_group);
+                                       &cpu_to_core_group,
+                                       send_covered, tmpmask);
        }
 #endif
 
        /* Set up physical groups */
        for (i = 0; i < MAX_NUMNODES; i++) {
-               cpumask_t nodemask = node_to_cpumask(i);
+               SCHED_CPUMASK_VAR(nodemask, allmasks);
+               SCHED_CPUMASK_VAR(send_covered, allmasks);
 
-               cpus_and(nodemask, nodemask, *cpu_map);
-               if (cpus_empty(nodemask))
+               *nodemask = node_to_cpumask(i);
+               cpus_and(*nodemask, *nodemask, *cpu_map);
+               if (cpus_empty(*nodemask))
                        continue;
 
-               init_sched_build_groups(nodemask, cpu_map, &cpu_to_phys_group);
+               init_sched_build_groups(nodemask, cpu_map,
+                                       &cpu_to_phys_group,
+                                       send_covered, tmpmask);
        }
 
 #ifdef CONFIG_NUMA
        /* Set up node groups */
-       if (sd_allnodes)
-               init_sched_build_groups(*cpu_map, cpu_map,
-                                       &cpu_to_allnodes_group);
+       if (sd_allnodes) {
+               SCHED_CPUMASK_VAR(send_covered, allmasks);
+
+               init_sched_build_groups(cpu_map, cpu_map,
+                                       &cpu_to_allnodes_group,
+                                       send_covered, tmpmask);
+       }
 
        for (i = 0; i < MAX_NUMNODES; i++) {
                /* Set up node groups */
                struct sched_group *sg, *prev;
-               cpumask_t nodemask = node_to_cpumask(i);
-               cpumask_t domainspan;
-               cpumask_t covered = CPU_MASK_NONE;
+               SCHED_CPUMASK_VAR(nodemask, allmasks);
+               SCHED_CPUMASK_VAR(domainspan, allmasks);
+               SCHED_CPUMASK_VAR(covered, allmasks);
                int j;
 
-               cpus_and(nodemask, nodemask, *cpu_map);
-               if (cpus_empty(nodemask)) {
+               *nodemask = node_to_cpumask(i);
+               cpus_clear(*covered);
+
+               cpus_and(*nodemask, *nodemask, *cpu_map);
+               if (cpus_empty(*nodemask)) {
                        sched_group_nodes[i] = NULL;
                        continue;
                }
 
-               domainspan = sched_domain_node_span(i);
-               cpus_and(domainspan, domainspan, *cpu_map);
+               sched_domain_node_span(i, domainspan);
+               cpus_and(*domainspan, *domainspan, *cpu_map);
 
                sg = kmalloc_node(sizeof(struct sched_group), GFP_KERNEL, i);
                if (!sg) {
@@ -6698,31 +7458,31 @@ static int build_sched_domains(const cpumask_t *cpu_map)
                        goto error;
                }
                sched_group_nodes[i] = sg;
-               for_each_cpu_mask(j, nodemask) {
+               for_each_cpu_mask(j, *nodemask) {
                        struct sched_domain *sd;
 
                        sd = &per_cpu(node_domains, j);
                        sd->groups = sg;
                }
                sg->__cpu_power = 0;
-               sg->cpumask = nodemask;
+               sg->cpumask = *nodemask;
                sg->next = sg;
-               cpus_or(covered, covered, nodemask);
+               cpus_or(*covered, *covered, *nodemask);
                prev = sg;
 
                for (j = 0; j < MAX_NUMNODES; j++) {
-                       cpumask_t tmp, notcovered;
+                       SCHED_CPUMASK_VAR(notcovered, allmasks);
                        int n = (i + j) % MAX_NUMNODES;
+                       node_to_cpumask_ptr(pnodemask, n);
 
-                       cpus_complement(notcovered, covered);
-                       cpus_and(tmp, notcovered, *cpu_map);
-                       cpus_and(tmp, tmp, domainspan);
-                       if (cpus_empty(tmp))
+                       cpus_complement(*notcovered, *covered);
+                       cpus_and(*tmpmask, *notcovered, *cpu_map);
+                       cpus_and(*tmpmask, *tmpmask, *domainspan);
+                       if (cpus_empty(*tmpmask))
                                break;
 
-                       nodemask = node_to_cpumask(n);
-                       cpus_and(tmp, tmp, nodemask);
-                       if (cpus_empty(tmp))
+                       cpus_and(*tmpmask, *tmpmask, *pnodemask);
+                       if (cpus_empty(*tmpmask))
                                continue;
 
                        sg = kmalloc_node(sizeof(struct sched_group),
@@ -6733,9 +7493,9 @@ static int build_sched_domains(const cpumask_t *cpu_map)
                                goto error;
                        }
                        sg->__cpu_power = 0;
-                       sg->cpumask = tmp;
+                       sg->cpumask = *tmpmask;
                        sg->next = prev->next;
-                       cpus_or(covered, covered, tmp);
+                       cpus_or(*covered, *covered, *tmpmask);
                        prev->next = sg;
                        prev = sg;
                }
@@ -6771,7 +7531,8 @@ static int build_sched_domains(const cpumask_t *cpu_map)
        if (sd_allnodes) {
                struct sched_group *sg;
 
-               cpu_to_allnodes_group(first_cpu(*cpu_map), cpu_map, &sg);
+               cpu_to_allnodes_group(first_cpu(*cpu_map), cpu_map, &sg,
+                                                               tmpmask);
                init_numa_sched_groups_power(sg);
        }
 #endif
@@ -6789,17 +7550,26 @@ static int build_sched_domains(const cpumask_t *cpu_map)
                cpu_attach_domain(sd, rd, i);
        }
 
+       SCHED_CPUMASK_FREE((void *)allmasks);
        return 0;
 
 #ifdef CONFIG_NUMA
 error:
-       free_sched_groups(cpu_map);
+       free_sched_groups(cpu_map, tmpmask);
+       SCHED_CPUMASK_FREE((void *)allmasks);
        return -ENOMEM;
 #endif
 }
 
+static int build_sched_domains(const cpumask_t *cpu_map)
+{
+       return __build_sched_domains(cpu_map, NULL);
+}
+
 static cpumask_t *doms_cur;    /* current sched domains */
 static int ndoms_cur;          /* number of sched domains in 'doms_cur' */
+static struct sched_domain_attr *dattr_cur;    /* attribues of custom domains
+                                                  in 'doms_cur' */
 
 /*
  * Special case: If a kmalloc of a doms_cur partition (array of
@@ -6808,6 +7578,10 @@ static int ndoms_cur;            /* number of sched domains in 'doms_cur' */
  */
 static cpumask_t fallback_doms;
 
+void __attribute__((weak)) arch_update_cpu_topology(void)
+{
+}
+
 /*
  * Set up scheduler domains and groups. Callers must hold the hotplug lock.
  * For now this just excludes isolated cpus, but could be used to
@@ -6817,20 +7591,23 @@ static int arch_init_sched_domains(const cpumask_t *cpu_map)
 {
        int err;
 
+       arch_update_cpu_topology();
        ndoms_cur = 1;
        doms_cur = kmalloc(sizeof(cpumask_t), GFP_KERNEL);
        if (!doms_cur)
                doms_cur = &fallback_doms;
        cpus_andnot(*doms_cur, *cpu_map, cpu_isolated_map);
+       dattr_cur = NULL;
        err = build_sched_domains(doms_cur);
        register_sched_domain_sysctl();
 
        return err;
 }
 
-static void arch_destroy_sched_domains(const cpumask_t *cpu_map)
+static void arch_destroy_sched_domains(const cpumask_t *cpu_map,
+                                      cpumask_t *tmpmask)
 {
-       free_sched_groups(cpu_map);
+       free_sched_groups(cpu_map, tmpmask);
 }
 
 /*
@@ -6839,6 +7616,7 @@ static void arch_destroy_sched_domains(const cpumask_t *cpu_map)
  */
 static void detach_destroy_domains(const cpumask_t *cpu_map)
 {
+       cpumask_t tmpmask;
        int i;
 
        unregister_sched_domain_sysctl();
@@ -6846,7 +7624,23 @@ static void detach_destroy_domains(const cpumask_t *cpu_map)
        for_each_cpu_mask(i, *cpu_map)
                cpu_attach_domain(NULL, &def_root_domain, i);
        synchronize_sched();
-       arch_destroy_sched_domains(cpu_map);
+       arch_destroy_sched_domains(cpu_map, &tmpmask);
+}
+
+/* handle null as "default" */
+static int dattrs_equal(struct sched_domain_attr *cur, int idx_cur,
+                       struct sched_domain_attr *new, int idx_new)
+{
+       struct sched_domain_attr tmp;
+
+       /* fast path */
+       if (!new && !cur)
+               return 1;
+
+       tmp = SD_ATTR_INIT;
+       return !memcmp(cur ? (cur + idx_cur) : &tmp,
+                       new ? (new + idx_new) : &tmp,
+                       sizeof(struct sched_domain_attr));
 }
 
 /*
@@ -6870,11 +7664,12 @@ static void detach_destroy_domains(const cpumask_t *cpu_map)
  *
  * Call with hotplug lock held
  */
-void partition_sched_domains(int ndoms_new, cpumask_t *doms_new)
+void partition_sched_domains(int ndoms_new, cpumask_t *doms_new,
+                            struct sched_domain_attr *dattr_new)
 {
        int i, j;
 
-       lock_doms_cur();
+       mutex_lock(&sched_domains_mutex);
 
        /* always unregister in case we don't destroy any domains */
        unregister_sched_domain_sysctl();
@@ -6883,12 +7678,14 @@ void partition_sched_domains(int ndoms_new, cpumask_t *doms_new)
                ndoms_new = 1;
                doms_new = &fallback_doms;
                cpus_andnot(doms_new[0], cpu_online_map, cpu_isolated_map);
+               dattr_new = NULL;
        }
 
        /* Destroy deleted domains */
        for (i = 0; i < ndoms_cur; i++) {
                for (j = 0; j < ndoms_new; j++) {
-                       if (cpus_equal(doms_cur[i], doms_new[j]))
+                       if (cpus_equal(doms_cur[i], doms_new[j])
+                           && dattrs_equal(dattr_cur, i, dattr_new, j))
                                goto match1;
                }
                /* no match - a current sched domain not in new doms_new[] */
@@ -6900,11 +7697,13 @@ match1:
        /* Build new domains */
        for (i = 0; i < ndoms_new; i++) {
                for (j = 0; j < ndoms_cur; j++) {
-                       if (cpus_equal(doms_new[i], doms_cur[j]))
+                       if (cpus_equal(doms_new[i], doms_cur[j])
+                           && dattrs_equal(dattr_new, i, dattr_cur, j))
                                goto match2;
                }
                /* no match - add a new doms_new */
-               build_sched_domains(doms_new + i);
+               __build_sched_domains(doms_new + i,
+                                       dattr_new ? dattr_new + i : NULL);
 match2:
                ;
        }
@@ -6912,22 +7711,26 @@ match2:
        /* Remember the new sched domains */
        if (doms_cur != &fallback_doms)
                kfree(doms_cur);
+       kfree(dattr_cur);       /* kfree(NULL) is safe */
        doms_cur = doms_new;
+       dattr_cur = dattr_new;
        ndoms_cur = ndoms_new;
 
        register_sched_domain_sysctl();
 
-       unlock_doms_cur();
+       mutex_unlock(&sched_domains_mutex);
 }
 
 #if defined(CONFIG_SCHED_MC) || defined(CONFIG_SCHED_SMT)
-static int arch_reinit_sched_domains(void)
+int arch_reinit_sched_domains(void)
 {
        int err;
 
        get_online_cpus();
+       mutex_lock(&sched_domains_mutex);
        detach_destroy_domains(&cpu_online_map);
        err = arch_init_sched_domains(&cpu_online_map);
+       mutex_unlock(&sched_domains_mutex);
        put_online_cpus();
 
        return err;
@@ -7039,34 +7842,27 @@ void __init sched_init_smp(void)
 {
        cpumask_t non_isolated_cpus;
 
+#if defined(CONFIG_NUMA)
+       sched_group_nodes_bycpu = kzalloc(nr_cpu_ids * sizeof(void **),
+                                                               GFP_KERNEL);
+       BUG_ON(sched_group_nodes_bycpu == NULL);
+#endif
        get_online_cpus();
+       mutex_lock(&sched_domains_mutex);
        arch_init_sched_domains(&cpu_online_map);
        cpus_andnot(non_isolated_cpus, cpu_possible_map, cpu_isolated_map);
        if (cpus_empty(non_isolated_cpus))
                cpu_set(smp_processor_id(), non_isolated_cpus);
+       mutex_unlock(&sched_domains_mutex);
        put_online_cpus();
        /* XXX: Theoretical race here - CPU may be hotplugged now */
        hotcpu_notifier(update_sched_domains, 0);
+       init_hrtick();
 
        /* Move init over to a non-isolated CPU */
-       if (set_cpus_allowed(current, non_isolated_cpus) < 0)
+       if (set_cpus_allowed_ptr(current, &non_isolated_cpus) < 0)
                BUG();
        sched_init_granularity();
-
-#ifdef CONFIG_FAIR_GROUP_SCHED
-       if (nr_cpu_ids == 1)
-               return;
-
-       lb_monitor_task = kthread_create(load_balance_monitor, NULL,
-                                        "group_balance");
-       if (!IS_ERR(lb_monitor_task)) {
-               lb_monitor_task->flags |= PF_NOFREEZE;
-               wake_up_process(lb_monitor_task);
-       } else {
-               printk(KERN_ERR "Could not create load balance monitor thread"
-                       "(error = %ld) \n", PTR_ERR(lb_monitor_task));
-       }
-#endif
 }
 #else
 void __init sched_init_smp(void)
@@ -7085,6 +7881,7 @@ int in_sched_functions(unsigned long addr)
 static void init_cfs_rq(struct cfs_rq *cfs_rq, struct rq *rq)
 {
        cfs_rq->tasks_timeline = RB_ROOT;
+       INIT_LIST_HEAD(&cfs_rq->tasks);
 #ifdef CONFIG_FAIR_GROUP_SCHED
        cfs_rq->rq = rq;
 #endif
@@ -7104,7 +7901,7 @@ static void init_rt_rq(struct rt_rq *rt_rq, struct rq *rq)
        /* delimiter for bitsearch: */
        __set_bit(MAX_RT_PRIO, array->bitmap);
 
-#if defined CONFIG_SMP || defined CONFIG_FAIR_GROUP_SCHED
+#if defined CONFIG_SMP || defined CONFIG_RT_GROUP_SCHED
        rt_rq->highest_prio = MAX_RT_PRIO;
 #endif
 #ifdef CONFIG_SMP
@@ -7114,17 +7911,21 @@ static void init_rt_rq(struct rt_rq *rt_rq, struct rq *rq)
 
        rt_rq->rt_time = 0;
        rt_rq->rt_throttled = 0;
+       rt_rq->rt_runtime = 0;
+       spin_lock_init(&rt_rq->rt_runtime_lock);
 
-#ifdef CONFIG_FAIR_GROUP_SCHED
+#ifdef CONFIG_RT_GROUP_SCHED
+       rt_rq->rt_nr_boosted = 0;
        rt_rq->rq = rq;
 #endif
 }
 
 #ifdef CONFIG_FAIR_GROUP_SCHED
-static void init_tg_cfs_entry(struct rq *rq, struct task_group *tg,
-               struct cfs_rq *cfs_rq, struct sched_entity *se,
-               int cpu, int add)
+static void init_tg_cfs_entry(struct task_group *tg, struct cfs_rq *cfs_rq,
+                               struct sched_entity *se, int cpu, int add,
+                               struct sched_entity *parent)
 {
+       struct rq *rq = cpu_rq(cpu);
        tg->cfs_rq[cpu] = cfs_rq;
        init_cfs_rq(cfs_rq, rq);
        cfs_rq->tg = tg;
@@ -7132,43 +7933,132 @@ static void init_tg_cfs_entry(struct rq *rq, struct task_group *tg,
                list_add(&cfs_rq->leaf_cfs_rq_list, &rq->leaf_cfs_rq_list);
 
        tg->se[cpu] = se;
-       se->cfs_rq = &rq->cfs;
+       /* se could be NULL for init_task_group */
+       if (!se)
+               return;
+
+       if (!parent)
+               se->cfs_rq = &rq->cfs;
+       else
+               se->cfs_rq = parent->my_q;
+
        se->my_q = cfs_rq;
        se->load.weight = tg->shares;
-       se->load.inv_weight = div64_64(1ULL<<32, se->load.weight);
-       se->parent = NULL;
+       se->load.inv_weight = 0;
+       se->parent = parent;
 }
+#endif
 
-static void init_tg_rt_entry(struct rq *rq, struct task_group *tg,
-               struct rt_rq *rt_rq, struct sched_rt_entity *rt_se,
-               int cpu, int add)
+#ifdef CONFIG_RT_GROUP_SCHED
+static void init_tg_rt_entry(struct task_group *tg, struct rt_rq *rt_rq,
+               struct sched_rt_entity *rt_se, int cpu, int add,
+               struct sched_rt_entity *parent)
 {
+       struct rq *rq = cpu_rq(cpu);
+
        tg->rt_rq[cpu] = rt_rq;
        init_rt_rq(rt_rq, rq);
        rt_rq->tg = tg;
        rt_rq->rt_se = rt_se;
+       rt_rq->rt_runtime = tg->rt_bandwidth.rt_runtime;
        if (add)
                list_add(&rt_rq->leaf_rt_rq_list, &rq->leaf_rt_rq_list);
 
        tg->rt_se[cpu] = rt_se;
+       if (!rt_se)
+               return;
+
+       if (!parent)
+               rt_se->rt_rq = &rq->rt;
+       else
+               rt_se->rt_rq = parent->my_q;
+
        rt_se->rt_rq = &rq->rt;
        rt_se->my_q = rt_rq;
-       rt_se->parent = NULL;
+       rt_se->parent = parent;
        INIT_LIST_HEAD(&rt_se->run_list);
 }
 #endif
 
 void __init sched_init(void)
 {
-       int highest_cpu = 0;
        int i, j;
+       unsigned long alloc_size = 0, ptr;
+
+#ifdef CONFIG_FAIR_GROUP_SCHED
+       alloc_size += 2 * nr_cpu_ids * sizeof(void **);
+#endif
+#ifdef CONFIG_RT_GROUP_SCHED
+       alloc_size += 2 * nr_cpu_ids * sizeof(void **);
+#endif
+#ifdef CONFIG_USER_SCHED
+       alloc_size *= 2;
+#endif
+       /*
+        * As sched_init() is called before page_alloc is setup,
+        * we use alloc_bootmem().
+        */
+       if (alloc_size) {
+               ptr = (unsigned long)alloc_bootmem(alloc_size);
+
+#ifdef CONFIG_FAIR_GROUP_SCHED
+               init_task_group.se = (struct sched_entity **)ptr;
+               ptr += nr_cpu_ids * sizeof(void **);
+
+               init_task_group.cfs_rq = (struct cfs_rq **)ptr;
+               ptr += nr_cpu_ids * sizeof(void **);
+
+#ifdef CONFIG_USER_SCHED
+               root_task_group.se = (struct sched_entity **)ptr;
+               ptr += nr_cpu_ids * sizeof(void **);
+
+               root_task_group.cfs_rq = (struct cfs_rq **)ptr;
+               ptr += nr_cpu_ids * sizeof(void **);
+#endif
+#endif
+#ifdef CONFIG_RT_GROUP_SCHED
+               init_task_group.rt_se = (struct sched_rt_entity **)ptr;
+               ptr += nr_cpu_ids * sizeof(void **);
+
+               init_task_group.rt_rq = (struct rt_rq **)ptr;
+               ptr += nr_cpu_ids * sizeof(void **);
+
+#ifdef CONFIG_USER_SCHED
+               root_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
+       }
 
 #ifdef CONFIG_SMP
+       init_aggregate();
        init_defrootdomain();
 #endif
 
-#ifdef CONFIG_FAIR_GROUP_SCHED
+       init_rt_bandwidth(&def_rt_bandwidth,
+                       global_rt_period(), global_rt_runtime());
+
+#ifdef CONFIG_RT_GROUP_SCHED
+       init_rt_bandwidth(&init_task_group.rt_bandwidth,
+                       global_rt_period(), global_rt_runtime());
+#ifdef CONFIG_USER_SCHED
+       init_rt_bandwidth(&root_task_group.rt_bandwidth,
+                       global_rt_period(), RUNTIME_INF);
+#endif
+#endif
+
+#ifdef CONFIG_GROUP_SCHED
        list_add(&init_task_group.list, &task_groups);
+       INIT_LIST_HEAD(&init_task_group.children);
+
+#ifdef CONFIG_USER_SCHED
+       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
 
        for_each_possible_cpu(i) {
@@ -7178,24 +8068,67 @@ void __init sched_init(void)
                spin_lock_init(&rq->lock);
                lockdep_set_class(&rq->lock, &rq->rq_lock_key);
                rq->nr_running = 0;
-               rq->clock = 1;
                init_cfs_rq(&rq->cfs, rq);
                init_rt_rq(&rq->rt, rq);
 #ifdef CONFIG_FAIR_GROUP_SCHED
                init_task_group.shares = init_task_group_load;
                INIT_LIST_HEAD(&rq->leaf_cfs_rq_list);
-               init_tg_cfs_entry(rq, &init_task_group,
+#ifdef CONFIG_CGROUP_SCHED
+               /*
+                * How much cpu bandwidth does init_task_group get?
+                *
+                * In case of task-groups formed thr' the cgroup filesystem, it
+                * gets 100% of the cpu resources in the system. This overall
+                * system cpu resource is divided among the tasks of
+                * init_task_group and its child task-groups in a fair manner,
+                * based on each entity's (task or task-group's) weight
+                * (se->load.weight).
+                *
+                * In other words, if init_task_group has 10 tasks of weight
+                * 1024) and two child groups A0 and A1 (of weight 1024 each),
+                * then A0's share of the cpu resource is:
+                *
+                *      A0's bandwidth = 1024 / (10*1024 + 1024 + 1024) = 8.33%
+                *
+                * We achieve this by letting init_task_group's tasks sit
+                * directly in rq->cfs (i.e init_task_group->se[] = NULL).
+                */
+               init_tg_cfs_entry(&init_task_group, &rq->cfs, NULL, i, 1, NULL);
+#elif defined CONFIG_USER_SCHED
+               root_task_group.shares = NICE_0_LOAD;
+               init_tg_cfs_entry(&root_task_group, &rq->cfs, NULL, i, 0, NULL);
+               /*
+                * In case of task-groups formed thr' the user id of tasks,
+                * init_task_group represents tasks belonging to root user.
+                * Hence it forms a sibling of all subsequent groups formed.
+                * In this case, init_task_group gets only a fraction of overall
+                * system cpu resource, based on the weight assigned to root
+                * user's cpu share (INIT_TASK_GROUP_LOAD). This is accomplished
+                * by letting tasks of init_task_group sit in a separate cfs_rq
+                * (init_cfs_rq) and having one entity represent this group of
+                * tasks in rq->cfs (i.e init_task_group->se[] != NULL).
+                */
+               init_tg_cfs_entry(&init_task_group,
                                &per_cpu(init_cfs_rq, i),
-                               &per_cpu(init_sched_entity, i), i, 1);
+                               &per_cpu(init_sched_entity, i), i, 1,
+                               root_task_group.se[i]);
 
-               init_task_group.rt_ratio = sysctl_sched_rt_ratio; /* XXX */
+#endif
+#endif /* CONFIG_FAIR_GROUP_SCHED */
+
+               rq->rt.rt_runtime = def_rt_bandwidth.rt_runtime;
+#ifdef CONFIG_RT_GROUP_SCHED
                INIT_LIST_HEAD(&rq->leaf_rt_rq_list);
-               init_tg_rt_entry(rq, &init_task_group,
+#ifdef CONFIG_CGROUP_SCHED
+               init_tg_rt_entry(&init_task_group, &rq->rt, NULL, i, 1, NULL);
+#elif defined CONFIG_USER_SCHED
+               init_tg_rt_entry(&root_task_group, &rq->rt, NULL, i, 0, NULL);
+               init_tg_rt_entry(&init_task_group,
                                &per_cpu(init_rt_rq, i),
-                               &per_cpu(init_sched_rt_entity, i), i, 1);
+                               &per_cpu(init_sched_rt_entity, i), i, 1,
+                               root_task_group.rt_se[i]);
+#endif
 #endif
-               rq->rt_period_expire = 0;
-               rq->rt_throttled = 0;
 
                for (j = 0; j < CPU_LOAD_IDX_MAX; j++)
                        rq->cpu_load[j] = 0;
@@ -7212,7 +8145,6 @@ void __init sched_init(void)
 #endif
                init_rq_hrtick(rq);
                atomic_set(&rq->nr_iowait, 0);
-               highest_cpu = i;
        }
 
        set_load_weight(&init_task);
@@ -7222,8 +8154,7 @@ void __init sched_init(void)
 #endif
 
 #ifdef CONFIG_SMP
-       nr_cpu_ids = highest_cpu + 1;
-       open_softirq(SCHED_SOFTIRQ, run_rebalance_domains, NULL);
+       open_softirq(SCHED_SOFTIRQ, run_rebalance_domains);
 #endif
 
 #ifdef CONFIG_RT_MUTEXES
@@ -7247,6 +8178,8 @@ void __init sched_init(void)
         * During early bootup we pretend to be a normal task:
         */
        current->sched_class = &fair_sched_class;
+
+       scheduler_running = 1;
 }
 
 #ifdef CONFIG_DEBUG_SPINLOCK_SLEEP
@@ -7278,6 +8211,7 @@ EXPORT_SYMBOL(__might_sleep);
 static void normalize_task(struct rq *rq, struct task_struct *p)
 {
        int on_rq;
+
        update_rq_clock(rq);
        on_rq = p->se.on_rq;
        if (on_rq)
@@ -7295,7 +8229,7 @@ void normalize_rt_tasks(void)
        unsigned long flags;
        struct rq *rq;
 
-       read_lock_irq(&tasklist_lock);
+       read_lock_irqsave(&tasklist_lock, flags);
        do_each_thread(g, p) {
                /*
                 * Only normalize user tasks:
@@ -7309,7 +8243,6 @@ void normalize_rt_tasks(void)
                p->se.sleep_start               = 0;
                p->se.block_start               = 0;
 #endif
-               task_rq(p)->clock               = 0;
 
                if (!rt_task(p)) {
                        /*
@@ -7321,16 +8254,16 @@ void normalize_rt_tasks(void)
                        continue;
                }
 
-               spin_lock_irqsave(&p->pi_lock, flags);
+               spin_lock(&p->pi_lock);
                rq = __task_rq_lock(p);
 
                normalize_task(rq, p);
 
                __task_rq_unlock(rq);
-               spin_unlock_irqrestore(&p->pi_lock, flags);
+               spin_unlock(&p->pi_lock);
        } while_each_thread(g, p);
 
-       read_unlock_irq(&tasklist_lock);
+       read_unlock_irqrestore(&tasklist_lock, flags);
 }
 
 #endif /* CONFIG_MAGIC_SYSRQ */
@@ -7380,224 +8313,130 @@ void set_curr_task(int cpu, struct task_struct *p)
 #endif
 
 #ifdef CONFIG_FAIR_GROUP_SCHED
-
-#ifdef CONFIG_SMP
-/*
- * distribute shares of all task groups among their schedulable entities,
- * to reflect load distribution across cpus.
- */
-static int rebalance_shares(struct sched_domain *sd, int this_cpu)
+static void free_fair_sched_group(struct task_group *tg)
 {
-       struct cfs_rq *cfs_rq;
-       struct rq *rq = cpu_rq(this_cpu);
-       cpumask_t sdspan = sd->span;
-       int balanced = 1;
-
-       /* Walk thr' all the task groups that we have */
-       for_each_leaf_cfs_rq(rq, cfs_rq) {
-               int i;
-               unsigned long total_load = 0, total_shares;
-               struct task_group *tg = cfs_rq->tg;
-
-               /* Gather total task load of this group across cpus */
-               for_each_cpu_mask(i, sdspan)
-                       total_load += tg->cfs_rq[i]->load.weight;
-
-               /* Nothing to do if this group has no load */
-               if (!total_load)
-                       continue;
-
-               /*
-                * tg->shares represents the number of cpu shares the task group
-                * is eligible to hold on a single cpu. On N cpus, it is
-                * eligible to hold (N * tg->shares) number of cpu shares.
-                */
-               total_shares = tg->shares * cpus_weight(sdspan);
-
-               /*
-                * redistribute total_shares across cpus as per the task load
-                * distribution.
-                */
-               for_each_cpu_mask(i, sdspan) {
-                       unsigned long local_load, local_shares;
-
-                       local_load = tg->cfs_rq[i]->load.weight;
-                       local_shares = (local_load * total_shares) / total_load;
-                       if (!local_shares)
-                               local_shares = MIN_GROUP_SHARES;
-                       if (local_shares == tg->se[i]->load.weight)
-                               continue;
+       int i;
 
-                       spin_lock_irq(&cpu_rq(i)->lock);
-                       set_se_shares(tg->se[i], local_shares);
-                       spin_unlock_irq(&cpu_rq(i)->lock);
-                       balanced = 0;
-               }
+       for_each_possible_cpu(i) {
+               if (tg->cfs_rq)
+                       kfree(tg->cfs_rq[i]);
+               if (tg->se)
+                       kfree(tg->se[i]);
        }
 
-       return balanced;
+       kfree(tg->cfs_rq);
+       kfree(tg->se);
 }
 
-/*
- * How frequently should we rebalance_shares() across cpus?
- *
- * The more frequently we rebalance shares, the more accurate is the fairness
- * of cpu bandwidth distribution between task groups. However higher frequency
- * also implies increased scheduling overhead.
- *
- * sysctl_sched_min_bal_int_shares represents the minimum interval between
- * consecutive calls to rebalance_shares() in the same sched domain.
- *
- * sysctl_sched_max_bal_int_shares represents the maximum interval between
- * consecutive calls to rebalance_shares() in the same sched domain.
- *
- * These settings allows for the appropriate trade-off between accuracy of
- * fairness and the associated overhead.
- *
- */
-
-/* default: 8ms, units: milliseconds */
-const_debug unsigned int sysctl_sched_min_bal_int_shares = 8;
-
-/* default: 128ms, units: milliseconds */
-const_debug unsigned int sysctl_sched_max_bal_int_shares = 128;
-
-/* kernel thread that runs rebalance_shares() periodically */
-static int load_balance_monitor(void *unused)
+static
+int alloc_fair_sched_group(struct task_group *tg, struct task_group *parent)
 {
-       unsigned int timeout = sysctl_sched_min_bal_int_shares;
-       struct sched_param schedparm;
-       int ret;
+       struct cfs_rq *cfs_rq;
+       struct sched_entity *se, *parent_se;
+       struct rq *rq;
+       int i;
 
-       /*
-        * We don't want this thread's execution to be limited by the shares
-        * assigned to default group (init_task_group). Hence make it run
-        * as a SCHED_RR RT task at the lowest priority.
-        */
-       schedparm.sched_priority = 1;
-       ret = sched_setscheduler(current, SCHED_RR, &schedparm);
-       if (ret)
-               printk(KERN_ERR "Couldn't set SCHED_RR policy for load balance"
-                               " monitor thread (error = %d) \n", ret);
+       tg->cfs_rq = kzalloc(sizeof(cfs_rq) * nr_cpu_ids, GFP_KERNEL);
+       if (!tg->cfs_rq)
+               goto err;
+       tg->se = kzalloc(sizeof(se) * nr_cpu_ids, GFP_KERNEL);
+       if (!tg->se)
+               goto err;
 
-       while (!kthread_should_stop()) {
-               int i, cpu, balanced = 1;
+       tg->shares = NICE_0_LOAD;
 
-               /* Prevent cpus going down or coming up */
-               get_online_cpus();
-               /* lockout changes to doms_cur[] array */
-               lock_doms_cur();
-               /*
-                * Enter a rcu read-side critical section to safely walk rq->sd
-                * chain on various cpus and to walk task group list
-                * (rq->leaf_cfs_rq_list) in rebalance_shares().
-                */
-               rcu_read_lock();
+       for_each_possible_cpu(i) {
+               rq = cpu_rq(i);
 
-               for (i = 0; i < ndoms_cur; i++) {
-                       cpumask_t cpumap = doms_cur[i];
-                       struct sched_domain *sd = NULL, *sd_prev = NULL;
+               cfs_rq = kmalloc_node(sizeof(struct cfs_rq),
+                               GFP_KERNEL|__GFP_ZERO, cpu_to_node(i));
+               if (!cfs_rq)
+                       goto err;
 
-                       cpu = first_cpu(cpumap);
+               se = kmalloc_node(sizeof(struct sched_entity),
+                               GFP_KERNEL|__GFP_ZERO, cpu_to_node(i));
+               if (!se)
+                       goto err;
 
-                       /* Find the highest domain at which to balance shares */
-                       for_each_domain(cpu, sd) {
-                               if (!(sd->flags & SD_LOAD_BALANCE))
-                                       continue;
-                               sd_prev = sd;
-                       }
+               parent_se = parent ? parent->se[i] : NULL;
+               init_tg_cfs_entry(tg, cfs_rq, se, i, 0, parent_se);
+       }
 
-                       sd = sd_prev;
-                       /* sd == NULL? No load balance reqd in this domain */
-                       if (!sd)
-                               continue;
+       return 1;
 
-                       balanced &= rebalance_shares(sd, cpu);
-               }
+ err:
+       return 0;
+}
 
-               rcu_read_unlock();
+static inline void register_fair_sched_group(struct task_group *tg, int cpu)
+{
+       list_add_rcu(&tg->cfs_rq[cpu]->leaf_cfs_rq_list,
+                       &cpu_rq(cpu)->leaf_cfs_rq_list);
+}
 
-               unlock_doms_cur();
-               put_online_cpus();
+static inline void unregister_fair_sched_group(struct task_group *tg, int cpu)
+{
+       list_del_rcu(&tg->cfs_rq[cpu]->leaf_cfs_rq_list);
+}
+#else
+static inline void free_fair_sched_group(struct task_group *tg)
+{
+}
 
-               if (!balanced)
-                       timeout = sysctl_sched_min_bal_int_shares;
-               else if (timeout < sysctl_sched_max_bal_int_shares)
-                       timeout *= 2;
+static inline
+int alloc_fair_sched_group(struct task_group *tg, struct task_group *parent)
+{
+       return 1;
+}
 
-               msleep_interruptible(timeout);
-       }
+static inline void register_fair_sched_group(struct task_group *tg, int cpu)
+{
+}
 
-       return 0;
+static inline void unregister_fair_sched_group(struct task_group *tg, int cpu)
+{
 }
-#endif /* CONFIG_SMP */
+#endif
 
-static void free_sched_group(struct task_group *tg)
+#ifdef CONFIG_RT_GROUP_SCHED
+static void free_rt_sched_group(struct task_group *tg)
 {
        int i;
 
+       destroy_rt_bandwidth(&tg->rt_bandwidth);
+
        for_each_possible_cpu(i) {
-               if (tg->cfs_rq)
-                       kfree(tg->cfs_rq[i]);
-               if (tg->se)
-                       kfree(tg->se[i]);
                if (tg->rt_rq)
                        kfree(tg->rt_rq[i]);
                if (tg->rt_se)
                        kfree(tg->rt_se[i]);
        }
 
-       kfree(tg->cfs_rq);
-       kfree(tg->se);
        kfree(tg->rt_rq);
        kfree(tg->rt_se);
-       kfree(tg);
 }
 
-/* allocate runqueue etc for a new task group */
-struct task_group *sched_create_group(void)
+static
+int alloc_rt_sched_group(struct task_group *tg, struct task_group *parent)
 {
-       struct task_group *tg;
-       struct cfs_rq *cfs_rq;
-       struct sched_entity *se;
        struct rt_rq *rt_rq;
-       struct sched_rt_entity *rt_se;
+       struct sched_rt_entity *rt_se, *parent_se;
        struct rq *rq;
        int i;
 
-       tg = kzalloc(sizeof(*tg), GFP_KERNEL);
-       if (!tg)
-               return ERR_PTR(-ENOMEM);
-
-       tg->cfs_rq = kzalloc(sizeof(cfs_rq) * NR_CPUS, GFP_KERNEL);
-       if (!tg->cfs_rq)
-               goto err;
-       tg->se = kzalloc(sizeof(se) * NR_CPUS, GFP_KERNEL);
-       if (!tg->se)
-               goto err;
-       tg->rt_rq = kzalloc(sizeof(rt_rq) * NR_CPUS, GFP_KERNEL);
+       tg->rt_rq = kzalloc(sizeof(rt_rq) * nr_cpu_ids, GFP_KERNEL);
        if (!tg->rt_rq)
                goto err;
-       tg->rt_se = kzalloc(sizeof(rt_se) * NR_CPUS, GFP_KERNEL);
+       tg->rt_se = kzalloc(sizeof(rt_se) * nr_cpu_ids, GFP_KERNEL);
        if (!tg->rt_se)
                goto err;
 
-       tg->shares = NICE_0_LOAD;
-       tg->rt_ratio = 0; /* XXX */
+       init_rt_bandwidth(&tg->rt_bandwidth,
+                       ktime_to_ns(def_rt_bandwidth.rt_period), 0);
 
        for_each_possible_cpu(i) {
                rq = cpu_rq(i);
 
-               cfs_rq = kmalloc_node(sizeof(struct cfs_rq),
-                               GFP_KERNEL|__GFP_ZERO, cpu_to_node(i));
-               if (!cfs_rq)
-                       goto err;
-
-               se = kmalloc_node(sizeof(struct sched_entity),
-                               GFP_KERNEL|__GFP_ZERO, cpu_to_node(i));
-               if (!se)
-                       goto err;
-
                rt_rq = kmalloc_node(sizeof(struct rt_rq),
                                GFP_KERNEL|__GFP_ZERO, cpu_to_node(i));
                if (!rt_rq)
@@ -7608,20 +8447,84 @@ struct task_group *sched_create_group(void)
                if (!rt_se)
                        goto err;
 
-               init_tg_cfs_entry(rq, tg, cfs_rq, se, i, 0);
-               init_tg_rt_entry(rq, tg, rt_rq, rt_se, i, 0);
+               parent_se = parent ? parent->rt_se[i] : NULL;
+               init_tg_rt_entry(tg, rt_rq, rt_se, i, 0, parent_se);
        }
 
-       lock_task_group_list();
+       return 1;
+
+ err:
+       return 0;
+}
+
+static inline void register_rt_sched_group(struct task_group *tg, int cpu)
+{
+       list_add_rcu(&tg->rt_rq[cpu]->leaf_rt_rq_list,
+                       &cpu_rq(cpu)->leaf_rt_rq_list);
+}
+
+static inline void unregister_rt_sched_group(struct task_group *tg, int cpu)
+{
+       list_del_rcu(&tg->rt_rq[cpu]->leaf_rt_rq_list);
+}
+#else
+static inline void free_rt_sched_group(struct task_group *tg)
+{
+}
+
+static inline
+int alloc_rt_sched_group(struct task_group *tg, struct task_group *parent)
+{
+       return 1;
+}
+
+static inline void register_rt_sched_group(struct task_group *tg, int cpu)
+{
+}
+
+static inline void unregister_rt_sched_group(struct task_group *tg, int cpu)
+{
+}
+#endif
+
+#ifdef CONFIG_GROUP_SCHED
+static void free_sched_group(struct task_group *tg)
+{
+       free_fair_sched_group(tg);
+       free_rt_sched_group(tg);
+       kfree(tg);
+}
+
+/* allocate runqueue etc for a new task group */
+struct task_group *sched_create_group(struct task_group *parent)
+{
+       struct task_group *tg;
+       unsigned long flags;
+       int i;
+
+       tg = kzalloc(sizeof(*tg), GFP_KERNEL);
+       if (!tg)
+               return ERR_PTR(-ENOMEM);
+
+       if (!alloc_fair_sched_group(tg, parent))
+               goto err;
+
+       if (!alloc_rt_sched_group(tg, parent))
+               goto err;
+
+       spin_lock_irqsave(&task_group_lock, flags);
        for_each_possible_cpu(i) {
-               rq = cpu_rq(i);
-               cfs_rq = tg->cfs_rq[i];
-               list_add_rcu(&cfs_rq->leaf_cfs_rq_list, &rq->leaf_cfs_rq_list);
-               rt_rq = tg->rt_rq[i];
-               list_add_rcu(&rt_rq->leaf_rt_rq_list, &rq->leaf_rt_rq_list);
+               register_fair_sched_group(tg, i);
+               register_rt_sched_group(tg, i);
        }
        list_add_rcu(&tg->list, &task_groups);
-       unlock_task_group_list();
+
+       WARN_ON(!parent); /* root should already exist */
+
+       tg->parent = parent;
+       list_add_rcu(&tg->siblings, &parent->children);
+       INIT_LIST_HEAD(&tg->children);
+       spin_unlock_irqrestore(&task_group_lock, flags);
 
        return tg;
 
@@ -7640,21 +8543,17 @@ static void free_sched_group_rcu(struct rcu_head *rhp)
 /* Destroy runqueue etc associated with a task group */
 void sched_destroy_group(struct task_group *tg)
 {
-       struct cfs_rq *cfs_rq = NULL;
-       struct rt_rq *rt_rq = NULL;
+       unsigned long flags;
        int i;
 
-       lock_task_group_list();
+       spin_lock_irqsave(&task_group_lock, flags);
        for_each_possible_cpu(i) {
-               cfs_rq = tg->cfs_rq[i];
-               list_del_rcu(&cfs_rq->leaf_cfs_rq_list);
-               rt_rq = tg->rt_rq[i];
-               list_del_rcu(&rt_rq->leaf_rt_rq_list);
+               unregister_fair_sched_group(tg, i);
+               unregister_rt_sched_group(tg, i);
        }
        list_del_rcu(&tg->list);
-       unlock_task_group_list();
-
-       BUG_ON(!cfs_rq);
+       list_del_rcu(&tg->siblings);
+       spin_unlock_irqrestore(&task_group_lock, flags);
 
        /* wait for possible concurrent references to cfs_rqs complete */
        call_rcu(&tg->rcu, free_sched_group_rcu);
@@ -7678,70 +8577,82 @@ void sched_move_task(struct task_struct *tsk)
        running = task_current(rq, tsk);
        on_rq = tsk->se.on_rq;
 
-       if (on_rq) {
+       if (on_rq)
                dequeue_task(rq, tsk, 0);
-               if (unlikely(running))
-                       tsk->sched_class->put_prev_task(rq, tsk);
-       }
+       if (unlikely(running))
+               tsk->sched_class->put_prev_task(rq, tsk);
 
        set_task_rq(tsk, task_cpu(tsk));
 
-       if (on_rq) {
-               if (unlikely(running))
-                       tsk->sched_class->set_curr_task(rq);
+#ifdef CONFIG_FAIR_GROUP_SCHED
+       if (tsk->sched_class->moved_group)
+               tsk->sched_class->moved_group(tsk);
+#endif
+
+       if (unlikely(running))
+               tsk->sched_class->set_curr_task(rq);
+       if (on_rq)
                enqueue_task(rq, tsk, 0);
-       }
 
        task_rq_unlock(rq, &flags);
 }
+#endif
 
-/* rq->lock to be locked by caller */
-static void set_se_shares(struct sched_entity *se, unsigned long shares)
+#ifdef CONFIG_FAIR_GROUP_SCHED
+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;
 
-       if (!shares)
-               shares = MIN_GROUP_SHARES;
-
        on_rq = se->on_rq;
-       if (on_rq) {
+       if (on_rq)
                dequeue_entity(cfs_rq, se, 0);
-               dec_cpu_load(rq, se->load.weight);
-       }
 
        se->load.weight = shares;
-       se->load.inv_weight = div64_64((1ULL<<32), shares);
+       se->load.inv_weight = 0;
 
-       if (on_rq) {
+       if (on_rq)
                enqueue_entity(cfs_rq, se, 0);
-               inc_cpu_load(rq, se->load.weight);
-       }
 }
 
+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);
+
 int sched_group_set_shares(struct task_group *tg, unsigned long shares)
 {
        int i;
-       struct cfs_rq *cfs_rq;
-       struct rq *rq;
+       unsigned long flags;
+
+       /*
+        * We can't change the weight of the root cgroup.
+        */
+       if (!tg->se[0])
+               return -EINVAL;
+
+       if (shares < MIN_SHARES)
+               shares = MIN_SHARES;
+       else if (shares > MAX_SHARES)
+               shares = MAX_SHARES;
 
-       lock_task_group_list();
+       mutex_lock(&shares_mutex);
        if (tg->shares == shares)
                goto done;
 
-       if (shares < MIN_GROUP_SHARES)
-               shares = MIN_GROUP_SHARES;
-
-       /*
-        * Prevent any load balance activity (rebalance_shares,
-        * load_balance_fair) from referring to this group first,
-        * by taking it off the rq->leaf_cfs_rq_list on each cpu.
-        */
-       for_each_possible_cpu(i) {
-               cfs_rq = tg->cfs_rq[i];
-               list_del_rcu(&cfs_rq->leaf_cfs_rq_list);
-       }
+       spin_lock_irqsave(&task_group_lock, flags);
+       for_each_possible_cpu(i)
+               unregister_fair_sched_group(tg, i);
+       list_del_rcu(&tg->siblings);
+       spin_unlock_irqrestore(&task_group_lock, flags);
 
        /* wait for any ongoing reference to this group to finish */
        synchronize_sched();
@@ -7752,22 +8663,24 @@ int sched_group_set_shares(struct task_group *tg, unsigned long shares)
         */
        tg->shares = shares;
        for_each_possible_cpu(i) {
-               spin_lock_irq(&cpu_rq(i)->lock);
+               /*
+                * force a rebalance
+                */
+               cfs_rq_set_shares(tg->cfs_rq[i], 0);
                set_se_shares(tg->se[i], shares);
-               spin_unlock_irq(&cpu_rq(i)->lock);
        }
 
        /*
         * Enable load balance activity on this group, by inserting it back on
         * each cpu's rq->leaf_cfs_rq_list.
         */
-       for_each_possible_cpu(i) {
-               rq = cpu_rq(i);
-               cfs_rq = tg->cfs_rq[i];
-               list_add_rcu(&cfs_rq->leaf_cfs_rq_list, &rq->leaf_cfs_rq_list);
-       }
+       spin_lock_irqsave(&task_group_lock, flags);
+       for_each_possible_cpu(i)
+               register_fair_sched_group(tg, i);
+       list_add_rcu(&tg->siblings, &tg->parent->children);
+       spin_unlock_irqrestore(&task_group_lock, flags);
 done:
-       unlock_task_group_list();
+       mutex_unlock(&shares_mutex);
        return 0;
 }
 
@@ -7775,35 +8688,226 @@ unsigned long sched_group_shares(struct task_group *tg)
 {
        return tg->shares;
 }
+#endif
 
+#ifdef CONFIG_RT_GROUP_SCHED
 /*
- * Ensure the total rt_ratio <= sysctl_sched_rt_ratio
+ * Ensure that the real time constraints are schedulable.
  */
-int sched_group_set_rt_ratio(struct task_group *tg, unsigned long rt_ratio)
+static DEFINE_MUTEX(rt_constraints_mutex);
+
+static unsigned long to_ratio(u64 period, u64 runtime)
+{
+       if (runtime == RUNTIME_INF)
+               return 1ULL << 16;
+
+       return div64_u64(runtime << 16, period);
+}
+
+#ifdef CONFIG_CGROUP_SCHED
+static int __rt_schedulable(struct task_group *tg, u64 period, u64 runtime)
+{
+       struct task_group *tgi, *parent = tg->parent;
+       unsigned long total = 0;
+
+       if (!parent) {
+               if (global_rt_period() < period)
+                       return 0;
+
+               return to_ratio(period, runtime) <
+                       to_ratio(global_rt_period(), global_rt_runtime());
+       }
+
+       if (ktime_to_ns(parent->rt_bandwidth.rt_period) < period)
+               return 0;
+
+       rcu_read_lock();
+       list_for_each_entry_rcu(tgi, &parent->children, siblings) {
+               if (tgi == tg)
+                       continue;
+
+               total += to_ratio(ktime_to_ns(tgi->rt_bandwidth.rt_period),
+                               tgi->rt_bandwidth.rt_runtime);
+       }
+       rcu_read_unlock();
+
+       return total + to_ratio(period, runtime) <
+               to_ratio(ktime_to_ns(parent->rt_bandwidth.rt_period),
+                               parent->rt_bandwidth.rt_runtime);
+}
+#elif defined CONFIG_USER_SCHED
+static int __rt_schedulable(struct task_group *tg, u64 period, u64 runtime)
 {
        struct task_group *tgi;
        unsigned long total = 0;
+       unsigned long global_ratio =
+               to_ratio(global_rt_period(), global_rt_runtime());
 
        rcu_read_lock();
-       list_for_each_entry_rcu(tgi, &task_groups, list)
-               total += tgi->rt_ratio;
+       list_for_each_entry_rcu(tgi, &task_groups, list) {
+               if (tgi == tg)
+                       continue;
+
+               total += to_ratio(ktime_to_ns(tgi->rt_bandwidth.rt_period),
+                               tgi->rt_bandwidth.rt_runtime);
+       }
        rcu_read_unlock();
 
-       if (total + rt_ratio - tg->rt_ratio > sysctl_sched_rt_ratio)
-               return -EINVAL;
+       return total + to_ratio(period, runtime) < global_ratio;
+}
+#endif
 
-       tg->rt_ratio = rt_ratio;
+/* Must be called with tasklist_lock held */
+static inline int tg_has_rt_tasks(struct task_group *tg)
+{
+       struct task_struct *g, *p;
+       do_each_thread(g, p) {
+               if (rt_task(p) && rt_rq_of_se(&p->rt)->tg == tg)
+                       return 1;
+       } while_each_thread(g, p);
        return 0;
 }
 
-unsigned long sched_group_rt_ratio(struct task_group *tg)
+static int tg_set_bandwidth(struct task_group *tg,
+               u64 rt_period, u64 rt_runtime)
 {
-       return tg->rt_ratio;
+       int i, err = 0;
+
+       mutex_lock(&rt_constraints_mutex);
+       read_lock(&tasklist_lock);
+       if (rt_runtime == 0 && tg_has_rt_tasks(tg)) {
+               err = -EBUSY;
+               goto unlock;
+       }
+       if (!__rt_schedulable(tg, rt_period, rt_runtime)) {
+               err = -EINVAL;
+               goto unlock;
+       }
+
+       spin_lock_irq(&tg->rt_bandwidth.rt_runtime_lock);
+       tg->rt_bandwidth.rt_period = ns_to_ktime(rt_period);
+       tg->rt_bandwidth.rt_runtime = rt_runtime;
+
+       for_each_possible_cpu(i) {
+               struct rt_rq *rt_rq = tg->rt_rq[i];
+
+               spin_lock(&rt_rq->rt_runtime_lock);
+               rt_rq->rt_runtime = rt_runtime;
+               spin_unlock(&rt_rq->rt_runtime_lock);
+       }
+       spin_unlock_irq(&tg->rt_bandwidth.rt_runtime_lock);
+ unlock:
+       read_unlock(&tasklist_lock);
+       mutex_unlock(&rt_constraints_mutex);
+
+       return err;
+}
+
+int sched_group_set_rt_runtime(struct task_group *tg, long rt_runtime_us)
+{
+       u64 rt_runtime, rt_period;
+
+       rt_period = ktime_to_ns(tg->rt_bandwidth.rt_period);
+       rt_runtime = (u64)rt_runtime_us * NSEC_PER_USEC;
+       if (rt_runtime_us < 0)
+               rt_runtime = RUNTIME_INF;
+
+       return tg_set_bandwidth(tg, rt_period, rt_runtime);
 }
 
-#endif /* CONFIG_FAIR_GROUP_SCHED */
+long sched_group_rt_runtime(struct task_group *tg)
+{
+       u64 rt_runtime_us;
+
+       if (tg->rt_bandwidth.rt_runtime == RUNTIME_INF)
+               return -1;
 
-#ifdef CONFIG_FAIR_CGROUP_SCHED
+       rt_runtime_us = tg->rt_bandwidth.rt_runtime;
+       do_div(rt_runtime_us, NSEC_PER_USEC);
+       return rt_runtime_us;
+}
+
+int sched_group_set_rt_period(struct task_group *tg, long rt_period_us)
+{
+       u64 rt_runtime, rt_period;
+
+       rt_period = (u64)rt_period_us * NSEC_PER_USEC;
+       rt_runtime = tg->rt_bandwidth.rt_runtime;
+
+       return tg_set_bandwidth(tg, rt_period, rt_runtime);
+}
+
+long sched_group_rt_period(struct task_group *tg)
+{
+       u64 rt_period_us;
+
+       rt_period_us = ktime_to_ns(tg->rt_bandwidth.rt_period);
+       do_div(rt_period_us, NSEC_PER_USEC);
+       return rt_period_us;
+}
+
+static int sched_rt_global_constraints(void)
+{
+       int ret = 0;
+
+       mutex_lock(&rt_constraints_mutex);
+       if (!__rt_schedulable(NULL, 1, 0))
+               ret = -EINVAL;
+       mutex_unlock(&rt_constraints_mutex);
+
+       return ret;
+}
+#else
+static int sched_rt_global_constraints(void)
+{
+       unsigned long flags;
+       int i;
+
+       spin_lock_irqsave(&def_rt_bandwidth.rt_runtime_lock, flags);
+       for_each_possible_cpu(i) {
+               struct rt_rq *rt_rq = &cpu_rq(i)->rt;
+
+               spin_lock(&rt_rq->rt_runtime_lock);
+               rt_rq->rt_runtime = global_rt_runtime();
+               spin_unlock(&rt_rq->rt_runtime_lock);
+       }
+       spin_unlock_irqrestore(&def_rt_bandwidth.rt_runtime_lock, flags);
+
+       return 0;
+}
+#endif
+
+int sched_rt_handler(struct ctl_table *table, int write,
+               struct file *filp, void __user *buffer, size_t *lenp,
+               loff_t *ppos)
+{
+       int ret;
+       int old_period, old_runtime;
+       static DEFINE_MUTEX(mutex);
+
+       mutex_lock(&mutex);
+       old_period = sysctl_sched_rt_period;
+       old_runtime = sysctl_sched_rt_runtime;
+
+       ret = proc_dointvec(table, write, filp, buffer, lenp, ppos);
+
+       if (!ret && write) {
+               ret = sched_rt_global_constraints();
+               if (ret) {
+                       sysctl_sched_rt_period = old_period;
+                       sysctl_sched_rt_runtime = old_runtime;
+               } else {
+                       def_rt_bandwidth.rt_runtime = global_rt_runtime();
+                       def_rt_bandwidth.rt_period =
+                               ns_to_ktime(global_rt_period());
+               }
+       }
+       mutex_unlock(&mutex);
+
+       return ret;
+}
+
+#ifdef CONFIG_CGROUP_SCHED
 
 /* return corresponding task_group object of a cgroup */
 static inline struct task_group *cgroup_tg(struct cgroup *cgrp)
@@ -7815,7 +8919,7 @@ static inline struct task_group *cgroup_tg(struct cgroup *cgrp)
 static struct cgroup_subsys_state *
 cpu_cgroup_create(struct cgroup_subsys *ss, struct cgroup *cgrp)
 {
-       struct task_group *tg;
+       struct task_group *tg, *parent;
 
        if (!cgrp->parent) {
                /* This is early initialization for the top cgroup */
@@ -7823,11 +8927,8 @@ cpu_cgroup_create(struct cgroup_subsys *ss, struct cgroup *cgrp)
                return &init_task_group.css;
        }
 
-       /* we support only 1-level deep hierarchical scheduler atm */
-       if (cgrp->parent->parent)
-               return ERR_PTR(-EINVAL);
-
-       tg = sched_create_group();
+       parent = cgroup_tg(cgrp->parent);
+       tg = sched_create_group(parent);
        if (IS_ERR(tg))
                return ERR_PTR(-ENOMEM);
 
@@ -7849,9 +8950,15 @@ static int
 cpu_cgroup_can_attach(struct cgroup_subsys *ss, struct cgroup *cgrp,
                      struct task_struct *tsk)
 {
+#ifdef CONFIG_RT_GROUP_SCHED
+       /* Don't accept realtime tasks when there is no way for them to run */
+       if (rt_task(tsk) && cgroup_tg(cgrp)->rt_bandwidth.rt_runtime == 0)
+               return -EINVAL;
+#else
        /* We don't support RT-tasks being in separate groups */
        if (tsk->sched_class != &fair_sched_class)
                return -EINVAL;
+#endif
 
        return 0;
 }
@@ -7863,43 +8970,65 @@ cpu_cgroup_attach(struct cgroup_subsys *ss, struct cgroup *cgrp,
        sched_move_task(tsk);
 }
 
-static int cpu_shares_write_uint(struct cgroup *cgrp, struct cftype *cftype,
+#ifdef CONFIG_FAIR_GROUP_SCHED
+static int cpu_shares_write_u64(struct cgroup *cgrp, struct cftype *cftype,
                                u64 shareval)
 {
        return sched_group_set_shares(cgroup_tg(cgrp), shareval);
 }
 
-static u64 cpu_shares_read_uint(struct cgroup *cgrp, struct cftype *cft)
+static u64 cpu_shares_read_u64(struct cgroup *cgrp, struct cftype *cft)
 {
        struct task_group *tg = cgroup_tg(cgrp);
 
        return (u64) tg->shares;
 }
+#endif
 
-static int cpu_rt_ratio_write_uint(struct cgroup *cgrp, struct cftype *cftype,
-               u64 rt_ratio_val)
+#ifdef CONFIG_RT_GROUP_SCHED
+static int cpu_rt_runtime_write(struct cgroup *cgrp, struct cftype *cft,
+                               s64 val)
 {
-       return sched_group_set_rt_ratio(cgroup_tg(cgrp), rt_ratio_val);
+       return sched_group_set_rt_runtime(cgroup_tg(cgrp), val);
 }
 
-static u64 cpu_rt_ratio_read_uint(struct cgroup *cgrp, struct cftype *cft)
+static s64 cpu_rt_runtime_read(struct cgroup *cgrp, struct cftype *cft)
 {
-       struct task_group *tg = cgroup_tg(cgrp);
+       return sched_group_rt_runtime(cgroup_tg(cgrp));
+}
 
-       return (u64) tg->rt_ratio;
+static int cpu_rt_period_write_uint(struct cgroup *cgrp, struct cftype *cftype,
+               u64 rt_period_us)
+{
+       return sched_group_set_rt_period(cgroup_tg(cgrp), rt_period_us);
+}
+
+static u64 cpu_rt_period_read_uint(struct cgroup *cgrp, struct cftype *cft)
+{
+       return sched_group_rt_period(cgroup_tg(cgrp));
 }
+#endif
 
 static struct cftype cpu_files[] = {
+#ifdef CONFIG_FAIR_GROUP_SCHED
        {
                .name = "shares",
-               .read_uint = cpu_shares_read_uint,
-               .write_uint = cpu_shares_write_uint,
+               .read_u64 = cpu_shares_read_u64,
+               .write_u64 = cpu_shares_write_u64,
+       },
+#endif
+#ifdef CONFIG_RT_GROUP_SCHED
+       {
+               .name = "rt_runtime_us",
+               .read_s64 = cpu_rt_runtime_read,
+               .write_s64 = cpu_rt_runtime_write,
        },
        {
-               .name = "rt_ratio",
-               .read_uint = cpu_rt_ratio_read_uint,
-               .write_uint = cpu_rt_ratio_write_uint,
+               .name = "rt_period_us",
+               .read_u64 = cpu_rt_period_read_uint,
+               .write_u64 = cpu_rt_period_write_uint,
        },
+#endif
 };
 
 static int cpu_cgroup_populate(struct cgroup_subsys *ss, struct cgroup *cont)
@@ -7918,7 +9047,7 @@ struct cgroup_subsys cpu_cgroup_subsys = {
        .early_init     = 1,
 };
 
-#endif /* CONFIG_FAIR_CGROUP_SCHED */
+#endif /* CONFIG_CGROUP_SCHED */
 
 #ifdef CONFIG_CGROUP_CPUACCT
 
@@ -7939,9 +9068,9 @@ struct cpuacct {
 struct cgroup_subsys cpuacct_subsys;
 
 /* return cpu accounting group corresponding to this container */
-static inline struct cpuacct *cgroup_ca(struct cgroup *cont)
+static inline struct cpuacct *cgroup_ca(struct cgroup *cgrp)
 {
-       return container_of(cgroup_subsys_state(cont, cpuacct_subsys_id),
+       return container_of(cgroup_subsys_state(cgrp, cpuacct_subsys_id),
                            struct cpuacct, css);
 }
 
@@ -7954,7 +9083,7 @@ static inline struct cpuacct *task_ca(struct task_struct *tsk)
 
 /* create a new cpu accounting group */
 static struct cgroup_subsys_state *cpuacct_create(
-       struct cgroup_subsys *ss, struct cgroup *cont)
+       struct cgroup_subsys *ss, struct cgroup *cgrp)
 {
        struct cpuacct *ca = kzalloc(sizeof(*ca), GFP_KERNEL);
 
@@ -7972,18 +9101,18 @@ static struct cgroup_subsys_state *cpuacct_create(
 
 /* destroy an existing cpu accounting group */
 static void
-cpuacct_destroy(struct cgroup_subsys *ss, struct cgroup *cont)
+cpuacct_destroy(struct cgroup_subsys *ss, struct cgroup *cgrp)
 {
-       struct cpuacct *ca = cgroup_ca(cont);
+       struct cpuacct *ca = cgroup_ca(cgrp);
 
        free_percpu(ca->cpuusage);
        kfree(ca);
 }
 
 /* return total cpu usage (in nanoseconds) of a group */
-static u64 cpuusage_read(struct cgroup *cont, struct cftype *cft)
+static u64 cpuusage_read(struct cgroup *cgrp, struct cftype *cft)
 {
-       struct cpuacct *ca = cgroup_ca(cont);
+       struct cpuacct *ca = cgroup_ca(cgrp);
        u64 totalcpuusage = 0;
        int i;
 
@@ -8002,16 +9131,40 @@ static u64 cpuusage_read(struct cgroup *cont, struct cftype *cft)
        return totalcpuusage;
 }
 
+static int cpuusage_write(struct cgroup *cgrp, struct cftype *cftype,
+                                                               u64 reset)
+{
+       struct cpuacct *ca = cgroup_ca(cgrp);
+       int err = 0;
+       int i;
+
+       if (reset) {
+               err = -EINVAL;
+               goto out;
+       }
+
+       for_each_possible_cpu(i) {
+               u64 *cpuusage = percpu_ptr(ca->cpuusage, i);
+
+               spin_lock_irq(&cpu_rq(i)->lock);
+               *cpuusage = 0;
+               spin_unlock_irq(&cpu_rq(i)->lock);
+       }
+out:
+       return err;
+}
+
 static struct cftype files[] = {
        {
                .name = "usage",
-               .read_uint = cpuusage_read,
+               .read_u64 = cpuusage_read,
+               .write_u64 = cpuusage_write,
        },
 };
 
-static int cpuacct_populate(struct cgroup_subsys *ss, struct cgroup *cont)
+static int cpuacct_populate(struct cgroup_subsys *ss, struct cgroup *cgrp)
 {
-       return cgroup_add_files(cont, ss, files, ARRAY_SIZE(files));
+       return cgroup_add_files(cgrp, ss, files, ARRAY_SIZE(files));
 }
 
 /*