mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Kayra Cizmeci <kayracizmeci@gmail.com>
To: Peter Zijlstra <peterz@infradead.org>
Cc: mingo@kernel.org, linux-kernel@vger.kernel.org,
	juri.lelli@redhat.com,  vincent.guittot@linaro.org,
	dietmar.eggemann@arm.com, rostedt@goodmis.org,
	 bsegall@google.com, mgorman@suse.de, vschneid@redhat.com,
	kprateek.nayak@amd.com,  joshdon@google.com, tj@kernel.org,
	jakub@okonski.org
Subject: Re: [RFC][PATCH 3/3] sched/eevdf: Fix sched idle task group preemption
Date: Thu, 5 Nov 2026 23:10:43 +0300	[thread overview]
Message-ID: <auzW7Y9T4dwxa0DS@scheduler.schedules> (raw)
In-Reply-To: <20261105170157.765325702@infradead.org>

On Thu, Nov 05, 2026 at 05:55:28PM +0100, Peter Zijlstra wrote:
> From: Vincent Guittot <vincent.guittot@linaro.org>
> 
> Even with flat hierarchy which puts all runnable tasks in the same cfs rq,
> we need to parse the hierarchy to check for sched_idle task group.
> 
> Fixes: 85570f10a4c6 ("sched/eevdf: Move to a single runqueue")
> Reported-by: Jakub Okoński <jakub@okonski.org>
> Signed-off-by: Vincent Guittot <vincent.guittot@linaro.org>
> Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
> Link: https://lore.kernel.org/all/58dc8e8a-7260-43ce-aebb-8d9c29a6afc9@okonski.org/
> Link: https://patch.msgid.link/20261019182622.1584454-1-vincent.guittot@linaro.org
> ---
> 
> Changes since v1:
> - fix prototype and cleanup unsued variable
> 
>  kernel/sched/fair.c |   87 ++++++++++++++++++++++++++++++++++++++++++++--------
>  1 file changed, 74 insertions(+), 13 deletions(-)
> 
> --- a/kernel/sched/fair.c
> +++ b/kernel/sched/fair.c
> @@ -433,6 +433,38 @@ static inline struct sched_entity *paren
>  	return se->parent;
>  }
>  
> +static void
> +find_matching_se(struct sched_entity **se, struct sched_entity **pse)
> +{
> +	int se_depth, pse_depth;
> +
> +	/*
> +	 * preemption test can be made between sibling entities who are in the
> +	 * same cfs_rq i.e who have a common parent. Walk up the hierarchy of
> +	 * both tasks until we find their ancestors who are siblings of common
> +	 * parent.
> +	 */
> +
> +	/* First walk up until both entities are at same depth */
> +	se_depth = (*se)->depth;
> +	pse_depth = (*pse)->depth;
> +
> +	while (se_depth > pse_depth) {
> +		se_depth--;
> +		*se = parent_entity(*se);
> +	}
> +
> +	while (pse_depth > se_depth) {
> +		pse_depth--;
> +		*pse = parent_entity(*pse);
> +	}
> +
> +	while (!is_same_group(*se, *pse)) {
> +		*se = parent_entity(*se);
> +		*pse = parent_entity(*pse);
> +	}
> +}
> +
>  static int tg_is_idle(struct task_group *tg)
>  {
>  	return tg->idle > 0;
> @@ -476,6 +508,11 @@ static inline struct sched_entity *paren
>  	return NULL;
>  }
>  
> +static inline void
> +find_matching_se(struct sched_entity **se, struct sched_entity **pse)
> +{
> +}
> +
>  static inline int tg_is_idle(struct task_group *tg)
>  {
>  	return 0;
> @@ -10130,7 +10167,40 @@ preempt_sync(struct rq *rq, int wake_fla
>  }
>  
>  /*
> - * Preempt the current task with a newly woken task if needed:
> + * Preempt an idle entity in favor of a non-idle entity (and don't preempt
> + * in the inverse case).
> + */
> +static inline enum preempt_wakeup_action
> +wakeup_preempt_sched_idle(struct sched_entity *cse, struct sched_entity *pse)
> +{
> +	int cse_is_idle, pse_is_idle;
> +
> +	cse_is_idle = se_is_idle(cse);
> +	pse_is_idle = se_is_idle(pse);
> +
> +	if (cse_is_idle || pse_is_idle) {

We pass tasks to wakeup_preempt_sched_idle() (below) so this
se_is_idle() would just look to policy.

So even if they are in a idle group, if they don't have idle policy
themselves it just returns false.


Or am I getting something wrong?


> +		find_matching_se(&cse, &pse);
> +		WARN_ON_ONCE(!pse);
> +
> +		cse_is_idle = se_is_idle(cse);
> +		pse_is_idle = se_is_idle(pse);


Look here:

    ROOT
      |
     GA*
     /\
    /  \
   GB  GC*
   |    |
   TA   TB

Normally in the old code if TB is waking and TA is running we wouldn't
preempt TA. But because se_is_idle() returns true if idle is bigger than
0, both GB and GC is considered the same (if my other issue is true,
walk doesn't even starts so we don't come even come here)

Is this knowingly like this?

> +
> +		/*
> +		 * Preempt an idle entity in favor of a non-idle entity (and
> +		 * don't preempt in the inverse case).
> +		 */
> +		if (cse_is_idle && !pse_is_idle)
> +			return PREEMPT_WAKEUP_RESCHED;
> +
> +		if (cse_is_idle != pse_is_idle)
> +			return PREEMPT_WAKEUP_NONE;
> +	}
> +
> +	return PREEMPT_WAKEUP_PICK;
> +}
> +
> +/*
> + * Preempt the current task with a newly woken task if needed.
>   */
>  static void wakeup_preempt_fair(struct rq *rq, struct task_struct *p, int wake_flags)
>  {
> @@ -10138,7 +10208,6 @@ static void wakeup_preempt_fair(struct r
>  	struct task_struct *donor = rq->donor;
>  	struct sched_entity *nse, *se = &donor->se, *pse = &p->se;
>  	struct cfs_rq *cfs_rq = &rq->cfs;
> -	int cse_is_idle, pse_is_idle;
>  
>  	/*
>  	 * XXX Getting preempted by higher class, try and find idle CPU?
> @@ -10175,22 +10244,14 @@ static void wakeup_preempt_fair(struct r
>  	if (!sched_feat(WAKEUP_PREEMPTION))
>  		return;
>  
> -	WARN_ON_ONCE(!pse);
> -
> -	cse_is_idle = se_is_idle(se);
> -	pse_is_idle = se_is_idle(pse);
> +	preempt_action = wakeup_preempt_sched_idle(se, pse);
>  
> -	nse = se;
> -	/*
> -	 * Preempt an idle entity in favor of a non-idle entity (and don't preempt
> -	 * in the inverse case).
> -	 */
> -	if (cse_is_idle && !pse_is_idle)
> +	if (preempt_action == PREEMPT_WAKEUP_RESCHED)
>  		goto preempt;
>  
>  	update_curr_fair(rq);
>  
> -	if (cse_is_idle != pse_is_idle)
> +	if (preempt_action == PREEMPT_WAKEUP_NONE)
>  		goto update;
>  
>  	/*
> 
> 


Cheers,

Kayra

      reply	other threads:[~2026-11-05 20:10 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-11-05 16:55 [PATCH 0/3] sched/fair: Fix cgroup::idle preemption Peter Zijlstra
2026-11-05 16:55 ` [PATCH 1/3] sched/fair: Use guard in sched_group_set_idle() Peter Zijlstra
2026-11-05 17:42   ` Kayra Cizmeci
2026-11-05 16:55 ` [PATCH 2/3] sched/fair: Make cfs_rq::idle the sum of ancestor tg::idle Peter Zijlstra
2026-11-05 19:20   ` Kayra Cizmeci
2026-11-05 16:55 ` [RFC][PATCH 3/3] sched/eevdf: Fix sched idle task group preemption Peter Zijlstra
2026-11-05 20:10   ` Kayra Cizmeci [this message]

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=auzW7Y9T4dwxa0DS@scheduler.schedules \
    --to=kayracizmeci@gmail.com \
    --cc=bsegall@google.com \
    --cc=dietmar.eggemann@arm.com \
    --cc=jakub@okonski.org \
    --cc=joshdon@google.com \
    --cc=juri.lelli@redhat.com \
    --cc=kprateek.nayak@amd.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mgorman@suse.de \
    --cc=mingo@kernel.org \
    --cc=peterz@infradead.org \
    --cc=rostedt@goodmis.org \
    --cc=tj@kernel.org \
    --cc=vincent.guittot@linaro.org \
    --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

all inboxes | Powered by JetHome®