OSDN Git Service

Merge 4.4.166 into android-4.4-p
[sagit-ice-cold/kernel_xiaomi_msm8998.git] / kernel / sched / core.c
index 3030633..328e17d 100644 (file)
@@ -32,7 +32,7 @@
 #include <linux/init.h>
 #include <linux/uaccess.h>
 #include <linux/highmem.h>
-#include <asm/mmu_context.h>
+#include <linux/mmu_context.h>
 #include <linux/interrupt.h>
 #include <linux/capability.h>
 #include <linux/completion.h>
@@ -74,6 +74,7 @@
 #include <linux/binfmts.h>
 #include <linux/context_tracking.h>
 #include <linux/compiler.h>
+#include <linux/cpufreq_times.h>
 
 #include <asm/switch_to.h>
 #include <asm/tlb.h>
@@ -619,9 +620,9 @@ void resched_cpu(int cpu)
        struct rq *rq = cpu_rq(cpu);
        unsigned long flags;
 
-       if (!raw_spin_trylock_irqsave(&rq->lock, flags))
-               return;
-       resched_curr(rq);
+       raw_spin_lock_irqsave(&rq->lock, flags);
+       if (cpu_online(cpu) || cpu == smp_processor_id())
+               resched_curr(rq);
        raw_spin_unlock_irqrestore(&rq->lock, flags);
 }
 
@@ -2159,6 +2160,7 @@ void __dl_clear_params(struct task_struct *p)
        dl_se->dl_period = 0;
        dl_se->flags = 0;
        dl_se->dl_bw = 0;
+       dl_se->dl_density = 0;
 
        dl_se->dl_throttled = 0;
        dl_se->dl_new = 1;
@@ -2783,7 +2785,7 @@ context_switch(struct rq *rq, struct task_struct *prev,
                atomic_inc(&oldmm->mm_count);
                enter_lazy_tlb(oldmm, next);
        } else
-               switch_mm(oldmm, mm, next);
+               switch_mm_irqs_off(oldmm, mm, next);
 
        if (!prev->mm) {
                prev->active_mm = NULL;
@@ -2983,91 +2985,6 @@ unsigned long long task_sched_runtime(struct task_struct *p)
        return ns;
 }
 
