Merge branch 'timers-nohz-for-linus' of git://git.kernel.org/pub/scm/linux/kernel...
authorLinus Torvalds <torvalds@linux-foundation.org>
Tue, 1 Sep 2015 04:04:24 +0000 (21:04 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Tue, 1 Sep 2015 04:04:24 +0000 (21:04 -0700)
Pull NOHZ updates from Ingo Molnar:
 "The main changes, mostly written by Frederic Weisbecker, include:

   - Fix some jiffies based cputime assumptions.  (No real harm because
     the concerned code isn't used by full dynticks.)

   - Simplify jiffies <-> usecs conversions.  Remove dead code.

   - Remove early hacks on nohz full code that avoided messing up idle
     nohz internals.  Now nohz integrates well full and idle and such
     hack have become needless.

   - Restart nohz full tick from irq exit.  (A simplification and a
     preparation for future optimization on scheduler kick to nohz
     full)

   - Code cleanups.

   - Tile driver isolation enhancement on top of nohz.  (Chris Metcalf)"

* 'timers-nohz-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  nohz: Remove useless argument on tick_nohz_task_switch()
  nohz: Move tick_nohz_restart_sched_tick() above its users
  nohz: Restart nohz full tick from irq exit
  nohz: Remove idle task special case
  nohz: Prevent tilegx network driver interrupts
  alpha: Fix jiffies based cputime assumption
  apm32: Fix cputime == jiffies assumption
  jiffies: Remove HZ > USEC_PER_SEC special case

1  2 
include/linux/jiffies.h
kernel/sched/core.c

diff --combined include/linux/jiffies.h
index 1ba48a18c1d77e9fbc497a3f01cdd58bc15459f8,7c6febede6ba0d4f06eac31018c3da063c2864ec..9ea50da7351351e6165326687ac959ab09a52cac
@@@ -351,7 -351,7 +351,7 @@@ static inline unsigned long _msecs_to_j
   * directly here and from __msecs_to_jiffies() in the case where
   * constant folding is not possible.
   */
 -static inline unsigned long msecs_to_jiffies(const unsigned int m)
 +static __always_inline unsigned long msecs_to_jiffies(const unsigned int m)
  {
        if (__builtin_constant_p(m)) {
                if ((int)m < 0)
  }
  
  extern unsigned long __usecs_to_jiffies(const unsigned int u);
- #if HZ <= USEC_PER_SEC && !(USEC_PER_SEC % HZ)
+ #if !(USEC_PER_SEC % HZ)
  static inline unsigned long _usecs_to_jiffies(const unsigned int u)
  {
        return (u + (USEC_PER_SEC / HZ) - 1) / (USEC_PER_SEC / HZ);
  }
- #elif HZ > USEC_PER_SEC && !(HZ % USEC_PER_SEC)
- static inline unsigned long _usecs_to_jiffies(const unsigned int u)
- {
-       return u * (HZ / USEC_PER_SEC);
- }
- static inline unsigned long _usecs_to_jiffies(const unsigned int u)
- {
  #else
  static inline unsigned long _usecs_to_jiffies(const unsigned int u)
  {
   * directly here and from __msecs_to_jiffies() in the case where
   * constant folding is not possible.
   */
 -static inline unsigned long usecs_to_jiffies(const unsigned int u)
 +static __always_inline unsigned long usecs_to_jiffies(const unsigned int u)
  {
        if (__builtin_constant_p(u)) {
                if (u > jiffies_to_usecs(MAX_JIFFY_OFFSET))
diff --combined kernel/sched/core.c
index 7819725e9da88f203eeb81446c6892543b40b696,4d34035bb3ee101abc7eddbce32f94610261cc14..8b864ecee0e187c58a7903058ae1c0fa57b4d0c3
@@@ -1151,45 -1151,15 +1151,45 @@@ static int migration_cpu_stop(void *dat
        return 0;
  }
  
 -void do_set_cpus_allowed(struct task_struct *p, const struct cpumask *new_mask)
 +/*
 + * sched_class::set_cpus_allowed must do the below, but is not required to
 + * actually call this function.
 + */
 +void set_cpus_allowed_common(struct task_struct *p, const struct cpumask *new_mask)
  {
 -      if (p->sched_class->set_cpus_allowed)
 -              p->sched_class->set_cpus_allowed(p, new_mask);
 -
        cpumask_copy(&p->cpus_allowed, new_mask);
        p->nr_cpus_allowed = cpumask_weight(new_mask);
  }
  
 +void do_set_cpus_allowed(struct task_struct *p, const struct cpumask *new_mask)
 +{
 +      struct rq *rq = task_rq(p);
 +      bool queued, running;
 +
 +      lockdep_assert_held(&p->pi_lock);
 +
 +      queued = task_on_rq_queued(p);
 +      running = task_current(rq, p);
 +
 +      if (queued) {
 +              /*
 +               * Because __kthread_bind() calls this on blocked tasks without
 +               * holding rq->lock.
 +               */
 +              lockdep_assert_held(&rq->lock);
 +              dequeue_task(rq, p, 0);
 +      }
 +      if (running)
 +              put_prev_task(rq, p);
 +
 +      p->sched_class->set_cpus_allowed(p, new_mask);
 +
 +      if (running)
 +              p->sched_class->set_curr_task(rq);
 +      if (queued)
 +              enqueue_task(rq, p, 0);
 +}
 +
  /*
   * Change a given task's CPU affinity. Migrate the thread to a
   * proper CPU and schedule it away if the CPU it's executing on
   * task must not exit() & deallocate itself prematurely. The
   * call is not atomic; no spinlocks may be held.
   */
 -int set_cpus_allowed_ptr(struct task_struct *p, const struct cpumask *new_mask)
 +static int __set_cpus_allowed_ptr(struct task_struct *p,
 +                                const struct cpumask *new_mask, bool check)
  {
        unsigned long flags;
        struct rq *rq;
  
        rq = task_rq_lock(p, &flags);
  
 +      /*
 +       * Must re-check here, to close a race against __kthread_bind(),
 +       * sched_setaffinity() is not guaranteed to observe the flag.
 +       */
 +      if (check && (p->flags & PF_NO_SETAFFINITY)) {
 +              ret = -EINVAL;
 +              goto out;
 +      }
 +
        if (cpumask_equal(&p->cpus_allowed, new_mask))
                goto out;
  
  
        return ret;
  }
 +
 +int set_cpus_allowed_ptr(struct task_struct *p, const struct cpumask *new_mask)
 +{
 +      return __set_cpus_allowed_ptr(p, new_mask, false);
 +}
  EXPORT_SYMBOL_GPL(set_cpus_allowed_ptr);
  
  void set_task_cpu(struct task_struct *p, unsigned int new_cpu)
@@@ -1640,15 -1595,6 +1640,15 @@@ static void update_avg(u64 *avg, u64 sa
        s64 diff = sample - *avg;
        *avg += diff >> 3;
  }
 +
 +#else
 +
 +static inline int __set_cpus_allowed_ptr(struct task_struct *p,
 +                                       const struct cpumask *new_mask, bool check)
 +{
 +      return set_cpus_allowed_ptr(p, new_mask);
 +}
 +
  #endif /* CONFIG_SMP */
  
  static void
@@@ -1708,9 -1654,9 +1708,9 @@@ static voi
  ttwu_do_wakeup(struct rq *rq, struct task_struct *p, int wake_flags)
  {
        check_preempt_curr(rq, p, wake_flags);
 -      trace_sched_wakeup(p, true);
 -
        p->state = TASK_RUNNING;
 +      trace_sched_wakeup(p);
 +
  #ifdef CONFIG_SMP
        if (p->sched_class->task_woken) {
                /*
@@@ -1928,8 -1874,6 +1928,8 @@@ try_to_wake_up(struct task_struct *p, u
        if (!(p->state & state))
                goto out;
  
 +      trace_sched_waking(p);
 +
        success = 1; /* we're going to change ->state */
        cpu = task_cpu(p);
  
@@@ -2005,8 -1949,6 +2005,8 @@@ static void try_to_wake_up_local(struc
        if (!(p->state & TASK_NORMAL))
                goto out;
  
 +      trace_sched_waking(p);
 +
        if (!task_on_rq_queued(p))
                ttwu_activate(rq, p, ENQUEUE_WAKEUP);
  
@@@ -2074,6 -2016,9 +2074,6 @@@ static void __sched_fork(unsigned long 
        p->se.prev_sum_exec_runtime     = 0;
        p->se.nr_migrations             = 0;
        p->se.vruntime                  = 0;
 -#ifdef CONFIG_SMP
 -      p->se.avg.decay_count           = 0;
 -#endif
        INIT_LIST_HEAD(&p->se.group_node);
  
  #ifdef CONFIG_SCHEDSTATS
@@@ -2255,8 -2200,8 +2255,8 @@@ unsigned long to_ratio(u64 period, u64 
  #ifdef CONFIG_SMP
  inline struct dl_bw *dl_bw_of(int i)
  {
 -      rcu_lockdep_assert(rcu_read_lock_sched_held(),
 -                         "sched RCU must be held");
 +      RCU_LOCKDEP_WARN(!rcu_read_lock_sched_held(),
 +                       "sched RCU must be held");
        return &cpu_rq(i)->rd->dl_bw;
  }
  
@@@ -2265,8 -2210,8 +2265,8 @@@ static inline int dl_bw_cpus(int i
        struct root_domain *rd = cpu_rq(i)->rd;
        int cpus = 0;
  
 -      rcu_lockdep_assert(rcu_read_lock_sched_held(),
 -                         "sched RCU must be held");
 +      RCU_LOCKDEP_WARN(!rcu_read_lock_sched_held(),
 +                       "sched RCU must be held");
        for_each_cpu_and(i, rd->span, cpu_active_mask)
                cpus++;
  
@@@ -2358,11 -2303,11 +2358,11 @@@ void wake_up_new_task(struct task_struc
  #endif
  
        /* Initialize new task's runnable average */
 -      init_task_runnable_average(p);
 +      init_entity_runnable_average(&p->se);
        rq = __task_rq_lock(p);
        activate_task(rq, p, 0);
        p->on_rq = TASK_ON_RQ_QUEUED;
 -      trace_sched_wakeup_new(p, true);
 +      trace_sched_wakeup_new(p);
        check_preempt_curr(rq, p, WF_FORK);
  #ifdef CONFIG_SMP
        if (p->sched_class->task_woken)
@@@ -2524,6 -2469,7 +2524,6 @@@ static struct rq *finish_task_switch(st
         */
        prev_state = prev->state;
        vtime_task_switch(prev);
 -      finish_arch_switch(prev);
        perf_event_task_sched_in(prev, current);
        finish_lock_switch(rq, prev);
        finish_arch_post_lock_switch();
                put_task_struct(prev);
        }
  
-       tick_nohz_task_switch(current);
+       tick_nohz_task_switch();
        return rq;
  }
  
@@@ -4394,7 -4340,7 +4394,7 @@@ long sched_setaffinity(pid_t pid, cons
        }
  #endif
  again:
 -      retval = set_cpus_allowed_ptr(p, new_mask);
 +      retval = __set_cpus_allowed_ptr(p, new_mask, true);
  
        if (!retval) {
                cpuset_cpus_allowed(p, cpus_allowed);
@@@ -4546,7 -4492,7 +4546,7 @@@ SYSCALL_DEFINE0(sched_yield
  
  int __sched _cond_resched(void)
  {
 -      if (should_resched()) {
 +      if (should_resched(0)) {
                preempt_schedule_common();
                return 1;
        }
@@@ -4564,7 -4510,7 +4564,7 @@@ EXPORT_SYMBOL(_cond_resched)
   */
  int __cond_resched_lock(spinlock_t *lock)
  {
 -      int resched = should_resched();
 +      int resched = should_resched(PREEMPT_LOCK_OFFSET);
        int ret = 0;
  
        lockdep_assert_held(lock);
@@@ -4586,7 -4532,7 +4586,7 @@@ int __sched __cond_resched_softirq(void
  {
        BUG_ON(!in_softirq());
  
 -      if (should_resched()) {
 +      if (should_resched(SOFTIRQ_DISABLE_OFFSET)) {
                local_bh_enable();
                preempt_schedule_common();
                local_bh_disable();
@@@ -4919,8 -4865,7 +4919,8 @@@ void init_idle(struct task_struct *idle
        struct rq *rq = cpu_rq(cpu);
        unsigned long flags;
  
 -      raw_spin_lock_irqsave(&rq->lock, flags);
 +      raw_spin_lock_irqsave(&idle->pi_lock, flags);
 +      raw_spin_lock(&rq->lock);
  
        __sched_fork(0, idle);
        idle->state = TASK_RUNNING;
  #if defined(CONFIG_SMP)
        idle->on_cpu = 1;
  #endif
 -      raw_spin_unlock_irqrestore(&rq->lock, flags);
 +      raw_spin_unlock(&rq->lock);
 +      raw_spin_unlock_irqrestore(&idle->pi_lock, flags);
  
        /* Set the preempt count _outside_ the spinlocks! */
        init_idle_preempt_count(idle, cpu);
@@@ -5367,7 -5311,8 +5367,7 @@@ static void register_sched_domain_sysct
  /* may be called multiple times per register */
  static void unregister_sched_domain_sysctl(void)
  {
 -      if (sd_sysctl_header)
 -              unregister_sysctl_table(sd_sysctl_header);
 +      unregister_sysctl_table(sd_sysctl_header);
        sd_sysctl_header = NULL;
        if (sd_ctl_dir[0].child)
                sd_free_ctl_entry(&sd_ctl_dir[0].child);
@@@ -5488,14 -5433,6 +5488,14 @@@ static int sched_cpu_active(struct noti
        case CPU_STARTING:
                set_cpu_rq_start_time();
                return NOTIFY_OK;
 +      case CPU_ONLINE:
 +              /*
 +               * At this point a starting CPU has marked itself as online via
 +               * set_cpu_online(). But it might not yet have marked itself
 +               * as active, which is essential from here on.
 +               *
 +               * Thus, fall-through and help the starting CPU along.
 +               */
        case CPU_DOWN_FAILED:
                set_cpu_active((long)hcpu, true);
                return NOTIFY_OK;
@@@ -6508,10 -6445,8 +6508,10 @@@ static void init_numa_topology_type(voi
  
        n = sched_max_numa_distance;
  
 -      if (n <= 1)
 +      if (sched_domains_numa_levels <= 1) {
                sched_numa_topology_type = NUMA_DIRECT;
 +              return;
 +      }
  
        for_each_online_node(a) {
                for_each_online_node(b) {