Skip to content

Commit 877029d

Browse files
committed
Merge tag 'sched-urgent-2021-07-11' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
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
2 parents 936b664 + 3e1493f commit 877029d

File tree

2 files changed

+18
-10
lines changed

2 files changed

+18
-10
lines changed

kernel/sched/fair.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3037,8 +3037,9 @@ enqueue_load_avg(struct cfs_rq *cfs_rq, struct sched_entity *se)
30373037
static inline void
30383038
dequeue_load_avg(struct cfs_rq *cfs_rq, struct sched_entity *se)
30393039
{
3040+
u32 divider = get_pelt_divider(&se->avg);
30403041
sub_positive(&cfs_rq->avg.load_avg, se->avg.load_avg);
3041-
sub_positive(&cfs_rq->avg.load_sum, se_weight(se) * se->avg.load_sum);
3042+
cfs_rq->avg.load_sum = cfs_rq->avg.load_avg * divider;
30423043
}
30433044
#else
30443045
static inline void
@@ -5081,15 +5082,15 @@ static const u64 cfs_bandwidth_slack_period = 5 * NSEC_PER_MSEC;
50815082
static int runtime_refresh_within(struct cfs_bandwidth *cfs_b, u64 min_expire)
50825083
{
50835084
struct hrtimer *refresh_timer = &cfs_b->period_timer;
5084-
u64 remaining;
5085+
s64 remaining;
50855086

50865087
/* if the call-back is running a quota refresh is already occurring */
50875088
if (hrtimer_callback_running(refresh_timer))
50885089
return 1;
50895090

50905091
/* is a quota refresh about to occur? */
50915092
remaining = ktime_to_ns(hrtimer_expires_remaining(refresh_timer));
5092-
if (remaining < min_expire)
5093+
if (remaining < (s64)min_expire)
50935094
return 1;
50945095

50955096
return 0;

kernel/sched/sched.h

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2818,20 +2818,27 @@ static __always_inline
28182818
unsigned long uclamp_rq_util_with(struct rq *rq, unsigned long util,
28192819
struct task_struct *p)
28202820
{
2821-
unsigned long min_util;
2822-
unsigned long max_util;
2821+
unsigned long min_util = 0;
2822+
unsigned long max_util = 0;
28232823

28242824
if (!static_branch_likely(&sched_uclamp_used))
28252825
return util;
28262826

2827-
min_util = READ_ONCE(rq->uclamp[UCLAMP_MIN].value);
2828-
max_util = READ_ONCE(rq->uclamp[UCLAMP_MAX].value);
2829-
28302827
if (p) {
2831-
min_util = max(min_util, uclamp_eff_value(p, UCLAMP_MIN));
2832-
max_util = max(max_util, uclamp_eff_value(p, UCLAMP_MAX));
2828+
min_util = uclamp_eff_value(p, UCLAMP_MIN);
2829+
max_util = uclamp_eff_value(p, UCLAMP_MAX);
2830+
2831+
/*
2832+
* Ignore last runnable task's max clamp, as this task will
2833+
* reset it. Similarly, no need to read the rq's min clamp.
2834+
*/
2835+
if (rq->uclamp_flags & UCLAMP_FLAG_IDLE)
2836+
goto out;
28332837
}
28342838

2839+
min_util = max_t(unsigned long, min_util, READ_ONCE(rq->uclamp[UCLAMP_MIN].value));
2840+
max_util = max_t(unsigned long, max_util, READ_ONCE(rq->uclamp[UCLAMP_MAX].value));
2841+
out:
28352842
/*
28362843
* Since CPU's {min,max}_util clamps are MAX aggregated considering
28372844
* RUNNABLE tasks with _different_ clamps, we can end up with an

0 commit comments

Comments
 (0)