[PATCH v7 10/23] sched: Split out __sched() deactivate task logic into a helper

John Stultz posted 23 patches 1 year, 12 months ago
[PATCH v7 10/23] sched: Split out __sched() deactivate task logic into a helper
Posted by John Stultz 1 year, 12 months ago
As we're going to re-use the deactivation logic,
split it into a helper.

Cc: Joel Fernandes <joelaf@google.com>
Cc: Qais Yousef <qyousef@google.com>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Juri Lelli <juri.lelli@redhat.com>
Cc: Vincent Guittot <vincent.guittot@linaro.org>
Cc: Dietmar Eggemann <dietmar.eggemann@arm.com>
Cc: Valentin Schneider <vschneid@redhat.com>
Cc: Steven Rostedt <rostedt@goodmis.org>
Cc: Ben Segall <bsegall@google.com>
Cc: Zimuzo Ezeozue <zezeozue@google.com>
Cc: Youssef Esmat <youssefesmat@google.com>
Cc: Mel Gorman <mgorman@suse.de>
Cc: Daniel Bristot de Oliveira <bristot@redhat.com>
Cc: Will Deacon <will@kernel.org>
Cc: Waiman Long <longman@redhat.com>
Cc: Boqun Feng <boqun.feng@gmail.com>
Cc: "Paul E. McKenney" <paulmck@kernel.org>
Cc: Metin Kaya <Metin.Kaya@arm.com>
Cc: Xuewen Yan <xuewen.yan94@gmail.com>
Cc: K Prateek Nayak <kprateek.nayak@amd.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: kernel-team@android.com
Signed-off-by: John Stultz <jstultz@google.com>
---
v6:
* Define function as static to avoid "no previous prototype"
  warnings as Reported-by: kernel test robot <lkp@intel.com>
v7:
* Rename state task_state to be more clear, as suggested by
  Metin Kaya
---
 kernel/sched/core.c | 66 +++++++++++++++++++++++++--------------------
 1 file changed, 37 insertions(+), 29 deletions(-)

diff --git a/kernel/sched/core.c b/kernel/sched/core.c
index 0ce34f5c0e0c..34acd80b6bd0 100644
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -6571,6 +6571,42 @@ pick_next_task(struct rq *rq, struct task_struct *prev, struct rq_flags *rf)
 # define SM_MASK_PREEMPT	SM_PREEMPT
 #endif
 
+static bool try_to_deactivate_task(struct rq *rq, struct task_struct *p,
+				   unsigned long task_state)
+{
+	if (signal_pending_state(task_state, p)) {
+		WRITE_ONCE(p->__state, TASK_RUNNING);
+	} else {
+		p->sched_contributes_to_load =
+			(task_state & TASK_UNINTERRUPTIBLE) &&
+			!(task_state & TASK_NOLOAD) &&
+			!(task_state & TASK_FROZEN);
+
+		if (p->sched_contributes_to_load)
+			rq->nr_uninterruptible++;
+
+		/*
+		 * __schedule()			ttwu()
+		 *   prev_state = prev->state;    if (p->on_rq && ...)
+		 *   if (prev_state)		    goto out;
+		 *     p->on_rq = 0;		  smp_acquire__after_ctrl_dep();
+		 *				  p->state = TASK_WAKING
+		 *
+		 * Where __schedule() and ttwu() have matching control dependencies.
+		 *
+		 * After this, schedule() must not care about p->state any more.
+		 */
+		deactivate_task(rq, p, DEQUEUE_SLEEP | DEQUEUE_NOCLOCK);
+
+		if (p->in_iowait) {
+			atomic_inc(&rq->nr_iowait);
+			delayacct_blkio_start();
+		}
+		return true;
+	}
+	return false;
+}
+
 /*
  * __schedule() is the main scheduler function.
  *
@@ -6662,35 +6698,7 @@ static void __sched notrace __schedule(unsigned int sched_mode)
 	 */
 	prev_state = READ_ONCE(prev->__state);
 	if (!(sched_mode & SM_MASK_PREEMPT) && prev_state) {
-		if (signal_pending_state(prev_state, prev)) {
-			WRITE_ONCE(prev->__state, TASK_RUNNING);
-		} else {
-			prev->sched_contributes_to_load =
-				(prev_state & TASK_UNINTERRUPTIBLE) &&
-				!(prev_state & TASK_NOLOAD) &&
-				!(prev_state & TASK_FROZEN);
-
-			if (prev->sched_contributes_to_load)
-				rq->nr_uninterruptible++;
-
-			/*
-			 * __schedule()			ttwu()
-			 *   prev_state = prev->state;    if (p->on_rq && ...)
-			 *   if (prev_state)		    goto out;
-			 *     p->on_rq = 0;		  smp_acquire__after_ctrl_dep();
-			 *				  p->state = TASK_WAKING
-			 *
-			 * Where __schedule() and ttwu() have matching control dependencies.
-			 *
-			 * After this, schedule() must not care about p->state any more.
-			 */
-			deactivate_task(rq, prev, DEQUEUE_SLEEP | DEQUEUE_NOCLOCK);
-
-			if (prev->in_iowait) {
-				atomic_inc(&rq->nr_iowait);
-				delayacct_blkio_start();
-			}
-		}
+		try_to_deactivate_task(rq, prev, prev_state);
 		switch_count = &prev->nvcsw;
 	}
 
