Merge remote-tracking branch 'stable/linux-3.0.y' into develop-3.0
[firefly-linux-kernel-4.4.55.git] / kernel / sched.c
index aacd55f8d4ea2ba17154ac43ae359498081653af..c4743ee8bcbc4249e473a29de5cf7731e774e854 100644 (file)
@@ -71,6 +71,7 @@
 #include <linux/ctype.h>
 #include <linux/ftrace.h>
 #include <linux/slab.h>
+#include <linux/cpuacct.h>
 
 #include <asm/tlb.h>
 #include <asm/irq_regs.h>
@@ -6476,7 +6477,7 @@ static int __cpuinit sched_cpu_active(struct notifier_block *nfb,
                                      unsigned long action, void *hcpu)
 {
        switch (action & ~CPU_TASKS_FROZEN) {
-       case CPU_ONLINE:
+       case CPU_STARTING:
        case CPU_DOWN_FAILED:
                set_cpu_active((long)hcpu, true);
                return NOTIFY_OK;
@@ -7949,7 +7950,7 @@ static void init_rt_rq(struct rt_rq *rt_rq, struct rq *rq)
 #ifdef CONFIG_SMP
        rt_rq->rt_nr_migratory = 0;
        rt_rq->overloaded = 0;
-       plist_head_init_raw(&rt_rq->pushable_tasks, &rq->lock);
+       plist_head_init(&rt_rq->pushable_tasks);
 #endif
 
        rt_rq->rt_time = 0;
@@ -8154,7 +8155,7 @@ void __init sched_init(void)
 #endif
 
 #ifdef CONFIG_RT_MUTEXES
-       plist_head_init_raw(&init_task.pi_waiters, &init_task.pi_lock);
+       plist_head_init(&init_task.pi_waiters);
 #endif
 
        /*
@@ -8205,13 +8206,24 @@ static inline int preempt_count_equals(int preempt_offset)
        return (nested == preempt_offset);
 }
 
+static int __might_sleep_init_called;
+int __init __might_sleep_init(void)
+{
+       __might_sleep_init_called = 1;
+       return 0;
+}
+early_initcall(__might_sleep_init);
+
 void __might_sleep(const char *file, int line, int preempt_offset)
 {
 #ifdef in_atomic
        static unsigned long prev_jiffy;        /* ratelimiting */
 
        if ((preempt_count_equals(preempt_offset) && !irqs_disabled()) ||
-           system_state != SYSTEM_RUNNING || oops_in_progress)
+           oops_in_progress)
+               return;
+       if (system_state != SYSTEM_RUNNING &&
+           (!__might_sleep_init_called || system_state != SYSTEM_BOOTING))
                return;
        if (time_before(jiffies, prev_jiffy + HZ) && prev_jiffy)
                return;
@@ -8961,6 +8973,20 @@ cpu_cgroup_destroy(struct cgroup_subsys *ss, struct cgroup *cgrp)
        sched_destroy_group(tg);
 }
 
