Merge branch 'sched/urgent' into sched/core, to pick up fixes before applying new...
authorIngo Molnar <mingo@kernel.org>
Mon, 23 Mar 2015 09:50:29 +0000 (10:50 +0100)
committerIngo Molnar <mingo@kernel.org>
Mon, 23 Mar 2015 09:50:29 +0000 (10:50 +0100)
Signed-off-by: Ingo Molnar <mingo@kernel.org>
1  2 
arch/x86/kernel/process.c
kernel/sched/core.c

  #include <asm/syscalls.h>
  #include <asm/idle.h>
  #include <asm/uaccess.h>
 +#include <asm/mwait.h>
  #include <asm/i387.h>
  #include <asm/fpu-internal.h>
  #include <asm/debugreg.h>
  #include <asm/nmi.h>
+ #include <asm/tlbflush.h>
  
  /*
   * per-CPU TSS segments. Threads are completely 'soft' on Linux,
@@@ -142,7 -142,7 +143,7 @@@ void flush_thread(void
  
  static void hard_disable_TSC(void)
  {
-       write_cr4(read_cr4() | X86_CR4_TSD);
+       cr4_set_bits(X86_CR4_TSD);
  }
  
  void disable_TSC(void)
  
  static void hard_enable_TSC(void)
  {
-       write_cr4(read_cr4() & ~X86_CR4_TSD);
+       cr4_clear_bits(X86_CR4_TSD);
  }
  
  static void enable_TSC(void)
@@@ -399,53 -399,6 +400,53 @@@ static void amd_e400_idle(void
                default_idle();
  }
  
 +/*
 + * Intel Core2 and older machines prefer MWAIT over HALT for C1.
 + * We can't rely on cpuidle installing MWAIT, because it will not load
 + * on systems that support only C1 -- so the boot default must be MWAIT.
 + *
 + * Some AMD machines are the opposite, they depend on using HALT.
 + *
 + * So for default C1, which is used during boot until cpuidle loads,
 + * use MWAIT-C1 on Intel HW that has it, else use HALT.
 + */
 +static int prefer_mwait_c1_over_halt(const struct cpuinfo_x86 *c)
 +{
 +      if (c->x86_vendor != X86_VENDOR_INTEL)
 +              return 0;
 +
 +      if (!cpu_has(c, X86_FEATURE_MWAIT))
 +              return 0;
 +
 +      return 1;
 +}
 +
 +/*
 + * MONITOR/MWAIT with no hints, used for default default C1 state.
 + * This invokes MWAIT with interrutps enabled and no flags,
 + * which is backwards compatible with the original MWAIT implementation.
 + */
 +
 +static void mwait_idle(void)
 +{
 +      if (!current_set_polling_and_test()) {
 +              if (this_cpu_has(X86_BUG_CLFLUSH_MONITOR)) {
 +                      smp_mb(); /* quirk */
 +                      clflush((void *)&current_thread_info()->flags);
 +                      smp_mb(); /* quirk */
 +              }
 +
 +              __monitor((void *)&current_thread_info()->flags, 0, 0);
 +              if (!need_resched())
 +                      __sti_mwait(0, 0);
 +              else
 +                      local_irq_enable();
 +      } else {
 +              local_irq_enable();
 +      }
 +      __current_clr_polling();
 +}
 +
  void select_idle_routine(const struct cpuinfo_x86 *c)
  {
  #ifdef CONFIG_SMP
                /* E400: APIC timer interrupt does not wake up CPU from C1e */
                pr_info("using AMD E400 aware idle routine\n");
                x86_idle = amd_e400_idle;
 +      } else if (prefer_mwait_c1_over_halt(c)) {
 +              pr_info("using mwait in idle threads\n");
 +              x86_idle = mwait_idle;
        } else
                x86_idle = default_idle;
  }
diff --combined kernel/sched/core.c
@@@ -689,23 -689,6 +689,23 @@@ static inline bool got_nohz_idle_kick(v
  #ifdef CONFIG_NO_HZ_FULL
  bool sched_can_stop_tick(void)
  {
 +      /*
 +       * FIFO realtime policy runs the highest priority task. Other runnable
 +       * tasks are of a lower priority. The scheduler tick does nothing.
 +       */
 +      if (current->policy == SCHED_FIFO)
 +              return true;
 +
 +      /*
 +       * Round-robin realtime tasks time slice with other tasks at the same
 +       * realtime priority. Is this task the only one at this priority?
 +       */
 +      if (current->policy == SCHED_RR) {
 +              struct sched_rt_entity *rt_se = &current->rt;
 +
 +              return rt_se->run_list.prev == rt_se->run_list.next;
 +      }
 +
        /*
         * More than one running task need preemption.
         * nr_running update is assumed to be visible
@@@ -3051,6 -3034,8 +3051,8 @@@ void rt_mutex_setprio(struct task_struc
        } else {
                if (dl_prio(oldprio))
                        p->dl.dl_boosted = 0;
+               if (rt_prio(oldprio))
+                       p->rt.timeout = 0;
                p->sched_class = &fair_sched_class;
        }
  
@@@ -5412,9 -5397,7 +5414,7 @@@ static int sched_domain_debug_one(struc
                                  struct cpumask *groupmask)
  {
        struct sched_group *group = sd->groups;
-       char str[256];
  
-       cpulist_scnprintf(str, sizeof(str), sched_domain_span(sd));
        cpumask_clear(groupmask);
  
        printk(KERN_DEBUG "%*s domain %d: ", level, "", level);
                return -1;
        }
  
-       printk(KERN_CONT "span %s level %s\n", str, sd->name);
+       printk(KERN_CONT "span %*pbl level %s\n",
+              cpumask_pr_args(sched_domain_span(sd)), sd->name);
  
        if (!cpumask_test_cpu(cpu, sched_domain_span(sd))) {
                printk(KERN_ERR "ERROR: domain->span does not contain "
  
                cpumask_or(groupmask, groupmask, sched_group_cpus(group));
  
-               cpulist_scnprintf(str, sizeof(str), sched_group_cpus(group));
-               printk(KERN_CONT " %s", str);
+               printk(KERN_CONT " %*pbl",
+                      cpumask_pr_args(sched_group_cpus(group)));
                if (group->sgc->capacity != SCHED_CAPACITY_SCALE) {
                        printk(KERN_CONT " (cpu_capacity = %d)",
                                group->sgc->capacity);