-#ifdef CONFIG_CPU_FREQ_GOV_SCHED
-
-static inline
-unsigned long add_capacity_margin(unsigned long cpu_capacity)
-{
-       cpu_capacity  = cpu_capacity * capacity_margin;
-       cpu_capacity /= SCHED_CAPACITY_SCALE;
-       return cpu_capacity;
-}
-
-static inline
-unsigned long sum_capacity_reqs(unsigned long cfs_cap,
-                               struct sched_capacity_reqs *scr)
-{
-       unsigned long total = add_capacity_margin(cfs_cap + scr->rt);
-       return total += scr->dl;
-}
-
-unsigned long boosted_cpu_util(int cpu);
-static void sched_freq_tick_pelt(int cpu)
-{
-       unsigned long cpu_utilization = boosted_cpu_util(cpu);
-       unsigned long capacity_curr = capacity_curr_of(cpu);
-       struct sched_capacity_reqs *scr;
-
-       scr = &per_cpu(cpu_sched_capacity_reqs, cpu);
-       if (sum_capacity_reqs(cpu_utilization, scr) < capacity_curr)
-               return;
-
-       /*
-        * To make free room for a task that is building up its "real"
-        * utilization and to harm its performance the least, request
-        * a jump to a higher OPP as soon as the margin of free capacity
-        * is impacted (specified by capacity_margin).
-        * Remember CPU utilization in sched_capacity_reqs should be normalised.
-        */
-       cpu_utilization = cpu_utilization * SCHED_CAPACITY_SCALE / capacity_orig_of(cpu);
-       set_cfs_cpu_capacity(cpu, true, cpu_utilization);
-}
-
-#ifdef CONFIG_SCHED_WALT
-static void sched_freq_tick_walt(int cpu)
-{
-       unsigned long cpu_utilization = cpu_util_freq(cpu);
-       unsigned long capacity_curr = capacity_curr_of(cpu);
-
-       if (walt_disabled || !sysctl_sched_use_walt_cpu_util)
-               return sched_freq_tick_pelt(cpu);
-
-       /*
-        * Add a margin to the WALT utilization to check if we will need to
-        * increase frequency.
-        * NOTE: WALT tracks a single CPU signal for all the scheduling
-        * classes, thus this margin is going to be added to the DL class as
-        * well, which is something we do not do in sched_freq_tick_pelt case.
-        */
-       if (add_capacity_margin(cpu_utilization) <= capacity_curr)
-               return;
-
-       /*
-        * It is likely that the load is growing so we
-        * keep the added margin in our request as an
-        * extra boost.
-        * Remember CPU utilization in sched_capacity_reqs should be normalised.
-        */
-       cpu_utilization = cpu_utilization * SCHED_CAPACITY_SCALE / capacity_orig_of(cpu);
-       set_cfs_cpu_capacity(cpu, true, cpu_utilization);
-
-}
-#define _sched_freq_tick(cpu) sched_freq_tick_walt(cpu)
-#else
-#define _sched_freq_tick(cpu) sched_freq_tick_pelt(cpu)
-#endif /* CONFIG_SCHED_WALT */
-
-static void sched_freq_tick(int cpu)
-{
-       if (!sched_freq())
-               return;
-
-       _sched_freq_tick(cpu);
-}
-#else
-static inline void sched_freq_tick(int cpu) { }
-#endif /* CONFIG_CPU_FREQ_GOV_SCHED */
-
 /*
  * This function gets called by the timer code, with HZ frequency.
  * We call it with interrupts disabled.
@@ -3088,7 +3005,6 @@ void scheduler_tick(void)
        curr->sched_class->task_tick(rq, curr, 0);
        update_cpu_load_active(rq);
        calc_global_load_tick(rq);
-       sched_freq_tick(cpu);
        raw_spin_unlock(&rq->lock);
 
        perf_event_task_tick();
@@ -3855,6 +3771,7 @@ __setparam_dl(struct task_struct *p, const struct sched_attr *attr)
        dl_se->dl_period = attr->sched_period ?: dl_se->dl_deadline;
        dl_se->flags = attr->sched_flags;
        dl_se->dl_bw = to_ratio(dl_se->dl_period, dl_se->dl_runtime);
+       dl_se->dl_density = to_ratio(dl_se->dl_deadline, dl_se->dl_runtime);
 
        /*
         * Changing the parameters of a task is 'tricky' and we're not doing
@@ -4027,8 +3944,8 @@ static int __sched_setscheduler(struct task_struct *p,
        struct rq *rq;
        int reset_on_fork;
 
-       /* may grab non-irq protected spin_locks */
-       BUG_ON(in_interrupt());
+       /* The pi code expects interrupts enabled */
+       BUG_ON(pi && in_interrupt());
 recheck:
        /* double check policy once rq lock held */
        if (policy < 0) {
@@ -6180,6 +6097,19 @@ static void rq_attach_root(struct rq *rq, struct root_domain *rd)
                call_rcu_sched(&old_rd->rcu, free_rootdomain);
 }
 
+void sched_get_rd(struct root_domain *rd)
+{
+       atomic_inc(&rd->refcount);
+}
+
+void sched_put_rd(struct root_domain *rd)
+{
+       if (!atomic_dec_and_test(&rd->refcount))
+               return;
+
+       call_rcu_sched(&rd->rcu, free_rootdomain);
+}
+
 static int init_rootdomain(struct root_domain *rd)
 {
        memset(rd, 0, sizeof(*rd));
@@ -6193,6 +6123,12 @@ static int init_rootdomain(struct root_domain *rd)
        if (!zalloc_cpumask_var(&rd->rto_mask, GFP_KERNEL))
                goto free_dlo_mask;
 
+#ifdef HAVE_RT_PUSH_IPI
+       rd->rto_cpu = -1;
+       raw_spin_lock_init(&rd->rto_lock);
+       init_irq_work(&rd->rto_push_work, rto_push_irq_work_func);
+#endif
+
        init_dl_bw(&rd->dl_bw);
        if (cpudl_init(&rd->cpudl) != 0)
                goto free_dlo_mask;
@@ -8208,11 +8144,9 @@ void sched_destroy_group(struct task_group *tg)
 void sched_offline_group(struct task_group *tg)
 {
        unsigned long flags;
-       int i;
 
        /* end participation in shares distribution */
-       for_each_possible_cpu(i)
-               unregister_fair_sched_group(tg, i);
+       unregister_fair_sched_group(tg);
 
        spin_lock_irqsave(&task_group_lock, flags);
        list_del_rcu(&tg->list);