Merge branch 'sched-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel...
authorLinus Torvalds <torvalds@linux-foundation.org>
Tue, 30 Jan 2018 19:55:56 +0000 (11:55 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Tue, 30 Jan 2018 19:55:56 +0000 (11:55 -0800)
Pull scheduler updates from Ingo Molnar:
 "The main changes in this cycle were:

   - Implement frequency/CPU invariance and OPP selection for
     SCHED_DEADLINE (Juri Lelli)

   - Tweak the task migration logic for better multi-tasking
     workload scalability (Mel Gorman)

   - Misc cleanups, fixes and improvements"

* 'sched-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  sched/deadline: Make bandwidth enforcement scale-invariant
  sched/cpufreq: Move arch_scale_{freq,cpu}_capacity() outside of #ifdef CONFIG_SMP
  sched/cpufreq: Remove arch_scale_freq_capacity()'s 'sd' parameter
  sched/cpufreq: Always consider all CPUs when deciding next freq
  sched/cpufreq: Split utilization signals
  sched/cpufreq: Change the worker kthread to SCHED_DEADLINE
  sched/deadline: Move CPU frequency selection triggering points
  sched/cpufreq: Use the DEADLINE utilization signal
  sched/deadline: Implement "runtime overrun signal" support
  sched/fair: Only immediately migrate tasks due to interrupts if prev and target CPUs share cache
  sched/fair: Correct obsolete comment about cpufreq_update_util()
  sched/fair: Remove impossible condition from find_idlest_group_cpu()
  sched/cpufreq: Don't pass flags to sugov_set_iowait_boost()
  sched/cpufreq: Initialize sg_cpu->flags to 0
  sched/fair: Consider RT/IRQ pressure in capacity_spare_wake()
  sched/fair: Use 'unsigned long' for utilization, consistently
  sched/core: Rework and clarify prepare_lock_switch()
  sched/fair: Remove unused 'curr' parameter from wakeup_gran
  sched/headers: Constify object_is_on_stack()

1  2 
include/linux/sched.h
kernel/sched/core.c
kernel/sched/fair.c
kernel/time/posix-cpu-timers.c

diff --combined include/linux/sched.h
index 68a504f6e474fa67198cdddc0b249ee8bc237d78,f7506712825c7632a0282de259cae18e4b2bf0a2..166144c04ef61af4b8ec47033d99b95a678aaeec
@@@ -472,11 -472,15 +472,15 @@@ struct sched_dl_entity 
         * has not been executed yet. This flag is useful to avoid race
         * conditions between the inactive timer handler and the wakeup
         * code.
+        *
+        * @dl_overrun tells if the task asked to be informed about runtime
+        * overruns.
         */
        unsigned int                    dl_throttled      : 1;
        unsigned int                    dl_boosted        : 1;
        unsigned int                    dl_yielded        : 1;
        unsigned int                    dl_non_contending : 1;
+       unsigned int                    dl_overrun        : 1;
  
        /*
         * Bandwidth enforcement timer. Each -deadline task has its
@@@ -1427,6 -1431,7 +1431,7 @@@ extern int idle_cpu(int cpu)
  extern int sched_setscheduler(struct task_struct *, int, const struct sched_param *);
  extern int sched_setscheduler_nocheck(struct task_struct *, int, const struct sched_param *);
  extern int sched_setattr(struct task_struct *, const struct sched_attr *);
+ extern int sched_setattr_nocheck(struct task_struct *, const struct sched_attr *);
  extern struct task_struct *idle_task(int cpu);
  
  /**
@@@ -1446,21 -1451,12 +1451,21 @@@ extern void ia64_set_curr_task(int cpu
  void yield(void);
  
  union thread_union {
 +#ifndef CONFIG_ARCH_TASK_STRUCT_ON_STACK
 +      struct task_struct task;
 +#endif
  #ifndef CONFIG_THREAD_INFO_IN_TASK
        struct thread_info thread_info;
  #endif
        unsigned long stack[THREAD_SIZE/sizeof(long)];
  };
  
 +#ifndef CONFIG_THREAD_INFO_IN_TASK
 +extern struct thread_info init_thread_info;
 +#endif
 +
 +extern unsigned long init_stack[THREAD_SIZE / sizeof(unsigned long)];
 +
  #ifdef CONFIG_THREAD_INFO_IN_TASK
  static inline struct thread_info *task_thread_info(struct task_struct *task)
  {
diff --combined kernel/sched/core.c
index 5a31a85bbd84e9b89298cf908991eeb002656733,402ef4fa0e1ccdfbb682771988f2bf46b33a8907..3da7a2444a911131589ce616147efd517c7bd354
@@@ -508,8 -508,7 +508,8 @@@ void resched_cpu(int cpu
        unsigned long flags;
  
        raw_spin_lock_irqsave(&rq->lock, flags);
 -      resched_curr(rq);
 +      if (cpu_online(cpu) || cpu == smp_processor_id())
 +              resched_curr(rq);
        raw_spin_unlock_irqrestore(&rq->lock, flags);
  }
  
@@@ -2046,7 -2045,7 +2046,7 @@@ try_to_wake_up(struct task_struct *p, u
         * If the owning (remote) CPU is still in the middle of schedule() with
         * this task as prev, wait until its done referencing the task.
         *
-        * Pairs with the smp_store_release() in finish_lock_switch().
+        * Pairs with the smp_store_release() in finish_task().
         *
         * This ensures that tasks getting woken will be fully ordered against
         * their previous state and preserve Program Order.
        p->state = TASK_WAKING;
  
        if (p->in_iowait) {
 -              delayacct_blkio_end();
 +              delayacct_blkio_end(p);
                atomic_dec(&task_rq(p)->nr_iowait);
        }
  
  #else /* CONFIG_SMP */
  
        if (p->in_iowait) {
 -              delayacct_blkio_end();
 +              delayacct_blkio_end(p);
                atomic_dec(&task_rq(p)->nr_iowait);
        }
  
@@@ -2123,7 -2122,7 +2123,7 @@@ static void try_to_wake_up_local(struc
  
        if (!task_on_rq_queued(p)) {
                if (p->in_iowait) {
 -                      delayacct_blkio_end();
 +                      delayacct_blkio_end(p);
                        atomic_dec(&rq->nr_iowait);
                }
                ttwu_activate(rq, p, ENQUEUE_WAKEUP | ENQUEUE_NOCLOCK);
@@@ -2572,6 -2571,50 +2572,50 @@@ fire_sched_out_preempt_notifiers(struc
  
  #endif /* CONFIG_PREEMPT_NOTIFIERS */
  
+ static inline void prepare_task(struct task_struct *next)
+ {
+ #ifdef CONFIG_SMP
+       /*
+        * Claim the task as running, we do this before switching to it
+        * such that any running task will have this set.
+        */
+       next->on_cpu = 1;
+ #endif
+ }
+ static inline void finish_task(struct task_struct *prev)
+ {
+ #ifdef CONFIG_SMP
+       /*
+        * After ->on_cpu is cleared, the task can be moved to a different CPU.
+        * We must ensure this doesn't happen until the switch is completely
+        * finished.
+        *
+        * In particular, the load of prev->state in finish_task_switch() must
+        * happen before this.
+        *
+        * Pairs with the smp_cond_load_acquire() in try_to_wake_up().
+        */
+       smp_store_release(&prev->on_cpu, 0);
+ #endif
+ }
+ static inline void finish_lock_switch(struct rq *rq)
+ {
+ #ifdef CONFIG_DEBUG_SPINLOCK
+       /* this is a valid case when another task releases the spinlock */
+       rq->lock.owner = current;
+ #endif
+       /*
+        * If we are tracking spinlock dependencies then we have to
+        * fix up the runqueue lock - which gets 'carried over' from
+        * prev into current:
+        */
+       spin_acquire(&rq->lock.dep_map, 0, 0, _THIS_IP_);
+       raw_spin_unlock_irq(&rq->lock);
+ }
  /**
   * prepare_task_switch - prepare to switch tasks
   * @rq: the runqueue preparing to switch
@@@ -2592,7 -2635,7 +2636,7 @@@ prepare_task_switch(struct rq *rq, stru
        sched_info_switch(rq, prev, next);
        perf_event_task_sched_out(prev, next);
        fire_sched_out_preempt_notifiers(prev, next);
-       prepare_lock_switch(rq, next);
+       prepare_task(next);
        prepare_arch_switch(next);
  }
  
@@@ -2647,7 -2690,7 +2691,7 @@@ static struct rq *finish_task_switch(st
         * the scheduled task must drop that reference.
         *
         * We must observe prev->state before clearing prev->on_cpu (in
-        * finish_lock_switch), otherwise a concurrent wakeup can get prev
+        * finish_task), otherwise a concurrent wakeup can get prev
         * running on another CPU and we could rave with its RUNNING -> DEAD
         * transition, resulting in a double drop.
         */
         * to use.
         */
        smp_mb__after_unlock_lock();
-       finish_lock_switch(rq, prev);
+       finish_task(prev);
+       finish_lock_switch(rq);
        finish_arch_post_lock_switch();
  
        fire_sched_in_preempt_notifiers(current);
@@@ -4041,8 -4085,7 +4086,7 @@@ recheck
                        return -EINVAL;
        }
  
-       if (attr->sched_flags &
-               ~(SCHED_FLAG_RESET_ON_FORK | SCHED_FLAG_RECLAIM))
+       if (attr->sched_flags & ~(SCHED_FLAG_ALL | SCHED_FLAG_SUGOV))
                return -EINVAL;
  
        /*
        }
  
        if (user) {
+               if (attr->sched_flags & SCHED_FLAG_SUGOV)
+                       return -EINVAL;
                retval = security_task_setscheduler(p);
                if (retval)
                        return retval;
@@@ -4164,7 -4210,8 +4211,8 @@@ change
                }
  #endif
  #ifdef CONFIG_SMP
-               if (dl_bandwidth_enabled() && dl_policy(policy)) {
+               if (dl_bandwidth_enabled() && dl_policy(policy) &&
+                               !(attr->sched_flags & SCHED_FLAG_SUGOV)) {
                        cpumask_t *span = rq->rd->span;
  
                        /*
@@@ -4294,6 -4341,11 +4342,11 @@@ int sched_setattr(struct task_struct *p
  }
  EXPORT_SYMBOL_GPL(sched_setattr);
  
+ int sched_setattr_nocheck(struct task_struct *p, const struct sched_attr *attr)
+ {
+       return __sched_setscheduler(p, attr, false, true);
+ }
  /**
   * sched_setscheduler_nocheck - change the scheduling policy and/or RT priority of a thread from kernelspace.
   * @p: the task in question.
diff --combined kernel/sched/fair.c
index 26a71ebcd3c2ed94941673a07408a8656ea766c3,1070803cb4237d29b76ccd81326b6fd4085170af..7b65359875009cc44b2f900d8f5cba166eb33ac3
@@@ -3020,9 -3020,7 +3020,7 @@@ static inline void cfs_rq_util_change(s
                /*
                 * There are a few boundary cases this might miss but it should
                 * get called often enough that that should (hopefully) not be
-                * a real problem -- added to that it only calls on the local
-                * CPU, so if we enqueue remotely we'll miss an update, but
-                * the next tick/schedule should update.
+                * a real problem.
                 *
                 * It will not get called when we go idle, because the idle
                 * thread is a different class (!fair), nor will the utilization
@@@ -3091,8 -3089,6 +3089,6 @@@ static u32 __accumulate_pelt_segments(u
        return c1 + c2 + c3;
  }
  
- #define cap_scale(v, s) ((v)*(s) >> SCHED_CAPACITY_SHIFT)
  /*
   * Accumulate the three separate parts of the sum; d1 the remainder
   * of the last (incomplete) period, d2 the span of full periods and d3
@@@ -3122,7 -3118,7 +3118,7 @@@ accumulate_sum(u64 delta, int cpu, stru
        u32 contrib = (u32)delta; /* p == 0 -> delta < 1024 */
        u64 periods;
  
-       scale_freq = arch_scale_freq_capacity(NULL, cpu);
+       scale_freq = arch_scale_freq_capacity(cpu);
        scale_cpu = arch_scale_cpu_capacity(NULL, cpu);
  
        delta += sa->period_contrib;
@@@ -4365,12 -4361,12 +4361,12 @@@ static inline bool cfs_bandwidth_used(v
  
  void cfs_bandwidth_usage_inc(void)
  {
 -      static_key_slow_inc(&__cfs_bandwidth_used);
 +      static_key_slow_inc_cpuslocked(&__cfs_bandwidth_used);
  }
  
  void cfs_bandwidth_usage_dec(void)
  {
 -      static_key_slow_dec(&__cfs_bandwidth_used);
 +      static_key_slow_dec_cpuslocked(&__cfs_bandwidth_used);
  }
  #else /* HAVE_JUMP_LABEL */
  static bool cfs_bandwidth_used(void)
@@@ -5689,8 -5685,8 +5685,8 @@@ static int wake_wide(struct task_struc
   * soonest. For the purpose of speed we only consider the waking and previous
   * CPU.
   *
-  * wake_affine_idle() - only considers 'now', it check if the waking CPU is (or
-  *                    will be) idle.
+  * wake_affine_idle() - only considers 'now', it check if the waking CPU is
+  *                    cache-affine and is (or will be) idle.
   *
   * wake_affine_weight() - considers the weight to reflect the average
   *                      scheduling latency of the CPUs. This seems to work
@@@ -5701,7 -5697,13 +5697,13 @@@ static boo
  wake_affine_idle(struct sched_domain *sd, struct task_struct *p,
                 int this_cpu, int prev_cpu, int sync)
  {
-       if (idle_cpu(this_cpu))
+       /*
+        * If this_cpu is idle, it implies the wakeup is from interrupt
+        * context. Only allow the move if cache is shared. Otherwise an
+        * interrupt intensive workload could force all tasks onto one
+        * node depending on the IO topology or IRQ affinity settings.
+        */
+       if (idle_cpu(this_cpu) && cpus_share_cache(this_cpu, prev_cpu))
                return true;
  
        if (sync && cpu_rq(this_cpu)->nr_running == 1)
@@@ -5765,12 -5767,12 +5767,12 @@@ static int wake_affine(struct sched_dom
        return affine;
  }
  
- static inline int task_util(struct task_struct *p);
- static int cpu_util_wake(int cpu, struct task_struct *p);
+ static inline unsigned long task_util(struct task_struct *p);
+ static unsigned long cpu_util_wake(int cpu, struct task_struct *p);
  
  static unsigned long capacity_spare_wake(int cpu, struct task_struct *p)
  {
-       return capacity_orig_of(cpu) - cpu_util_wake(cpu, p);
+       return max_t(long, capacity_of(cpu) - cpu_util_wake(cpu, p), 0);
  }
  
  /*
@@@ -5950,7 -5952,7 +5952,7 @@@ find_idlest_group_cpu(struct sched_grou
                        }
                } else if (shallowest_idle_cpu == -1) {
                        load = weighted_cpuload(cpu_rq(i));
-                       if (load < min_load || (load == min_load && i == this_cpu)) {
+                       if (load < min_load) {
                                min_load = load;
                                least_loaded_cpu = i;
                        }
@@@ -6247,7 -6249,7 +6249,7 @@@ static int select_idle_sibling(struct t
   * capacity_orig) as it useful for predicting the capacity required after task
   * migrations (scheduler-driven DVFS).
   */
- static int cpu_util(int cpu)
+ static unsigned long cpu_util(int cpu)
  {
        unsigned long util = cpu_rq(cpu)->cfs.avg.util_avg;
        unsigned long capacity = capacity_orig_of(cpu);
        return (util >= capacity) ? capacity : util;
  }
  
- static inline int task_util(struct task_struct *p)
+ static inline unsigned long task_util(struct task_struct *p)
  {
        return p->se.avg.util_avg;
  }
   * cpu_util_wake: Compute cpu utilization with any contributions from
   * the waking task p removed.
   */
- static int cpu_util_wake(int cpu, struct task_struct *p)
+ static unsigned long cpu_util_wake(int cpu, struct task_struct *p)
  {
        unsigned long util, capacity;
  
@@@ -6449,8 -6451,7 +6451,7 @@@ static void task_dead_fair(struct task_
  }
  #endif /* CONFIG_SMP */
  
- static unsigned long
- wakeup_gran(struct sched_entity *curr, struct sched_entity *se)
+ static unsigned long wakeup_gran(struct sched_entity *se)
  {
        unsigned long gran = sysctl_sched_wakeup_granularity;
  
@@@ -6492,7 -6493,7 +6493,7 @@@ wakeup_preempt_entity(struct sched_enti
        if (vdiff <= 0)
                return -1;
  
-       gran = wakeup_gran(curr, se);
+       gran = wakeup_gran(se);
        if (vdiff > gran)
                return 1;
  
index ec9f5da6f163d40d3b2df9f4b9f76e783b304543,cf50ea34dbd1874b8c9b41c719839e03980e9e9a..2541bd89f20eb95f96d435d21f4eb7c4d1a0cda6
@@@ -14,6 -14,7 +14,7 @@@
  #include <linux/tick.h>
  #include <linux/workqueue.h>
  #include <linux/compat.h>
+ #include <linux/sched/deadline.h>
  
  #include "posix-timers.h"
  
@@@ -791,6 -792,14 +792,14 @@@ check_timers_list(struct list_head *tim
        return 0;
  }
  
+ static inline void check_dl_overrun(struct task_struct *tsk)
+ {
+       if (tsk->dl.dl_overrun) {
+               tsk->dl.dl_overrun = 0;
+               __group_send_sig_info(SIGXCPU, SEND_SIG_PRIV, tsk);
+       }
+ }
  /*
   * Check for any per-thread CPU timers that have fired and move them off
   * the tsk->cpu_timers[N] list onto the firing list.  Here we update the
@@@ -804,6 -813,9 +813,9 @@@ static void check_thread_timers(struct 
        u64 expires;
        unsigned long soft;
  
+       if (dl_task(tsk))
+               check_dl_overrun(tsk);
        /*
         * If cputime_expires is zero, then there are no active
         * per thread CPU timers.
@@@ -906,6 -918,9 +918,9 @@@ static void check_process_timers(struc
        struct task_cputime cputime;
        unsigned long soft;
  
+       if (dl_task(tsk))
+               check_dl_overrun(tsk);
        /*
         * If cputimer is not running, then there are no active
         * process wide timers (POSIX 1.b, itimers, RLIMIT_CPU).
@@@ -1111,6 -1126,9 +1126,9 @@@ static inline int fastpath_timer_check(
                        return 1;
        }
  
+       if (dl_task(tsk) && tsk->dl.dl_overrun)
+               return 1;
        return 0;
  }
  
@@@ -1189,8 -1207,9 +1207,8 @@@ void set_process_cpu_timer(struct task_
        u64 now;
  
        WARN_ON_ONCE(clock_idx == CPUCLOCK_SCHED);
 -      cpu_timer_sample_group(clock_idx, tsk, &now);
  
 -      if (oldval) {
 +      if (oldval && cpu_timer_sample_group(clock_idx, tsk, &now) != -EINVAL) {
                /*
                 * We are setting itimer. The *oldval is absolute and we update
                 * it to be relative, *newval argument is relative and we update
@@@ -1362,8 -1381,8 +1380,8 @@@ static long posix_cpu_nsleep_restart(st
        return do_cpu_nanosleep(which_clock, TIMER_ABSTIME, &t);
  }
  
 -#define PROCESS_CLOCK MAKE_PROCESS_CPUCLOCK(0, CPUCLOCK_SCHED)
 -#define THREAD_CLOCK  MAKE_THREAD_CPUCLOCK(0, CPUCLOCK_SCHED)
 +#define PROCESS_CLOCK make_process_cpuclock(0, CPUCLOCK_SCHED)
 +#define THREAD_CLOCK  make_thread_cpuclock(0, CPUCLOCK_SCHED)
  
  static int process_cpu_clock_getres(const clockid_t which_clock,
                                    struct timespec64 *tp)