The Linux Kernel Mailing List
 help / color / mirror / Atom feed
From: liuwenfang <liuwenfang@honor.com>
To: 'Tejun Heo' <tj@kernel.org>
Cc: 'David Vernet' <void@manifault.com>,
	'Andrea Righi' <arighi@nvidia.com>,
	'Changwoo Min' <changwoo@igalia.com>,
	'Ingo Molnar' <mingo@redhat.com>,
	'Peter Zijlstra' <peterz@infradead.org>,
	'Juri Lelli' <juri.lelli@redhat.com>,
	'Vincent Guittot' <vincent.guittot@linaro.org>,
	'Dietmar Eggemann' <dietmar.eggemann@arm.com>,
	'Steven Rostedt' <rostedt@goodmis.org>,
	'Ben Segall' <bsegall@google.com>, 'Mel Gorman' <mgorman@suse.de>,
	'Valentin Schneider' <vschneid@redhat.com>,
	"'linux-kernel@vger.kernel.org'" <linux-kernel@vger.kernel.org>
Subject: [PATCH] sched_ext: idle: Fix cpu_released while RT task is scheduled on an idle core
Date: Tue, 10 Jun 2025 07:51:17 +0000	[thread overview]
Message-ID: <ff3aa51349414f169cd550f25b245c38@honor.com> (raw)

Assume task RT1 and RT2 have RT prio, one cpu has scheduled task RT1,
task idle, and task RT2 in order, and rq->scx.cpu_released was true while
task RT1 was running. then rq->scx.cpu_released was changed from true to
false while task RT1 was scheduled out and idle was scheduled in.
But rq->scx.cpu_released could not be changed to true while task RT2 was
scheduled in later.

The sched_class of next task can be observed while update_idle and the
state of rq->scx.cpu_released can be changed properly.

Signed-off-by: liuwenfang liuwenfang@honor.com 
---
 kernel/sched/ext.c      |  2 +-
 kernel/sched/ext.h      | 11 +++++++----
 kernel/sched/ext_idle.c |  6 +++++-
 kernel/sched/ext_idle.h |  1 +
 kernel/sched/idle.c     |  6 +++---
 5 files changed, 17 insertions(+), 9 deletions(-)

diff --git a/kernel/sched/ext.c b/kernel/sched/ext.c
index f5133249f..6bbea0ea1 100644
--- a/kernel/sched/ext.c
+++ b/kernel/sched/ext.c
@@ -3187,7 +3187,7 @@ preempt_reason_from_class(const struct sched_class *class)
 	return SCX_CPU_PREEMPT_UNKNOWN;
 }
 
-static void switch_class(struct rq *rq, struct task_struct *next)
+void switch_class(struct rq *rq, struct task_struct *next)
 {
 	const struct sched_class *next_class = next->sched_class;
 
diff --git a/kernel/sched/ext.h b/kernel/sched/ext.h
index 1bda96b19..eddfcc98e 100644
--- a/kernel/sched/ext.h
+++ b/kernel/sched/ext.h
@@ -67,15 +67,18 @@ static inline void init_sched_ext_class(void) {}
 #endif	/* CONFIG_SCHED_CLASS_EXT */
 
 #if defined(CONFIG_SCHED_CLASS_EXT) && defined(CONFIG_SMP)
-void __scx_update_idle(struct rq *rq, bool idle, bool do_notify);
+void __scx_update_idle(struct rq *rq, struct task_struct *next,
+		       bool idle, bool do_notify);
 
-static inline void scx_update_idle(struct rq *rq, bool idle, bool do_notify)
+static inline void scx_update_idle(struct rq *rq, struct task_struct *next,
+				   bool idle, bool do_notify)
 {
 	if (scx_enabled())
-		__scx_update_idle(rq, idle, do_notify);
+		__scx_update_idle(rq, next, idle, do_notify);
 }
 #else
-static inline void scx_update_idle(struct rq *rq, bool idle, bool do_notify) {}
+static inline void scx_update_idle(struct rq *rq, struct task_struct *next,
+				   bool idle, bool do_notify) {}
 #endif
 
 #ifdef CONFIG_CGROUP_SCHED
diff --git a/kernel/sched/ext_idle.c b/kernel/sched/ext_idle.c
index e67a19a07..9735f1fb1 100644
--- a/kernel/sched/ext_idle.c
+++ b/kernel/sched/ext_idle.c
@@ -660,12 +660,16 @@ static void update_builtin_idle(int cpu, bool idle)
  * while avoiding unnecessary updates and maintaining balanced state
  * transitions.
  */
-void __scx_update_idle(struct rq *rq, bool idle, bool do_notify)
+void __scx_update_idle(struct rq *rq, struct task_struct *next,
+		       bool idle, bool do_notify)
 {
 	int cpu = cpu_of(rq);
 
 	lockdep_assert_rq_held(rq);
 
+	if (!idle && !rq->scx.cpu_released && next)
+		switch_class(rq, next);
+
 	/*
 	 * Trigger ops.update_idle() only when transitioning from a task to
 	 * the idle thread and vice versa.
diff --git a/kernel/sched/ext_idle.h b/kernel/sched/ext_idle.h
index 511cc2221..83d74ea37 100644
--- a/kernel/sched/ext_idle.h
+++ b/kernel/sched/ext_idle.h
@@ -31,5 +31,6 @@ s32 scx_select_cpu_dfl(struct task_struct *p, s32 prev_cpu, u64 wake_flags, u64
 void scx_idle_enable(struct sched_ext_ops *ops);
 void scx_idle_disable(void);
 int scx_idle_init(void);
+void switch_class(struct rq *rq, struct task_struct *next);
 
 #endif /* _KERNEL_SCHED_EXT_IDLE_H */
diff --git a/kernel/sched/idle.c b/kernel/sched/idle.c
index 2c85c86b4..1b77b56bc 100644
--- a/kernel/sched/idle.c
+++ b/kernel/sched/idle.c
@@ -452,20 +452,20 @@ static void wakeup_preempt_idle(struct rq *rq, struct task_struct *p, int flags)
 static void put_prev_task_idle(struct rq *rq, struct task_struct *prev, struct task_struct *next)
 {
 	dl_server_update_idle_time(rq, prev);
-	scx_update_idle(rq, false, true);
+	scx_update_idle(rq, next, false, true);
 }
 
 static void set_next_task_idle(struct rq *rq, struct task_struct *next, bool first)
 {
 	update_idle_core(rq);
-	scx_update_idle(rq, true, true);
+	scx_update_idle(rq, next, true, true);
 	schedstat_inc(rq->sched_goidle);
 	next->se.exec_start = rq_clock_task(rq);
 }
 
 struct task_struct *pick_task_idle(struct rq *rq)
 {
-	scx_update_idle(rq, true, false);
+	scx_update_idle(rq, NULL, true, false);
 	return rq->idle;
 }
 
-- 
2.17.1

                 reply	other threads:[~2025-06-10  7:51 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=ff3aa51349414f169cd550f25b245c38@honor.com \
    --to=liuwenfang@honor.com \
    --cc=arighi@nvidia.com \
    --cc=bsegall@google.com \
    --cc=changwoo@igalia.com \
    --cc=dietmar.eggemann@arm.com \
    --cc=juri.lelli@redhat.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mgorman@suse.de \
    --cc=mingo@redhat.com \
    --cc=peterz@infradead.org \
    --cc=rostedt@goodmis.org \
    --cc=tj@kernel.org \
    --cc=vincent.guittot@linaro.org \
    --cc=void@manifault.com \
    --cc=vschneid@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox