mirror of
https://gitee.com/bianbu-linux/linux-6.6
synced 2025-04-24 14:07:52 -04:00
sched/core: Fixed missing rq clock update before calling set_rq_offline()
When using a cpufreq governor that uses cpufreq_add_update_util_hook(), it is possible to trigger a missing update_rq_clock() warning for the CPU hotplug path: rq_attach_root() set_rq_offline() rq_offline_rt() __disable_runtime() sched_rt_rq_enqueue() enqueue_top_rt_rq() cpufreq_update_util() data->func(data, rq_clock(rq), flags) Move update_rq_clock() from sched_cpu_deactivate() (one of it's callers) into set_rq_offline() such that it covers all set_rq_offline() usage. Additionally change rq_attach_root() to use rq_lock_irqsave() so that it will properly manage the runqueue clock flags. Suggested-by: Ben Segall <bsegall@google.com> Signed-off-by: Hao Jia <jiahao.os@bytedance.com> Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> Reviewed-by: Vincent Guittot <vincent.guittot@linaro.org> Link: https://lkml.kernel.org/r/20230613082012.49615-2-jiahao.os@bytedance.com
This commit is contained in:
parent
e20f204c88
commit
cab3ecaed5
2 changed files with 4 additions and 4 deletions
|
@ -9585,6 +9585,7 @@ void set_rq_offline(struct rq *rq)
|
||||||
if (rq->online) {
|
if (rq->online) {
|
||||||
const struct sched_class *class;
|
const struct sched_class *class;
|
||||||
|
|
||||||
|
update_rq_clock(rq);
|
||||||
for_each_class(class) {
|
for_each_class(class) {
|
||||||
if (class->rq_offline)
|
if (class->rq_offline)
|
||||||
class->rq_offline(rq);
|
class->rq_offline(rq);
|
||||||
|
@ -9726,7 +9727,6 @@ int sched_cpu_deactivate(unsigned int cpu)
|
||||||
|
|
||||||
rq_lock_irqsave(rq, &rf);
|
rq_lock_irqsave(rq, &rf);
|
||||||
if (rq->rd) {
|
if (rq->rd) {
|
||||||
update_rq_clock(rq);
|
|
||||||
BUG_ON(!cpumask_test_cpu(cpu, rq->rd->span));
|
BUG_ON(!cpumask_test_cpu(cpu, rq->rd->span));
|
||||||
set_rq_offline(rq);
|
set_rq_offline(rq);
|
||||||
}
|
}
|
||||||
|
|
|
@ -487,9 +487,9 @@ static void free_rootdomain(struct rcu_head *rcu)
|
||||||
void rq_attach_root(struct rq *rq, struct root_domain *rd)
|
void rq_attach_root(struct rq *rq, struct root_domain *rd)
|
||||||
{
|
{
|
||||||
struct root_domain *old_rd = NULL;
|
struct root_domain *old_rd = NULL;
|
||||||
unsigned long flags;
|
struct rq_flags rf;
|
||||||
|
|
||||||
raw_spin_rq_lock_irqsave(rq, flags);
|
rq_lock_irqsave(rq, &rf);
|
||||||
|
|
||||||
if (rq->rd) {
|
if (rq->rd) {
|
||||||
old_rd = rq->rd;
|
old_rd = rq->rd;
|
||||||
|
@ -515,7 +515,7 @@ void rq_attach_root(struct rq *rq, struct root_domain *rd)
|
||||||
if (cpumask_test_cpu(rq->cpu, cpu_active_mask))
|
if (cpumask_test_cpu(rq->cpu, cpu_active_mask))
|
||||||
set_rq_online(rq);
|
set_rq_online(rq);
|
||||||
|
|
||||||
raw_spin_rq_unlock_irqrestore(rq, flags);
|
rq_unlock_irqrestore(rq, &rf);
|
||||||
|
|
||||||
if (old_rd)
|
if (old_rd)
|
||||||
call_rcu(&old_rd->rcu, free_rootdomain);
|
call_rcu(&old_rd->rcu, free_rootdomain);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue