Merge tag 'sched-urgent-2021-07-11' of git://git.kernel.org/pub/scm/linux/kernel...
authorLinus Torvalds <torvalds@linux-foundation.org>
Sun, 11 Jul 2021 18:13:57 +0000 (11:13 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Sun, 11 Jul 2021 18:13:57 +0000 (11:13 -0700)
Pull scheduler fixes from Ingo Molnar:
 "Three fixes:

   - Fix load tracking bug/inconsistency

   - Fix a sporadic CFS bandwidth constraints enforcement bug

   - Fix a uclamp utilization tracking bug for newly woken tasks"

* tag 'sched-urgent-2021-07-11' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  sched/uclamp: Ignore max aggregation if rq is idle
  sched/fair: Fix CFS bandwidth hrtimer expiry type
  sched/fair: Sync load_sum with load_avg after dequeue

1  2 
kernel/sched/fair.c

diff --combined kernel/sched/fair.c
@@@ -3037,8 -3037,9 +3037,9 @@@ enqueue_load_avg(struct cfs_rq *cfs_rq
  static inline void
  dequeue_load_avg(struct cfs_rq *cfs_rq, struct sched_entity *se)
  {
+       u32 divider = get_pelt_divider(&se->avg);
        sub_positive(&cfs_rq->avg.load_avg, se->avg.load_avg);
-       sub_positive(&cfs_rq->avg.load_sum, se_weight(se) * se->avg.load_sum);
+       cfs_rq->avg.load_sum = cfs_rq->avg.load_avg * divider;
  }
  #else
  static inline void
@@@ -3255,31 -3256,6 +3256,31 @@@ static inline void cfs_rq_util_change(s
  
  #ifdef CONFIG_SMP
  #ifdef CONFIG_FAIR_GROUP_SCHED
 +/*
 + * Because list_add_leaf_cfs_rq always places a child cfs_rq on the list
 + * immediately before a parent cfs_rq, and cfs_rqs are removed from the list
 + * bottom-up, we only have to test whether the cfs_rq before us on the list
 + * is our child.
 + * If cfs_rq is not on the list, test whether a child needs its to be added to
 + * connect a branch to the tree  * (see list_add_leaf_cfs_rq() for details).
 + */
 +static inline bool child_cfs_rq_on_list(struct cfs_rq *cfs_rq)
 +{
 +      struct cfs_rq *prev_cfs_rq;
 +      struct list_head *prev;
 +
 +      if (cfs_rq->on_list) {
 +              prev = cfs_rq->leaf_cfs_rq_list.prev;
 +      } else {
 +              struct rq *rq = rq_of(cfs_rq);
 +
 +              prev = rq->tmp_alone_branch;
 +      }
 +
 +      prev_cfs_rq = container_of(prev, struct cfs_rq, leaf_cfs_rq_list);
 +
 +      return (prev_cfs_rq->tg->parent == cfs_rq->tg);
 +}
  
  static inline bool cfs_rq_is_decayed(struct cfs_rq *cfs_rq)
  {
        if (cfs_rq->avg.runnable_sum)
                return false;
  
 +      if (child_cfs_rq_on_list(cfs_rq))
 +              return false;
 +
        /*
         * _avg must be null when _sum are null because _avg = _sum / divider
         * Make sure that rounding and/or propagation of PELT values never
@@@ -5081,7 -5054,7 +5082,7 @@@ static const u64 cfs_bandwidth_slack_pe
  static int runtime_refresh_within(struct cfs_bandwidth *cfs_b, u64 min_expire)
  {
        struct hrtimer *refresh_timer = &cfs_b->period_timer;
-       u64 remaining;
+       s64 remaining;
  
        /* if the call-back is running a quota refresh is already occurring */
        if (hrtimer_callback_running(refresh_timer))
  
        /* is a quota refresh about to occur? */
        remaining = ktime_to_ns(hrtimer_expires_remaining(refresh_timer));
-       if (remaining < min_expire)
+       if (remaining < (s64)min_expire)
                return 1;
  
        return 0;