Miscellaneous scheduler fixes:

- Fix a timestamping bug in pick_task_fair() and
    yield_task_fair() (Zhan Xusheng)
 
  - Skip migrate-disabled tasks when picking a push
    candidate in the RT and DL schedulers (Seiji Nishikawa)
 
  - Skip rq->avg_idle update without a valid idle_stamp
    (Shubhang Kaushik)
 
  - Fix throttling bug in throttle_cfs_rq(), caused
    by the recent single-runqueue conversion (Wanwu Li)
 
  - Fix bandwidth calculation bug in distribute_cfs_runtime(),
    caused by the single-runqueue conversion (Wanwu Li)
 
  - Don't make x86 ITMT enablement depend on debugfs (Mario Limonciello)
 
  - Avoid creating misfits during cache-aware load-balancing
    on hybrid systems (Tim Chen)
 
 Signed-off-by: Ingo Molnar <mingo@kernel.org>
 -----BEGIN PGP SIGNATURE-----
 
 iQJFBAABCgAvFiEEBpT5eoXrXCwVQwEKEnMQ0APhK1gFAmqdTLIRHG1pbmdvQGtl
 cm5lbC5vcmcACgkQEnMQ0APhK1gdURAAnjK4q2xg115VyKOvg4u4epPre1XNK4a/
 RmimS/2+1fm7/5zqOXOQG3qU8z2Aj+nBIZa1d1yadV7ARHSymDINobCX+2HQ1DjU
 Iysk2BqbbLnQQNKh81OBWhPMyJy4yOnig/670KR5JdFAdTKFYW/Ys+pQmO9M6rEx
 hc8B4SUhOGeRnonfPMTbFW7H9eopWzst8kIpF0USl58az0mla5tkooWYJsvSuUHn
 g4s9IALlRe3DxgmMT3kLKoAx2+ySnrzZNRs+M8Z/sMSDKXCMFpvX36wOqBJMHwXe
 ZoAow/fJh4ysoYTR7luhDIBDQAkszf4GE9a644I/Bd0sIIYKs4+1RW1T3DAoWmKv
 Sx0C29MM4Ng4R3lPx2avb+c0T0VO080/3fqRFrGrck8BIpMa9HcinOxf6etI8+vt
 STnz5uQZZj3V+A5vzlKCAFGUUqK/s3EJnrT5z4VPxXmY2ZSyLLub4C5SQ8RNnqRL
 u+Q9ra9DYBJh/HJTgjjcAP/HxmKK5LyQXd2DzuA1wy/wwC+s7TtPrxN5ep5EdZmv
 K65zGGo28BgcCKD8jc1DfVXf8cf80fMiAr4fruGdo5TVwPyBahwZBi4sbqhahtqL
 D4QwCsbOfhS+evVpx29n+V7eQzZzvSdN1tFCtZ3Tg6VvT9aJ2jLSx79aCsL/cYbr
 hViB9N0yhGk=
 =8l0J
 -----END PGP SIGNATURE-----

Merge tag 'sched-urgent-2026-09-06' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull scheduler fixes from Ingo Molnar:

 - Fix a timestamping bug in pick_task_fair() and yield_task_fair()
   (Zhan Xusheng)

 - Skip migrate-disabled tasks when picking a push candidate in the
   RT and DL schedulers (Seiji Nishikawa)

 - Skip rq->avg_idle update without a valid idle_stamp (Shubhang
   Kaushik)

 - Fix throttling bug in throttle_cfs_rq(), caused by the recent
   single-runqueue conversion (Wanwu Li)

 - Fix bandwidth calculation bug in distribute_cfs_runtime(),
   caused by the single-runqueue conversion (Wanwu Li)

 - Don't make x86 ITMT enablement depend on debugfs (Mario Limonciello)

 - Avoid creating misfits during cache-aware load-balancing on hybrid
   systems (Tim Chen)

