Misc fixes:
- Fix EEVDF corner cases - Fix two nohz_full= related bugs that can cause boot crashes and warnings. Signed-off-by: Ingo Molnar <mingo@kernel.org> -----BEGIN PGP SIGNATURE----- iQJFBAABCgAvFiEEBpT5eoXrXCwVQwEKEnMQ0APhK1gFAmYuBxcRHG1pbmdvQGtl cm5lbC5vcmcACgkQEnMQ0APhK1im6A/+JfNAwxPghp9zM43ERLadl3MUbH0hsdV9 54xhQm58Fi8wzXhxhRiOcLqrhFDNsy91mRWHxt9/PjvdFXhp9GiNpehMsHCmTsS8 7ywJKcAeKTM1+7nq4RFbDFSSpr1J5aUYKXfuhWwr0QVF3mNoRkmZaLdlnVjxebbA sKXXtEKbn0yCeIsdPwmZlLxzNyOV2j0p8Xck8DKrLjW57pbebiBHyt2N59PsARb4 Yt9wNbyb48DqGNy2FaRCWlm/8OL0BLMB0tMnXkIDtW89uVuP4V6fQF0vau3re+vy A8+OMD8gpeYjNV5WKrT5r3+EQyFJGI7nr6PbWTY8KLIGCjSSu9iGojn0hdVMGTj7 rQe6LJNSMe6xW53ZrecMh6OGZ3esgkaZKafXrMcczcSq/CCX0wSVSAbANCkhyANx VFZsCgxX/zdRSwSRZiyiHLnP/3/lw0sOxoBS/m0hDSJulJF7fbQGLAfLx+Zccnoe 2KBra2DXk/49OH+jehrj2C1m2ozWp2+4Kb7mwYISrTJVp0ylgjNiznAKkmB5R8XN UOfio5nr09KJWpRKW3UoR2CpaPu/BXUB249DDm36zK1I9V/ljYzrCHKjw+TTWgdS nPEVVYR9aj4t/De8wPm0gk/Orv9KaQkpdsOCgezRB0hJGuLpABcA9FGlTJntQ+n9 UPLMOgN36Q4= =Zhc/ -----END PGP SIGNATURE----- Merge tag 'sched-urgent-2024-04-28' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip Pull scheduler fixes from Ingo Molnar: - Fix EEVDF corner cases - Fix two nohz_full= related bugs that can cause boot crashes and warnings * tag 'sched-urgent-2024-04-28' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: sched/isolation: Fix boot crash when maxcpus < first housekeeping CPU sched/isolation: Prevent boot crash when the boot CPU is nohz_full sched/eevdf: Prevent vlag from going out of bounds in reweight_eevdf() sched/eevdf: Fix miscalculation in reweight_entity() when se is not curr sched/eevdf: Always update V if se->on_rq when reweighting
This commit is contained in:
commit
245c8e8174
@ -129,11 +129,8 @@ adaptive-tick CPUs: At least one non-adaptive-tick CPU must remain
|
||||
online to handle timekeeping tasks in order to ensure that system
|
||||
calls like gettimeofday() returns accurate values on adaptive-tick CPUs.
|
||||
(This is not an issue for CONFIG_NO_HZ_IDLE=y because there are no running
|
||||
user processes to observe slight drifts in clock rate.) Therefore, the
|
||||
boot CPU is prohibited from entering adaptive-ticks mode. Specifying a
|
||||
"nohz_full=" mask that includes the boot CPU will result in a boot-time
|
||||
error message, and the boot CPU will be removed from the mask. Note that
|
||||
this means that your system must have at least two CPUs in order for
|
||||
user processes to observe slight drifts in clock rate.) Note that this
|
||||
means that your system must have at least two CPUs in order for
|
||||
CONFIG_NO_HZ_FULL=y to do anything for you.
|
||||
|
||||
Finally, adaptive-ticks CPUs must have their RCU callbacks offloaded.
|
||||
|
@ -696,15 +696,21 @@ u64 avg_vruntime(struct cfs_rq *cfs_rq)
|
||||
*
|
||||
* XXX could add max_slice to the augmented data to track this.
|
||||
*/
|
||||
static s64 entity_lag(u64 avruntime, struct sched_entity *se)
|
||||
{
|
||||
s64 vlag, limit;
|
||||
|
||||
vlag = avruntime - se->vruntime;
|
||||
limit = calc_delta_fair(max_t(u64, 2*se->slice, TICK_NSEC), se);
|
||||
|
||||
return clamp(vlag, -limit, limit);
|
||||
}
|
||||
|
||||
static void update_entity_lag(struct cfs_rq *cfs_rq, struct sched_entity *se)
|
||||
{
|
||||
s64 lag, limit;
|
||||
|
||||
SCHED_WARN_ON(!se->on_rq);
|
||||
lag = avg_vruntime(cfs_rq) - se->vruntime;
|
||||
|
||||
limit = calc_delta_fair(max_t(u64, 2*se->slice, TICK_NSEC), se);
|
||||
se->vlag = clamp(lag, -limit, limit);
|
||||
se->vlag = entity_lag(avg_vruntime(cfs_rq), se);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -3676,11 +3682,10 @@ static inline void
|
||||
dequeue_load_avg(struct cfs_rq *cfs_rq, struct sched_entity *se) { }
|
||||
#endif
|
||||
|
||||
static void reweight_eevdf(struct cfs_rq *cfs_rq, struct sched_entity *se,
|
||||
static void reweight_eevdf(struct sched_entity *se, u64 avruntime,
|
||||
unsigned long weight)
|
||||
{
|
||||
unsigned long old_weight = se->load.weight;
|
||||
u64 avruntime = avg_vruntime(cfs_rq);
|
||||
s64 vlag, vslice;
|
||||
|
||||
/*
|
||||
@ -3761,7 +3766,7 @@ static void reweight_eevdf(struct cfs_rq *cfs_rq, struct sched_entity *se,
|
||||
* = V - vl'
|
||||
*/
|
||||
if (avruntime != se->vruntime) {
|
||||
vlag = (s64)(avruntime - se->vruntime);
|
||||
vlag = entity_lag(avruntime, se);
|
||||
vlag = div_s64(vlag * old_weight, weight);
|
||||
se->vruntime = avruntime - vlag;
|
||||
}
|
||||
@ -3787,25 +3792,26 @@ static void reweight_entity(struct cfs_rq *cfs_rq, struct sched_entity *se,
|
||||
unsigned long weight)
|
||||
{
|
||||
bool curr = cfs_rq->curr == se;
|
||||
u64 avruntime;
|
||||
|
||||
if (se->on_rq) {
|
||||
/* commit outstanding execution time */
|
||||
if (curr)
|
||||
update_curr(cfs_rq);
|
||||
else
|
||||
update_curr(cfs_rq);
|
||||
avruntime = avg_vruntime(cfs_rq);
|
||||
if (!curr)
|
||||
__dequeue_entity(cfs_rq, se);
|
||||
update_load_sub(&cfs_rq->load, se->load.weight);
|
||||
}
|
||||
dequeue_load_avg(cfs_rq, se);
|
||||
|
||||
if (!se->on_rq) {
|
||||
if (se->on_rq) {
|
||||
reweight_eevdf(se, avruntime, weight);
|
||||
} else {
|
||||
/*
|
||||
* Because we keep se->vlag = V - v_i, while: lag_i = w_i*(V - v_i),
|
||||
* we need to scale se->vlag when w_i changes.
|
||||
*/
|
||||
se->vlag = div_s64(se->vlag * se->load.weight, weight);
|
||||
} else {
|
||||
reweight_eevdf(cfs_rq, se, weight);
|
||||
}
|
||||
|
||||
update_load_set(&se->load, weight);
|
||||
|
@ -46,7 +46,16 @@ int housekeeping_any_cpu(enum hk_type type)
|
||||
if (cpu < nr_cpu_ids)
|
||||
return cpu;
|
||||
|
||||
return cpumask_any_and(housekeeping.cpumasks[type], cpu_online_mask);
|
||||
cpu = cpumask_any_and(housekeeping.cpumasks[type], cpu_online_mask);
|
||||
if (likely(cpu < nr_cpu_ids))
|
||||
return cpu;
|
||||
/*
|
||||
* Unless we have another problem this can only happen
|
||||
* at boot time before start_secondary() brings the 1st
|
||||
* housekeeping CPU up.
|
||||
*/
|
||||
WARN_ON_ONCE(system_state == SYSTEM_RUNNING ||
|
||||
type != HK_TYPE_TIMER);
|
||||
}
|
||||
}
|
||||
return smp_processor_id();
|
||||
@ -109,6 +118,7 @@ static void __init housekeeping_setup_type(enum hk_type type,
|
||||
static int __init housekeeping_setup(char *str, unsigned long flags)
|
||||
{
|
||||
cpumask_var_t non_housekeeping_mask, housekeeping_staging;
|
||||
unsigned int first_cpu;
|
||||
int err = 0;
|
||||
|
||||
if ((flags & HK_FLAG_TICK) && !(housekeeping.flags & HK_FLAG_TICK)) {
|
||||
@ -129,7 +139,8 @@ static int __init housekeeping_setup(char *str, unsigned long flags)
|
||||
cpumask_andnot(housekeeping_staging,
|
||||
cpu_possible_mask, non_housekeeping_mask);
|
||||
|
||||
if (!cpumask_intersects(cpu_present_mask, housekeeping_staging)) {
|
||||
first_cpu = cpumask_first_and(cpu_present_mask, housekeeping_staging);
|
||||
if (first_cpu >= nr_cpu_ids || first_cpu >= setup_max_cpus) {
|
||||
__cpumask_set_cpu(smp_processor_id(), housekeeping_staging);
|
||||
__cpumask_clear_cpu(smp_processor_id(), non_housekeeping_mask);
|
||||
if (!housekeeping.flags) {
|
||||
@ -138,6 +149,9 @@ static int __init housekeeping_setup(char *str, unsigned long flags)
|
||||
}
|
||||
}
|
||||
|
||||
if (cpumask_empty(non_housekeeping_mask))
|
||||
goto free_housekeeping_staging;
|
||||
|
||||
if (!housekeeping.flags) {
|
||||
/* First setup call ("nohz_full=" or "isolcpus=") */
|
||||
enum hk_type type;
|
||||
|
Loading…
Reference in New Issue
Block a user