+static int
+cpu_cgroup_allow_attach(struct cgroup *cgrp, struct task_struct *tsk)
+{
+       const struct cred *cred = current_cred(), *tcred;
+
+       tcred = __task_cred(tsk);
+
+       if ((current != tsk) && !capable(CAP_SYS_NICE) &&
+           cred->euid != tcred->uid && cred->euid != tcred->suid)
+               return -EACCES;
+
+       return 0;
+}
+
 static int
 cpu_cgroup_can_attach_task(struct cgroup *cgrp, struct task_struct *tsk)
 {
@@ -9066,6 +9092,7 @@ struct cgroup_subsys cpu_cgroup_subsys = {
        .name           = "cpu",
        .create         = cpu_cgroup_create,
        .destroy        = cpu_cgroup_destroy,
+       .allow_attach   = cpu_cgroup_allow_attach,
        .can_attach_task = cpu_cgroup_can_attach_task,
        .attach_task    = cpu_cgroup_attach_task,
        .exit           = cpu_cgroup_exit,
@@ -9092,8 +9119,30 @@ struct cpuacct {
        u64 __percpu *cpuusage;
        struct percpu_counter cpustat[CPUACCT_STAT_NSTATS];
        struct cpuacct *parent;
+       struct cpuacct_charge_calls *cpufreq_fn;
+       void *cpuacct_data;
 };
 
+static struct cpuacct *cpuacct_root;
+
+/* Default calls for cpufreq accounting */
+static struct cpuacct_charge_calls *cpuacct_cpufreq;
+int cpuacct_register_cpufreq(struct cpuacct_charge_calls *fn)
+{
+       cpuacct_cpufreq = fn;
+
+       /*
+        * Root node is created before platform can register callbacks,
+        * initalize here.
+        */
+       if (cpuacct_root && fn) {
+               cpuacct_root->cpufreq_fn = fn;
+               if (fn->init)
+                       fn->init(&cpuacct_root->cpuacct_data);
+       }
+       return 0;
+}
+
 struct cgroup_subsys cpuacct_subsys;
 
 /* return cpu accounting group corresponding to this container */
@@ -9128,8 +9177,16 @@ static struct cgroup_subsys_state *cpuacct_create(
                if (percpu_counter_init(&ca->cpustat[i], 0))
                        goto out_free_counters;
 
+       ca->cpufreq_fn = cpuacct_cpufreq;
+
+       /* If available, have platform code initalize cpu frequency table */
+       if (ca->cpufreq_fn && ca->cpufreq_fn->init)
+               ca->cpufreq_fn->init(&ca->cpuacct_data);
+
        if (cgrp->parent)
                ca->parent = cgroup_ca(cgrp->parent);
+       else
+               cpuacct_root = ca;
 
        return &ca->css;
 
@@ -9257,6 +9314,32 @@ static int cpuacct_stats_show(struct cgroup *cgrp, struct cftype *cft,
        return 0;
 }
 
+static int cpuacct_cpufreq_show(struct cgroup *cgrp, struct cftype *cft,
+               struct cgroup_map_cb *cb)
+{
+       struct cpuacct *ca = cgroup_ca(cgrp);
+       if (ca->cpufreq_fn && ca->cpufreq_fn->cpufreq_show)
+               ca->cpufreq_fn->cpufreq_show(ca->cpuacct_data, cb);
+
+       return 0;
+}
+
+/* return total cpu power usage (milliWatt second) of a group */
+static u64 cpuacct_powerusage_read(struct cgroup *cgrp, struct cftype *cft)
+{
+       int i;
+       struct cpuacct *ca = cgroup_ca(cgrp);
+       u64 totalpower = 0;
+
+       if (ca->cpufreq_fn && ca->cpufreq_fn->power_usage)
+               for_each_present_cpu(i) {
+                       totalpower += ca->cpufreq_fn->power_usage(
+                                       ca->cpuacct_data);
+               }
+
+       return totalpower;
+}
+
 static struct cftype files[] = {
        {
                .name = "usage",
@@ -9271,6 +9354,14 @@ static struct cftype files[] = {
                .name = "stat",
                .read_map = cpuacct_stats_show,
        },
+       {
+               .name =  "cpufreq",
+               .read_map = cpuacct_cpufreq_show,
+       },
+       {
+               .name = "power",
+               .read_u64 = cpuacct_powerusage_read
+       },
 };
 
 static int cpuacct_populate(struct cgroup_subsys *ss, struct cgroup *cgrp)
@@ -9300,6 +9391,10 @@ static void cpuacct_charge(struct task_struct *tsk, u64 cputime)
        for (; ca; ca = ca->parent) {
                u64 *cpuusage = per_cpu_ptr(ca->cpuusage, cpu);
                *cpuusage += cputime;
+
+               /* Call back into platform code to account for CPU speeds */
+               if (ca->cpufreq_fn && ca->cpufreq_fn->charge)
+                       ca->cpufreq_fn->charge(ca->cpuacct_data, cputime, cpu);
        }
 
        rcu_read_unlock();