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 Signed-off-by: Ingo Molnar <mingo@kernel.org> -----BEGIN PGP SIGNATURE----- iQJFBAABCgAvFiEEBpT5eoXrXCwVQwEKEnMQ0APhK1gFAmDq8scRHG1pbmdvQGtl cm5lbC5vcmcACgkQEnMQ0APhK1i1nQ/+PsOimY0+2kW2EUp/a1a8h1ZHfyG1RjDo Kl/CCUDdEP0OuWC/cdnvYgo3hNPTVCpZvsIoR/t7CFinuR/ubfsFtLZ5juOzjk5v 2RjmSyOr0DbhUcO3GFKo+ABlrmiiJ9de89+oal+W/t/Zks/xqVHQ+f7HqSGvSd1f Lhem4U9UakbO3yjT/+VwSvNZgP8trtPQ6rrKw+yrwrxfjSo4D0Y+/3u/HCaYthIW 5i1+uBEXGnZaU7QhDfqqzbGcAKLRA+i2vBmNfbOyUeCcyKTsKlLwX9L1DlgNPLRP XvxVJWJcxwTsLbwVG1F3TvWw93iSLi34jPO//2ZnNppEhA4fjxmLSYV3uIsm8PUY /YmDdZ6fTW7ZIO/nhfcf3nS8Sp0UlfHXL9dV3mn2EzeMLGOKZY6vgAKdvEd+Fj+y J+VB01MgmVzGvFr9o1/ez3vWyk03CLDQuYMUo0yVcqAi4OLaArAz5vxXR/cF4PsB r69CCdSinMj2finaR39Eq0431Tpv71NDDfyqjVJEOk88Weszu6IACIOJCvpy0ZLQ LOA5kl2I8/mYEevnXgg9NPX8XO2iUFS1cVVNsRHUe4zqQZPPoBD6Oppb+kmfUQUe gABCZK217nkqFH4GdC9RCtRdnb4HO+6H15cLlDHjilECgGOPeJ8CPaK3pRvzv0g3 N2m4KcFI2j0= =FBcX -----END PGP SIGNATURE----- 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
This commit is contained in:
commit
877029d921
|
@ -3037,8 +3037,9 @@ enqueue_load_avg(struct cfs_rq *cfs_rq, struct sched_entity *se)
|
||||||
static inline void
|
static inline void
|
||||||
dequeue_load_avg(struct cfs_rq *cfs_rq, struct sched_entity *se)
|
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_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
|
#else
|
||||||
static inline void
|
static inline void
|
||||||
|
@ -5081,7 +5082,7 @@ static const u64 cfs_bandwidth_slack_period = 5 * NSEC_PER_MSEC;
|
||||||
static int runtime_refresh_within(struct cfs_bandwidth *cfs_b, u64 min_expire)
|
static int runtime_refresh_within(struct cfs_bandwidth *cfs_b, u64 min_expire)
|
||||||
{
|
{
|
||||||
struct hrtimer *refresh_timer = &cfs_b->period_timer;
|
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 the call-back is running a quota refresh is already occurring */
|
||||||
if (hrtimer_callback_running(refresh_timer))
|
if (hrtimer_callback_running(refresh_timer))
|
||||||
|
@ -5089,7 +5090,7 @@ static int runtime_refresh_within(struct cfs_bandwidth *cfs_b, u64 min_expire)
|
||||||
|
|
||||||
/* is a quota refresh about to occur? */
|
/* is a quota refresh about to occur? */
|
||||||
remaining = ktime_to_ns(hrtimer_expires_remaining(refresh_timer));
|
remaining = ktime_to_ns(hrtimer_expires_remaining(refresh_timer));
|
||||||
if (remaining < min_expire)
|
if (remaining < (s64)min_expire)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -2818,20 +2818,27 @@ static __always_inline
|
||||||
unsigned long uclamp_rq_util_with(struct rq *rq, unsigned long util,
|
unsigned long uclamp_rq_util_with(struct rq *rq, unsigned long util,
|
||||||
struct task_struct *p)
|
struct task_struct *p)
|
||||||
{
|
{
|
||||||
unsigned long min_util;
|
unsigned long min_util = 0;
|
||||||
unsigned long max_util;
|
unsigned long max_util = 0;
|
||||||
|
|
||||||
if (!static_branch_likely(&sched_uclamp_used))
|
if (!static_branch_likely(&sched_uclamp_used))
|
||||||
return util;
|
return util;
|
||||||
|
|
||||||
min_util = READ_ONCE(rq->uclamp[UCLAMP_MIN].value);
|
|
||||||
max_util = READ_ONCE(rq->uclamp[UCLAMP_MAX].value);
|
|
||||||
|
|
||||||
if (p) {
|
if (p) {
|
||||||
min_util = max(min_util, uclamp_eff_value(p, UCLAMP_MIN));
|
min_util = uclamp_eff_value(p, UCLAMP_MIN);
|
||||||
max_util = max(max_util, uclamp_eff_value(p, UCLAMP_MAX));
|
max_util = uclamp_eff_value(p, UCLAMP_MAX);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Ignore last runnable task's max clamp, as this task will
|
||||||
|
* reset it. Similarly, no need to read the rq's min clamp.
|
||||||
|
*/
|
||||||
|
if (rq->uclamp_flags & UCLAMP_FLAG_IDLE)
|
||||||
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
min_util = max_t(unsigned long, min_util, READ_ONCE(rq->uclamp[UCLAMP_MIN].value));
|
||||||
|
max_util = max_t(unsigned long, max_util, READ_ONCE(rq->uclamp[UCLAMP_MAX].value));
|
||||||
|
out:
|
||||||
/*
|
/*
|
||||||
* Since CPU's {min,max}_util clamps are MAX aggregated considering
|
* Since CPU's {min,max}_util clamps are MAX aggregated considering
|
||||||
* RUNNABLE tasks with _different_ clamps, we can end up with an
|
* RUNNABLE tasks with _different_ clamps, we can end up with an
|
||||||
|
|
Loading…
Reference in New Issue