Miscellaneous scheduler fixes:

- Fix EEVDF se->max_slice value on enqueueing (Vincent Guittot)
 
  - Fix EEVDF augmented rb-trees re-balancing with
    multiple fields (Vincent Guittot)
 
  - In proxy scheduling, account cgroup CPU time to the execution
    context, not the scheduling context (Hui Su)
 
  - Likewise, call wq_worker_tick() for the execution context,
    not the scheduling context (Hui Su)
 
 Signed-off-by: Ingo Molnar <mingo@kernel.org>
 -----BEGIN PGP SIGNATURE-----
 
 iQJFBAABCgAvFiEEBpT5eoXrXCwVQwEKEnMQ0APhK1gFAmqmXEMRHG1pbmdvQGtl
 cm5lbC5vcmcACgkQEnMQ0APhK1hchg/6A1gRkn7T5+K957U8wpB9vjtV9cKVdWpI
 XFDGm60ylFUmU388Xb8mmrbDgmej6RpX6C4ccppygM3196w513tB+Zr8w6jbSszk
 ddgWwfwi58FFBJZTH7JDqeJ64wvrl8KId44yM6k2JdXATxh2DGF0w+YdsA+M5HVJ
 EJbjACYhePdK27wvQDtj1poDfAyiabqEnv7w62dhEU9I+ikmcPAyrhmqU0yFDNUR
 sNozsDQnEJrHtllGHpr3FVxYRqob6lOtG+86VSiZ8F6i2kA3p/451mpMyyCOMUrF
 kZlBIryLG0gylXIensqLox+z2ZIE4nUL0OX3o7mC+MLNERdWvsdgHi9AcZlIoFpJ
 wMPBLENnnGbilmwhXjk0pL655rlVVUGwaTV4T9Pk5D5qew6B9LGe8uqiLo8U/qih
 1o5Lf3ZnUi0o8XHMfNkwQ3Y0m1S7CbgJYKItE+ec+2QifmKGD5dOKo5WWDKszywF
 Zb9ScP2fMKideS/JEX1/+jvLcpDmV+HE3mC58Muek96fbJG1IQ4bL5tu+fqO85rM
 68dJymtMrkoeegmq4jqERt758sZnyv2QbDmr1Kc1G9vSKNAeahYldPU2gQ6qFBnO
 VCMvI2BUmfiia9A6NBKKgpjijc4zWydyuaQ2zdvEBddYnLWKZ5Ge26lLrjraNtdB
 GtHalAP1gVs=
 =zJHp
 -----END PGP SIGNATURE-----

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

Pull scheduler fixes from Ingo Molnar:

 - Fix EEVDF se->max_slice value on enqueueing (Vincent Guittot)

 - Fix EEVDF augmented rb-trees re-balancing with multiple
   fields (Vincent Guittot)

 - In proxy scheduling, account cgroup CPU time to the execution
   context, not the scheduling context (Hui Su)

 - Likewise, call wq_worker_tick() for the execution context,
   not the scheduling context (Hui Su)

* tag 'sched-urgent-2026-09-13' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  sched/core: Call wq_worker_tick() for the execution context
  sched: Account cgroup CPU time to the execution context
  sched/eevdf: Fix rb augmented with multi fields
  sched/eevdf: Fix augmented max_slice
This commit is contained in:
Linus Torvalds 2026-09-13 09:03:22 -07:00
commit b2a8a7669e
3 changed files with 46 additions and 16 deletions

View File