* tag 'sched-urgent-2026-09-06' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  sched/fair: Avoid creating misfits during cache-aware balancing
  x86/itmt: Don't make ITMT enablement depend on debugfs
  sched/fair: Use cfs_rq->h_curr in distribute_cfs_runtime()
  sched/fair: Use cfs_rq->h_curr in throttle_cfs_rq()
  sched/core: Skip rq->avg_idle update without a valid idle_stamp
  sched/rt,dl: Skip migrate-disabled tasks when picking a push candidate
  sched/fair: Use update_curr_eevdf() for the remaining root cfs_rq callers
This commit is contained in:
Linus Torvalds 2026-09-06 11:08:44 -07:00
commit 88405f0ad1
5 changed files with 64 additions and 22 deletions

View File

@ -110,18 +110,14 @@ int sched_set_itmt_support(void)
arch_debugfs_dir,
&sysctl_sched_itmt_enabled,
&dfs_sched_itmt_fops);
if (IS_ERR_OR_NULL(dfs_sched_itmt)) {
if (IS_ERR(dfs_sched_itmt))
dfs_sched_itmt = NULL;
return -ENOMEM;
}
dfs_sched_core_prio = debugfs_create_file("sched_core_priority", 0644,
arch_debugfs_dir, NULL,
&sched_core_priority_fops);
if (IS_ERR_OR_NULL(dfs_sched_core_prio)) {
if (IS_ERR(dfs_sched_core_prio))
dfs_sched_core_prio = NULL;
return -ENOMEM;
}
sched_itmt_capable = true;

View File