-- 
2.43.0.472.g3155946c3a-goog
Re: [PATCH v7 10/23] sched: Split out __sched() deactivate task logic into a helper
Posted by Metin Kaya 1 year, 12 months ago
On 20/12/2023 12:18 am, John Stultz wrote:
> As we're going to re-use the deactivation logic,
> split it into a helper.
> 
> Cc: Joel Fernandes <joelaf@google.com>
> Cc: Qais Yousef <qyousef@google.com>
> Cc: Ingo Molnar <mingo@redhat.com>
> Cc: Peter Zijlstra <peterz@infradead.org>
> Cc: Juri Lelli <juri.lelli@redhat.com>
> Cc: Vincent Guittot <vincent.guittot@linaro.org>
> Cc: Dietmar Eggemann <dietmar.eggemann@arm.com>
> Cc: Valentin Schneider <vschneid@redhat.com>
> Cc: Steven Rostedt <rostedt@goodmis.org>
> Cc: Ben Segall <bsegall@google.com>
> Cc: Zimuzo Ezeozue <zezeozue@google.com>
> Cc: Youssef Esmat <youssefesmat@google.com>
> Cc: Mel Gorman <mgorman@suse.de>
> Cc: Daniel Bristot de Oliveira <bristot@redhat.com>
> Cc: Will Deacon <will@kernel.org>
> Cc: Waiman Long <longman@redhat.com>
> Cc: Boqun Feng <boqun.feng@gmail.com>
> Cc: "Paul E. McKenney" <paulmck@kernel.org>
> Cc: Metin Kaya <Metin.Kaya@arm.com>
> Cc: Xuewen Yan <xuewen.yan94@gmail.com>
> Cc: K Prateek Nayak <kprateek.nayak@amd.com>
> Cc: Thomas Gleixner <tglx@linutronix.de>
> Cc: kernel-team@android.com
> Signed-off-by: John Stultz <jstultz@google.com>
> ---
> v6:
> * Define function as static to avoid "no previous prototype"
>    warnings as Reported-by: kernel test robot <lkp@intel.com>
> v7:
> * Rename state task_state to be more clear, as suggested by
>    Metin Kaya
> ---
>   kernel/sched/core.c | 66 +++++++++++++++++++++++++--------------------
>   1 file changed, 37 insertions(+), 29 deletions(-)
> 
> diff --git a/kernel/sched/core.c b/kernel/sched/core.c
> index 0ce34f5c0e0c..34acd80b6bd0 100644
> --- a/kernel/sched/core.c
> +++ b/kernel/sched/core.c
> @@ -6571,6 +6571,42 @@ pick_next_task(struct rq *rq, struct task_struct *prev, struct rq_flags *rf)
>   # define SM_MASK_PREEMPT	SM_PREEMPT
>   #endif
>   

* Better to have a comment (e.g., in which conditions 
try_to_deactivate_task() returns true or false) here.

* try_to_deactivate_task() is temporarily used by 2 commits in the patch 
set (i.e., it's only called by __schedule() just like in this patch at 
the end of the series). However, it's nice to make that big 
__scheduler() function a bit modular as we discussed off-list. So, 
should we move this function out of the Proxy Execution patch set to get 
it merged independently?

