]> Git Repo - linux.git/commitdiff
Merge branch 'sched-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel...
authorLinus Torvalds <[email protected]>
Wed, 13 Sep 2017 19:22:32 +0000 (12:22 -0700)
committerLinus Torvalds <[email protected]>
Wed, 13 Sep 2017 19:22:32 +0000 (12:22 -0700)
Pull scheduler fixes from Ingo Molnar:
 "Three CPU hotplug related fixes and a debugging improvement"

* 'sched-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  sched/debug: Add debugfs knob for "sched_debug"
  sched/core: WARN() when migrating to an offline CPU
  sched/fair: Plug hole between hotplug and active_load_balance()
  sched/fair: Avoid newidle balance for !active CPUs

1  2 
kernel/sched/debug.c
kernel/sched/fair.c
kernel/sched/sched.h
kernel/sched/topology.c

diff --combined kernel/sched/debug.c
index 8e536d963652c230e8f08f906d723826b068faaa,b19d06ea6e10aed8f221d2ed79332e8fa63c9a88..01217fb5a5de9bd007506020cffb5052ab3abba8
@@@ -181,11 -181,16 +181,16 @@@ static const struct file_operations sch
        .release        = single_release,
  };
  
+ __read_mostly bool sched_debug_enabled;
  static __init int sched_init_debug(void)
  {
        debugfs_create_file("sched_features", 0644, NULL, NULL,
                        &sched_feat_fops);
  
+       debugfs_create_bool("sched_debug", 0644, NULL,
+                       &sched_debug_enabled);
        return 0;
  }
  late_initcall(sched_init_debug);
@@@ -530,7 -535,7 +535,7 @@@ void print_cfs_rq(struct seq_file *m, i
                        SPLIT_NS(cfs_rq->exec_clock));
  
        raw_spin_lock_irqsave(&rq->lock, flags);
 -      if (cfs_rq->rb_leftmost)
 +      if (rb_first_cached(&cfs_rq->tasks_timeline))
                MIN_vruntime = (__pick_first_entity(cfs_rq))->vruntime;
        last = __pick_last_entity(cfs_rq);
        if (last)