@ -3742,11 +3742,17 @@ static inline void ttwu_do_wakeup(struct task_struct *p)
void update_rq_avg_idle(struct rq *rq)
{
u64 delta = rq_clock(rq) - rq->idle_stamp;
u64 max = 2*rq->max_idle_balance_cost;
u64 idle_stamp = rq->idle_stamp;
u64 delta, max;
if (!idle_stamp)
return;
delta = rq_clock(rq) - idle_stamp;
update_avg(&rq->avg_idle, delta);
max = 2 * rq->max_idle_balance_cost;
if (rq->avg_idle > max)
rq->avg_idle = max;
rq->idle_stamp = 0;

View File

@ -3028,8 +3028,8 @@ static struct task_struct *pick_next_pushable_dl_task(struct rq *rq)
next_node = rb_first_cached(&rq->dl.pushable_dl_tasks_root);
while (next_node) {
i = __node_2_pdl(next_node);
/* make sure task isn't on_cpu (possible with proxy-exec) */
if (!task_on_cpu(rq, i)) {
/* skip tasks that cannot be migrated */
if (!task_on_cpu(rq, i) && !is_migration_disabled(i)) {
p = i;
break;
}

View File

@ -6978,14 +6978,14 @@ static int tg_throttle_down(struct task_group *tg, void *data)
static bool throttle_cfs_rq(struct cfs_rq *cfs_rq)
{
struct cfs_bandwidth *cfs_b = tg_cfs_bandwidth(cfs_rq->tg);
struct sched_entity *curr = cfs_rq->curr;
struct sched_entity *curr = cfs_rq->h_curr;
struct rq *rq = rq_of(cfs_rq);
scoped_guard(raw_spinlock, &cfs_b->lock) {
u64 target_runtime = 1;
/*
* If cfs_rq->curr is still runnable, we are here from an
* If cfs_rq->h_curr is still runnable, we are here from an
* update_curr(). Request sysctl_sched_cfs_bandwidth_slice
* worth of bandwidth to continue running.
*
@ -7192,7 +7192,7 @@ static bool distribute_cfs_runtime(struct cfs_bandwidth *cfs_b)
if (!list_empty(&cfs_rq->throttled_csd_list))
continue;
if (cfs_rq->curr) {
if (cfs_rq->h_curr) {
update_rq_clock(rq);
update_curr(cfs_rq);
}
@ -10057,7 +10057,7 @@ struct task_struct *pick_task_fair(struct rq *rq, struct rq_flags *rf)
/* Might not have done put_prev_entity() */
if (cfs_rq->curr && cfs_rq->curr->on_rq)
update_curr(cfs_rq);
update_curr_eevdf(cfs_rq);
se = pick_next_entity(rq, true);
if (!se)
@ -10160,7 +10160,7 @@ static void yield_task_fair(struct rq *rq)
/*
* Update run-time statistics of the 'current'.
*/
update_curr(cfs_rq);
update_curr_eevdf(cfs_rq);
/*
* Tell update_rq_clock() that we've just updated,
* so we don't do microscopic update in schedule()
@ -10691,17 +10691,40 @@ static enum llc_mig can_migrate_llc(int src_cpu, int dst_cpu,
return mig_llc;
}
static inline bool task_misfits_asym_cpu(struct lb_env *env, struct task_struct *p)
{
/*
* On asymmetric CPU capacity domains, do not let cache-aware
* balancing pull the task onto a destination CPU that cannot
* accommodate it. Doing so would turn the task into a misfit on
* the destination, trading a cache-locality gain for a capacity
* loss. If the task already does not fit its source CPU, the move
* cannot make things worse, so let the LLC preference decide.
*/
if ((env->sd->flags & SD_ASYM_CPUCAPACITY) && p &&
!task_fits_cpu(p, env->dst_cpu) &&
task_fits_cpu(p, env->src_cpu))
return true;
return false;
}
/*
* Check if task p can migrate from source LLC to
* destination LLC in terms of cache aware load balance.
*/
static enum llc_mig can_migrate_llc_task(int src_cpu, int dst_cpu,
static enum llc_mig can_migrate_llc_task(struct lb_env *env,
struct task_struct *p)
{
struct mm_struct *mm;
bool to_pref;
int cpu;
int cpu, src_cpu, dst_cpu;
if (task_misfits_asym_cpu(env, p))
return mig_forbid;
src_cpu = env->src_cpu;
dst_cpu = env->dst_cpu;
mm = p->mm;
if (!mm)
return mig_unrestricted;
@ -10758,6 +10781,14 @@ alb_break_llc(struct lb_env *env)
unsigned long util = 0;
struct task_struct *cur;
/*
* Migrating misfit tasks from current CPU
* to CPU with a better fit.
* Prioritize that over LLC preference.
*/
if (env->migration_type == migrate_misfit)
return false;
if (env->src_rq->nr_running <= 1)
return true;
@ -10765,7 +10796,8 @@ alb_break_llc(struct lb_env *env)
if (cur && cur->sched_class == &fair_sched_class)
util = task_util(cur);
if (can_migrate_llc(env->src_cpu, env->dst_cpu,
if (task_misfits_asym_cpu(env, cur) ||
can_migrate_llc(env->src_cpu, env->dst_cpu,
util, false) == mig_forbid)
return true;
}
@ -10805,8 +10837,7 @@ static bool migrate_degrades_llc(struct task_struct *p, struct lb_env *env)
READ_ONCE(p->preferred_llc) != llc_id(env->dst_cpu))
return true;
if (can_migrate_llc_task(env->src_cpu,
env->dst_cpu, p) != mig_forbid)
if (can_migrate_llc_task(env, p) != mig_forbid)
return false;
return true;
@ -11869,6 +11900,15 @@ static inline bool llc_balance(struct lb_env *env, struct sg_lb_stats *sgs,
if (env->sd->flags & SD_SHARE_LLC)
return false;
/*
* On asymmetric domains, group_misfit_task_load
* should be prioritized to move tasks to CPU that fit them
* over aggregating tasks to their preferred LLC.
*/
if ((env->sd->flags & SD_ASYM_CPUCAPACITY) &&
sgs->group_misfit_task_load)
return false;
/*
* Skip cache aware tagging if nr_balanced_failed is sufficiently high.
* Threshold of cache_nice_tries is set to 1 higher than nr_balance_failed

View File

@ -1872,8 +1872,8 @@ static struct task_struct *pick_next_pushable_task(struct rq *rq)
return NULL;
plist_for_each_entry(i, head, pushable_tasks) {
/* make sure task isn't on_cpu (possible with proxy-exec) */
if (!task_on_cpu(rq, i)) {
/* skip tasks that cannot be migrated */
if (!task_on_cpu(rq, i) && !is_migration_disabled(i)) {
p = i;
break;
}