> +static bool try_to_deactivate_task(struct rq *rq, struct task_struct *p,
> +				   unsigned long task_state)
> +{
> +	if (signal_pending_state(task_state, p)) {
> +		WRITE_ONCE(p->__state, TASK_RUNNING);
> +	} else {
> +		p->sched_contributes_to_load =
> +			(task_state & TASK_UNINTERRUPTIBLE) &&
> +			!(task_state & TASK_NOLOAD) &&
> +			!(task_state & TASK_FROZEN);
> +
> +		if (p->sched_contributes_to_load)
> +			rq->nr_uninterruptible++;
> +
> +		/*
> +		 * __schedule()			ttwu()
> +		 *   prev_state = prev->state;    if (p->on_rq && ...)
> +		 *   if (prev_state)		    goto out;
> +		 *     p->on_rq = 0;		  smp_acquire__after_ctrl_dep();
> +		 *				  p->state = TASK_WAKING
> +		 *
> +		 * Where __schedule() and ttwu() have matching control dependencies.
> +		 *
> +		 * After this, schedule() must not care about p->state any more.
> +		 */
> +		deactivate_task(rq, p, DEQUEUE_SLEEP | DEQUEUE_NOCLOCK);
> +
> +		if (p->in_iowait) {
> +			atomic_inc(&rq->nr_iowait);
> +			delayacct_blkio_start();
> +		}
> +		return true;
> +	}
> +	return false;
> +}
> +
>   /*
>    * __schedule() is the main scheduler function.
>    *
> @@ -6662,35 +6698,7 @@ static void __sched notrace __schedule(unsigned int sched_mode)
>   	 */
>   	prev_state = READ_ONCE(prev->__state);
>   	if (!(sched_mode & SM_MASK_PREEMPT) && prev_state) {
> -		if (signal_pending_state(prev_state, prev)) {
> -			WRITE_ONCE(prev->__state, TASK_RUNNING);
> -		} else {
> -			prev->sched_contributes_to_load =
> -				(prev_state & TASK_UNINTERRUPTIBLE) &&
> -				!(prev_state & TASK_NOLOAD) &&
> -				!(prev_state & TASK_FROZEN);
> -
> -			if (prev->sched_contributes_to_load)
> -				rq->nr_uninterruptible++;
> -
> -			/*
> -			 * __schedule()			ttwu()
> -			 *   prev_state = prev->state;    if (p->on_rq && ...)
> -			 *   if (prev_state)		    goto out;
> -			 *     p->on_rq = 0;		  smp_acquire__after_ctrl_dep();
> -			 *				  p->state = TASK_WAKING
> -			 *
> -			 * Where __schedule() and ttwu() have matching control dependencies.
> -			 *
> -			 * After this, schedule() must not care about p->state any more.
> -			 */
> -			deactivate_task(rq, prev, DEQUEUE_SLEEP | DEQUEUE_NOCLOCK);
> -
> -			if (prev->in_iowait) {
> -				atomic_inc(&rq->nr_iowait);
> -				delayacct_blkio_start();
> -			}
> -		}
> +		try_to_deactivate_task(rq, prev, prev_state);
>   		switch_count = &prev->nvcsw;
>   	}
>
Re: [PATCH v7 10/23] sched: Split out __sched() deactivate task logic into a helper
Posted by John Stultz 1 year, 12 months ago
On Thu, Dec 21, 2023 at 4:30 AM Metin Kaya <metin.kaya@arm.com> wrote:
>
> On 20/12/2023 12:18 am, John Stultz wrote:
> > As we're going to re-use the deactivation logic,
> > split it into a helper.
> >
>
> * Better to have a comment (e.g., in which conditions
> try_to_deactivate_task() returns true or false) here.

Ah, good point. I've added a comment to address this.

> * try_to_deactivate_task() is temporarily used by 2 commits in the patch
> set (i.e., it's only called by __schedule() just like in this patch at
> the end of the series). However, it's nice to make that big
> __scheduler() function a bit modular as we discussed off-list. So,
> should we move this function out of the Proxy Execution patch set to get
> it merged independently?

Yeah. I add and later remove the proxy_deactivate() function as it
goes unused, but I am thinking about keeping it to handle the case
where if the blocked on chains are too long, and we're spending too
much time re-running find_proxy_task() - where we should probably just
deactivate the selected task and move on.  But for now, you're right.

The suggestion of just the initial step of splitting the logic out
(probably make it a void function because the remaining usage in
__schedule() doesn't care about the result) is a good one, so I'll
rework it this way and send it separately (along with other early
patches Qais suggested).

thanks
-john