Skip to content

Commit 90ca941

Browse files
Xuewen YanPeter Zijlstra
authored andcommitted
sched/uclamp: Align uclamp and util_est and call before freq update
The commit dfa0a57 ("sched/uclamg: Handle delayed dequeue") has add the sched_delayed check to prevent double uclamp_dec/inc. However, it put the uclamp_rq_inc() after enqueue_task(). This may lead to the following issues: When a task with uclamp goes through enqueue_task() and could trigger cpufreq update, its uclamp won't even be considered in the cpufreq update. It is only after enqueue will the uclamp be added to rq buckets, and cpufreq will only pick it up at the next update. This could cause a delay in frequency updating. It may affect the performance(uclamp_min > 0) or power(uclamp_max < 1024). So, just like util_est, put the uclamp_rq_inc() before enqueue_task(). And as for the sched_delayed_task, same as util_est, using the sched_delayed flag to prevent inc the sched_delayed_task's uclamp, using the ENQUEUE_DELAYED flag to allow inc the sched_delayed_task's uclamp which is being woken up. Signed-off-by: Xuewen Yan <xuewen.yan@unisoc.com> Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> Reviewed-by: Vincent Guittot <vincent.guittot@linaro.org> Reviewed-by: Dietmar Eggemann <dietmar.eggemann@arm.com> Tested-by: Dietmar Eggemann <dietmar.eggemann@arm.com> Link: https://lore.kernel.org/r/20250417043457.10632-3-xuewen.yan@unisoc.com
1 parent 0212696 commit 90ca941

File tree

1 file changed

+10
-7
lines changed

1 file changed

+10
-7
lines changed

kernel/sched/core.c

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1753,7 +1753,7 @@ static inline void uclamp_rq_dec_id(struct rq *rq, struct task_struct *p,
17531753
}
17541754
}
17551755

1756-
static inline void uclamp_rq_inc(struct rq *rq, struct task_struct *p)
1756+
static inline void uclamp_rq_inc(struct rq *rq, struct task_struct *p, int flags)
17571757
{
17581758
enum uclamp_id clamp_id;
17591759

@@ -1769,7 +1769,8 @@ static inline void uclamp_rq_inc(struct rq *rq, struct task_struct *p)
17691769
if (unlikely(!p->sched_class->uclamp_enabled))
17701770
return;
17711771

1772-
if (p->se.sched_delayed)
1772+
/* Only inc the delayed task which being woken up. */
1773+
if (p->se.sched_delayed && !(flags & ENQUEUE_DELAYED))
17731774
return;
17741775

17751776
for_each_clamp_id(clamp_id)
@@ -2037,7 +2038,7 @@ static void __init init_uclamp(void)
20372038
}
20382039

20392040
#else /* !CONFIG_UCLAMP_TASK */
2040-
static inline void uclamp_rq_inc(struct rq *rq, struct task_struct *p) { }
2041+
static inline void uclamp_rq_inc(struct rq *rq, struct task_struct *p, int flags) { }
20412042
static inline void uclamp_rq_dec(struct rq *rq, struct task_struct *p) { }
20422043
static inline void uclamp_fork(struct task_struct *p) { }
20432044
static inline void uclamp_post_fork(struct task_struct *p) { }
@@ -2073,12 +2074,14 @@ void enqueue_task(struct rq *rq, struct task_struct *p, int flags)
20732074
if (!(flags & ENQUEUE_NOCLOCK))
20742075
update_rq_clock(rq);
20752076

2076-
p->sched_class->enqueue_task(rq, p, flags);
20772077
/*
2078-
* Must be after ->enqueue_task() because ENQUEUE_DELAYED can clear
2079-
* ->sched_delayed.
2078+
* Can be before ->enqueue_task() because uclamp considers the
2079+
* ENQUEUE_DELAYED task before its ->sched_delayed gets cleared
2080+
* in ->enqueue_task().
20802081
*/
2081-
uclamp_rq_inc(rq, p);
2082+
uclamp_rq_inc(rq, p, flags);
2083+
2084+
p->sched_class->enqueue_task(rq, p, flags);
20822085

20832086
psi_enqueue(p, flags);
20842087

0 commit comments

Comments
 (0)