diff --combined kernel/sched/fair.c
index 0a85641e62ce915ff2650c0aee3cdf14a1cc6bd7,efeebed935ae58588e84b70d40ece50c9ec1b010..70ba32e08a231858326211b7f64a3ae6a3f4dbd3
@@@ -513,7 -513,6 +513,7 @@@ static inline int entity_before(struct 
  static void update_min_vruntime(struct cfs_rq *cfs_rq)
  {
        struct sched_entity *curr = cfs_rq->curr;
 +      struct rb_node *leftmost = rb_first_cached(&cfs_rq->tasks_timeline);
  
        u64 vruntime = cfs_rq->min_vruntime;
  
                        curr = NULL;
        }
  
 -      if (cfs_rq->rb_leftmost) {
 -              struct sched_entity *se = rb_entry(cfs_rq->rb_leftmost,
 -                                                 struct sched_entity,
 -                                                 run_node);
 +      if (leftmost) { /* non-empty tree */
 +              struct sched_entity *se;
 +              se = rb_entry(leftmost, struct sched_entity, run_node);
  
                if (!curr)
                        vruntime = se->vruntime;
   */
  static void __enqueue_entity(struct cfs_rq *cfs_rq, struct sched_entity *se)
  {
 -      struct rb_node **link = &cfs_rq->tasks_timeline.rb_node;
 +      struct rb_node **link = &cfs_rq->tasks_timeline.rb_root.rb_node;
        struct rb_node *parent = NULL;
        struct sched_entity *entry;
 -      int leftmost = 1;
 +      bool leftmost = true;
  
        /*
         * Find the right place in the rbtree:
                        link = &parent->rb_left;
                } else {
                        link = &parent->rb_right;
 -                      leftmost = 0;
 +                      leftmost = false;
                }
        }
  
 -      /*
 -       * Maintain a cache of leftmost tree entries (it is frequently
 -       * used):
 -       */
 -      if (leftmost)
 -              cfs_rq->rb_leftmost = &se->run_node;
 -
        rb_link_node(&se->run_node, parent, link);
 -      rb_insert_color(&se->run_node, &cfs_rq->tasks_timeline);
 +      rb_insert_color_cached(&se->run_node,
 +                             &cfs_rq->tasks_timeline, leftmost);
  }
  
  static void __dequeue_entity(struct cfs_rq *cfs_rq, struct sched_entity *se)
  {
 -      if (cfs_rq->rb_leftmost == &se->run_node) {
 -              struct rb_node *next_node;
 -
 -              next_node = rb_next(&se->run_node);
 -              cfs_rq->rb_leftmost = next_node;
 -      }
 -
 -      rb_erase(&se->run_node, &cfs_rq->tasks_timeline);
 +      rb_erase_cached(&se->run_node, &cfs_rq->tasks_timeline);
  }
  
  struct sched_entity *__pick_first_entity(struct cfs_rq *cfs_rq)
  {
 -      struct rb_node *left = cfs_rq->rb_leftmost;
 +      struct rb_node *left = rb_first_cached(&cfs_rq->tasks_timeline);
  
        if (!left)
                return NULL;
@@@ -603,7 -616,7 +603,7 @@@ static struct sched_entity *__pick_next
  #ifdef CONFIG_SCHED_DEBUG
  struct sched_entity *__pick_last_entity(struct cfs_rq *cfs_rq)
  {
 -      struct rb_node *last = rb_last(&cfs_rq->tasks_timeline);
 +      struct rb_node *last = rb_last(&cfs_rq->tasks_timeline.rb_root);
  
        if (!last)
                return NULL;
@@@ -2790,9 -2803,7 +2790,9 @@@ static inline void update_cfs_shares(st
  
  static inline void cfs_rq_util_change(struct cfs_rq *cfs_rq)
  {
 -      if (&this_rq()->cfs == cfs_rq) {
 +      struct rq *rq = rq_of(cfs_rq);
 +
 +      if (&rq->cfs == cfs_rq) {
                /*
                 * There are a few boundary cases this might miss but it should
                 * get called often enough that that should (hopefully) not be
                 *
                 * See cpu_util().
                 */
 -              cpufreq_update_util(rq_of(cfs_rq), 0);
 +              cpufreq_update_util(rq, 0);
        }
  }
  
@@@ -4886,7 -4897,7 +4886,7 @@@ enqueue_task_fair(struct rq *rq, struc
         * passed.
         */
        if (p->in_iowait)
 -              cpufreq_update_this_cpu(rq, SCHED_CPUFREQ_IOWAIT);
 +              cpufreq_update_util(rq, SCHED_CPUFREQ_IOWAIT);
  
        for_each_sched_entity(se) {
                if (se->on_rq)
@@@ -8436,6 -8447,12 +8436,12 @@@ static int idle_balance(struct rq *this
         */
        this_rq->idle_stamp = rq_clock(this_rq);
  
+       /*
+        * Do not pull tasks towards !active CPUs...
+        */
+       if (!cpu_active(this_cpu))
+               return 0;
        /*
         * This is OK, because current is on_cpu, which avoids it being picked
         * for load-balance and preemption/IRQs are still disabled avoiding
@@@ -8543,6 -8560,13 +8549,13 @@@ static int active_load_balance_cpu_stop
        struct rq_flags rf;
  
        rq_lock_irq(busiest_rq, &rf);
+       /*
+        * Between queueing the stop-work and running it is a hole in which
+        * CPUs can become inactive. We should not move tasks from or to
+        * inactive CPUs.
+        */
+       if (!cpu_active(busiest_cpu) || !cpu_active(target_cpu))
+               goto out_unlock;
  
        /* make sure the requested cpu hasn't gone down in the meantime */
        if (unlikely(busiest_cpu != smp_processor_id() ||
@@@ -9299,7 -9323,7 +9312,7 @@@ static void set_curr_task_fair(struct r
  
  void init_cfs_rq(struct cfs_rq *cfs_rq)
  {
 -      cfs_rq->tasks_timeline = RB_ROOT;
 +      cfs_rq->tasks_timeline = RB_ROOT_CACHED;
        cfs_rq->min_vruntime = (u64)(-(1LL << 20));
  #ifndef CONFIG_64BIT
        cfs_rq->min_vruntime_copy = cfs_rq->min_vruntime;
diff --combined kernel/sched/sched.h
index 746ac78ff4927d03081688d3f140d6de5d0e7d02,7ea2a0339771ed1f0adda9c007d9b06f4b2c6857..14db76cd496ffb68641c3cc68a9be72205524e1b
@@@ -426,7 -426,8 +426,7 @@@ struct cfs_rq 
        u64 min_vruntime_copy;
  #endif
  
 -      struct rb_root tasks_timeline;
 -      struct rb_node *rb_leftmost;
 +      struct rb_root_cached tasks_timeline;
  
        /*
         * 'curr' points to currently running entity on this cfs_rq.
@@@ -549,7 -550,8 +549,7 @@@ struct rt_rq 
  /* Deadline class' related fields in a runqueue */
  struct dl_rq {
        /* runqueue is an rbtree, ordered by deadline */
 -      struct rb_root rb_root;
 -      struct rb_node *rb_leftmost;
 +      struct rb_root_cached root;
  
        unsigned long dl_nr_running;
  
         * an rb-tree, ordered by tasks' deadlines, with caching
         * of the leftmost (earliest deadline) element.
         */
 -      struct rb_root pushable_dl_tasks_root;
 -      struct rb_node *pushable_dl_tasks_leftmost;
 +      struct rb_root_cached pushable_dl_tasks_root;
  #else
        struct dl_bw dl_bw;
  #endif
@@@ -1951,6 -1954,8 +1951,8 @@@ extern struct sched_entity *__pick_firs
  extern struct sched_entity *__pick_last_entity(struct cfs_rq *cfs_rq);
  
  #ifdef        CONFIG_SCHED_DEBUG
+ extern bool sched_debug_enabled;
  extern void print_cfs_stats(struct seq_file *m, int cpu);
  extern void print_rt_stats(struct seq_file *m, int cpu);
  extern void print_dl_stats(struct seq_file *m, int cpu);
@@@ -2071,13 -2076,19 +2073,13 @@@ static inline void cpufreq_update_util(
  {
        struct update_util_data *data;
  
 -      data = rcu_dereference_sched(*this_cpu_ptr(&cpufreq_update_util_data));
 +      data = rcu_dereference_sched(*per_cpu_ptr(&cpufreq_update_util_data,
 +                                                cpu_of(rq)));
        if (data)
                data->func(data, rq_clock(rq), flags);
  }
 -
 -static inline void cpufreq_update_this_cpu(struct rq *rq, unsigned int flags)
 -{
 -      if (cpu_of(rq) == smp_processor_id())
 -              cpufreq_update_util(rq, flags);
 -}
  #else
  static inline void cpufreq_update_util(struct rq *rq, unsigned int flags) {}
 -static inline void cpufreq_update_this_cpu(struct rq *rq, unsigned int flags) {}
  #endif /* CONFIG_CPU_FREQ */
  
  #ifdef arch_scale_freq_capacity
diff --combined kernel/sched/topology.c
index 5d0062cc10cb8f99fffa3b8c1cc548f4329c46ed,2ab2aa68c796c8a0fb252d299ac7251163572256..f1cf4f306a8285b642c02ebd28e4d0c78e21e9a5
@@@ -14,11 -14,9 +14,9 @@@ cpumask_var_t sched_domains_tmpmask2
  
  #ifdef CONFIG_SCHED_DEBUG
  
- static __read_mostly int sched_debug_enabled;
  static int __init sched_debug_setup(char *str)
  {
-       sched_debug_enabled = 1;
+       sched_debug_enabled = true;
  
        return 0;
  }
@@@ -473,7 -471,7 +471,7 @@@ static int __init isolated_cpu_setup(ch
        alloc_bootmem_cpumask_var(&cpu_isolated_map);
        ret = cpulist_parse(str, cpu_isolated_map);
        if (ret) {
 -              pr_err("sched: Error, all isolcpus= values must be between 0 and %d\n", nr_cpu_ids);
 +              pr_err("sched: Error, all isolcpus= values must be between 0 and %u\n", nr_cpu_ids);
                return 0;
        }
        return 1;
This page took 0.090859 seconds and 4 git commands to generate.