@ -87,18 +87,18 @@ rb_add_augmented_cached(struct rb_node *node, struct rb_root_cached *tree,
}
/*
* Template for declaring augmented rbtree callbacks (generic case)
* Template for declaring augmented rbtree callbacks (generic multi fields)
*
* RBSTATIC: 'static' or empty
* RBNAME: name of the rb_augment_callbacks structure
* RBSTRUCT: struct type of the tree nodes
* RBFIELD: name of struct rb_node field within RBSTRUCT
* RBAUGMENTED: name of field within RBSTRUCT holding data for subtree
* RBCOMPUTE: name of function that recomputes the RBAUGMENTED data
* RBCOPY: name of function that copies the RBAUGMENTED datas
* RBCOMPUTE: name of function that recomputes the RBAUGMENTED datas
*/
#define RB_DECLARE_CALLBACKS(RBSTATIC, RBNAME, \
RBSTRUCT, RBFIELD, RBAUGMENTED, RBCOMPUTE) \
#define RB_DECLARE_CALLBACKS_MULTI(RBSTATIC, RBNAME, \
RBSTRUCT, RBFIELD, RBCOPY, RBCOMPUTE) \
static inline void \
RBNAME ## _propagate(struct rb_node *rb, struct rb_node *stop) \
{ \
@ -114,14 +114,14 @@ RBNAME ## _copy(struct rb_node *rb_old, struct rb_node *rb_new) \
{ \
RBSTRUCT *old = rb_entry(rb_old, RBSTRUCT, RBFIELD); \
RBSTRUCT *new = rb_entry(rb_new, RBSTRUCT, RBFIELD); \
new->RBAUGMENTED = old->RBAUGMENTED; \
RBCOPY(new, old); \
} \
static void \
RBNAME ## _rotate(struct rb_node *rb_old, struct rb_node *rb_new) \
{ \
RBSTRUCT *old = rb_entry(rb_old, RBSTRUCT, RBFIELD); \
RBSTRUCT *new = rb_entry(rb_new, RBSTRUCT, RBFIELD); \
new->RBAUGMENTED = old->RBAUGMENTED; \
RBCOPY(new, old); \
RBCOMPUTE(old, false); \
} \
RBSTATIC const struct rb_augment_callbacks RBNAME = { \
@ -130,6 +130,27 @@ RBSTATIC const struct rb_augment_callbacks RBNAME = { \
.rotate = RBNAME ## _rotate \
};
/*
* Template for declaring augmented rbtree callbacks (generic single field)
*
* RBSTATIC: 'static' or empty
* RBNAME: name of the rb_augment_callbacks structure
* RBSTRUCT: struct type of the tree nodes
* RBFIELD: name of struct rb_node field within RBSTRUCT
* RBAUGMENTED: name of field within RBSTRUCT holding data for subtree
* RBCOMPUTE: name of function that recomputes the RBAUGMENTED data
*/
#define RB_DECLARE_CALLBACKS(RBSTATIC, RBNAME, \
RBSTRUCT, RBFIELD, RBAUGMENTED, RBCOMPUTE) \
static inline void \
RBNAME ## _copy_single(RBSTRUCT *new, RBSTRUCT *old) \
{ \
new->RBAUGMENTED = old->RBAUGMENTED; \
} \
RB_DECLARE_CALLBACKS_MULTI(RBSTATIC, RBNAME, \
RBSTRUCT, RBFIELD, RBNAME ## _copy_single, RBCOMPUTE)
/*
* Template for declaring augmented rbtree callbacks,
* computing RBAUGMENTED scalar as max(RBCOMPUTE(node)) for all subtree nodes.

View File

@ -5776,8 +5776,8 @@ void sched_tick(void)
{
int cpu = smp_processor_id();
struct rq *rq = cpu_rq(cpu);
/* accounting goes to the donor task */
struct task_struct *donor;
/* scheduler accounting goes to the donor task */
struct task_struct *curr, *donor;
struct rq_flags rf;
unsigned long hw_pressure;
u64 resched_latency;
@ -5788,6 +5788,7 @@ void sched_tick(void)
sched_clock_tick();
rq_lock(rq, &rf);
curr = rq->curr;
donor = rq->donor;
psi_account_irqtime(rq, donor, NULL);
@ -5813,8 +5814,8 @@ void sched_tick(void)
perf_event_task_tick();
if (donor->flags & PF_WQ_WORKER)
wq_worker_tick(donor);
if (curr->flags & PF_WQ_WORKER)
wq_worker_tick(curr);
if (!scx_switched_all()) {
rq->idle_balance = idle_cpu(cpu);

View File

@ -1032,6 +1032,13 @@ static inline void __max_slice_update(struct sched_entity *se, struct rb_node *n
}
}
static inline void min_vruntime_copy(struct sched_entity *new, struct sched_entity *old)
{
new->min_vruntime = old->min_vruntime;
new->min_slice = old->min_slice;
new->max_slice = old->max_slice;
}
/*
* se->min_vruntime = min(se->vruntime, {left,right}->min_vruntime)
*/
@ -1059,8 +1066,9 @@ static inline bool min_vruntime_update(struct sched_entity *se, bool exit)
se->max_slice == old_max_slice;
}
RB_DECLARE_CALLBACKS(static, min_vruntime_cb, struct sched_entity,
run_node, min_vruntime, min_vruntime_update);
RB_DECLARE_CALLBACKS_MULTI(static, min_vruntime_cb, struct sched_entity,
run_node, min_vruntime_copy, min_vruntime_update);
/*
* Enqueue an entity into the rb-tree:
@ -1073,6 +1081,8 @@ static void __enqueue_entity(struct cfs_rq *cfs_rq, struct sched_entity *se)
sum_w_vruntime_add(cfs_rq, se);
se->min_vruntime = se->vruntime;
se->min_slice = se->slice;
se->max_slice = se->slice;
rb_add_augmented_cached(&se->run_node, &cfs_rq->tasks_timeline,
__entity_less, &min_vruntime_cb);
}
@ -1404,7 +1414,6 @@ static s64 update_se(struct rq *rq, struct sched_entity *se)
se->exec_start = now;
if (entity_is_task(se)) {
struct task_struct *donor = task_of(se);
struct task_struct *running = rq->curr;
/*
* If se is a task, we account the time against the running
@ -1417,8 +1426,7 @@ static s64 update_se(struct rq *rq, struct sched_entity *se)
account_group_exec_runtime(running, delta_exec);
account_mm_sched(rq, running, delta_exec);
/* cgroup time is always accounted against the donor */
cgroup_account_cputime(donor, delta_exec);
cgroup_account_cputime(running, delta_exec);
} else {
/* If not task, account the time against donor se */
se->sum_exec_runtime += delta_exec;