All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v3 0/1] wait_task_inactive() spend too much time on system startup
@ 2020-03-06  7:01 cl
  2020-03-06  7:01 ` [PATCH v3 1/1] kthread: do not preempt current task if it is going to call schedule() cl
  0 siblings, 1 reply; 7+ messages in thread
From: cl @ 2020-03-06  7:01 UTC (permalink / raw)
  To: heiko
  Cc: mingo, peterz, juri.lelli, vincent.guittot, dietmar.eggemann,
	rostedt, bsegall, mgorman, akpm, tglx, mpe, surenb, ben.dooks,
	anshuman.khandual, catalin.marinas, will, keescook, luto, wad,
	mark.rutland, geert+renesas, george_davis, sudeep.holla, linux,
	gregkh, info, kstewart, allison, linux-arm-kernel, linux-kernel,
	huangtao, Liang Chen

From: Liang Chen <cl@rock-chips.com>

Changelog:
v1: wait_task_inactive() frequently call schedule_hrtimeout() and spend a lot of time,
i am trying to optimize it on rockchip platform.
v2: Use atomic_flags(PFA) instead of TIF flag, and add some comments.
v3: Use a new method fix this issue to make the code simple.

Liang Chen (1):
  kthread: do not preempt current task if it is going to call schedule()

 kernel/kthread.c | 17 +++++++++++++++--
 1 file changed, 15 insertions(+), 2 deletions(-)

-- 
2.17.1




^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH v3 1/1] kthread: do not preempt current task if it is going to call schedule()
  2020-03-06  7:01 [PATCH v3 0/1] wait_task_inactive() spend too much time on system startup cl
@ 2020-03-06  7:01 ` cl
  2020-03-06 17:09     ` Steven Rostedt
                     ` (2 more replies)
  0 siblings, 3 replies; 7+ messages in thread
From: cl @ 2020-03-06  7:01 UTC (permalink / raw)
  To: heiko
  Cc: mingo, peterz, juri.lelli, vincent.guittot, dietmar.eggemann,
	rostedt, bsegall, mgorman, akpm, tglx, mpe, surenb, ben.dooks,
	anshuman.khandual, catalin.marinas, will, keescook, luto, wad,
	mark.rutland, geert+renesas, george_davis, sudeep.holla, linux,
	gregkh, info, kstewart, allison, linux-arm-kernel, linux-kernel,
	huangtao, Liang Chen

From: Liang Chen <cl@rock-chips.com>

when we create a kthread with ktrhead_create_on_cpu(),the child thread
entry is ktread.c:ktrhead() which will be preempted by the parent after
call complete(done) while schedule() is not called yet,then the parent
will call wait_task_inactive(child) but the child is still on the runqueue,
so the parent will schedule_hrtimeout() for 1 jiffy,it will waste a lot of
time,especially on startup.

  parent                             child
ktrhead_create_on_cpu()
  wait_fo_completion(&done) -----> ktread.c:ktrhead()
                             |----- complete(done);--wakeup and preempted by parent
 kthread_bind() <------------|  |-> schedule();--dequeue here
  wait_task_inactive(child)     |
   schedule_hrtimeout(1 jiffy) -|

So we hope the child just wakeup parent but not preempted by parent, and the
child is going to call schedule() soon,then the parent will not call
schedule_hrtimeout(1 jiffy) as the child is already dequeue.

The same issue for ktrhead_park()&&kthread_parkme().
This patch can save 120ms on rk312x startup with CONFIG_HZ=300.

Signed-off-by: Liang Chen <cl@rock-chips.com>
---
 kernel/kthread.c | 17 +++++++++++++++--
 1 file changed, 15 insertions(+), 2 deletions(-)

diff --git a/kernel/kthread.c b/kernel/kthread.c
index b262f47046ca..bfbfa481be3a 100644
--- a/kernel/kthread.c
+++ b/kernel/kthread.c
@@ -199,8 +199,15 @@ static void __kthread_parkme(struct kthread *self)
 		if (!test_bit(KTHREAD_SHOULD_PARK, &self->flags))
 			break;
 
+		/*
+		 * Thread is going to call schedule(), do not preempt it,
+		 * or the caller of kthread_park() may spend more time in
+		 * wait_task_inactive().
+		 */
+		preempt_disable();
 		complete(&self->parked);
-		schedule();
+		schedule_preempt_disabled();
+		preempt_enable();
 	}
 	__set_current_state(TASK_RUNNING);
 }
@@ -245,8 +252,14 @@ static int kthread(void *_create)
 	/* OK, tell user we're spawned, wait for stop or wakeup */
 	__set_current_state(TASK_UNINTERRUPTIBLE);
 	create->result = current;
+	/*
+	 * Thread is going to call schedule(), do not preempt it,
+	 * or the creator may spend more time in wait_task_inactive().
+	 */
+	preempt_disable();
 	complete(done);
-	schedule();
+	schedule_preempt_disabled();
+	preempt_enable();
 
 	ret = -EINTR;
 	if (!test_bit(KTHREAD_SHOULD_STOP, &self->flags)) {
-- 
2.17.1




^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: [PATCH v3 1/1] kthread: do not preempt current task if it is going to call schedule()
  2020-03-06  7:01 ` [PATCH v3 1/1] kthread: do not preempt current task if it is going to call schedule() cl
@ 2020-03-06 17:09     ` Steven Rostedt
  2020-03-11 15:39     ` Peter Zijlstra
  2020-03-20 12:58   ` [tip: sched/core] kthread: Do " tip-bot2 for Liang Chen
  2 siblings, 0 replies; 7+ messages in thread
From: Steven Rostedt @ 2020-03-06 17:09 UTC (permalink / raw)
  To: cl
  Cc: heiko, mingo, peterz, juri.lelli, vincent.guittot,
	dietmar.eggemann, bsegall, mgorman, akpm, tglx, mpe, surenb,
	ben.dooks, anshuman.khandual, catalin.marinas, will, keescook,
	luto, wad, mark.rutland, geert+renesas, george_davis,
	sudeep.holla, linux, gregkh, info, kstewart, allison,
	linux-arm-kernel, linux-kernel, huangtao

On Fri,  6 Mar 2020 15:01:33 +0800
<cl@rock-chips.com> wrote:

> From: Liang Chen <cl@rock-chips.com>
> 
> when we create a kthread with ktrhead_create_on_cpu(),the child thread
> entry is ktread.c:ktrhead() which will be preempted by the parent after
> call complete(done) while schedule() is not called yet,then the parent
> will call wait_task_inactive(child) but the child is still on the runqueue,
> so the parent will schedule_hrtimeout() for 1 jiffy,it will waste a lot of
> time,especially on startup.
> 
>   parent                             child
> ktrhead_create_on_cpu()
>   wait_fo_completion(&done) -----> ktread.c:ktrhead()
>                              |----- complete(done);--wakeup and preempted by parent
>  kthread_bind() <------------|  |-> schedule();--dequeue here
>   wait_task_inactive(child)     |
>    schedule_hrtimeout(1 jiffy) -|
> 
> So we hope the child just wakeup parent but not preempted by parent, and the
> child is going to call schedule() soon,then the parent will not call
> schedule_hrtimeout(1 jiffy) as the child is already dequeue.
> 
> The same issue for ktrhead_park()&&kthread_parkme().
> This patch can save 120ms on rk312x startup with CONFIG_HZ=300.
> 
> Signed-off-by: Liang Chen <cl@rock-chips.com>
> ---
>  kernel/kthread.c | 17 +++++++++++++++--
>  1 file changed, 15 insertions(+), 2 deletions(-)
> 
> diff --git a/kernel/kthread.c b/kernel/kthread.c
> index b262f47046ca..bfbfa481be3a 100644
> --- a/kernel/kthread.c
> +++ b/kernel/kthread.c
> @@ -199,8 +199,15 @@ static void __kthread_parkme(struct kthread *self)
>  		if (!test_bit(KTHREAD_SHOULD_PARK, &self->flags))
>  			break;
>  
> +		/*
> +		 * Thread is going to call schedule(), do not preempt it,
> +		 * or the caller of kthread_park() may spend more time in
> +		 * wait_task_inactive().
> +		 */
> +		preempt_disable();
>  		complete(&self->parked);

I first was concerned that this could break PREEMPT_RT, as complete() calls
spin_locks() which are turned into sleeping locks when PREEMPT_RT is
enabled. But looking at the latest PREEMPT_RT patch, it appears that it
converts the locks in complete() into raw_spin_locks (and using swake).

I don't see any other issue with this patch.

Reviewed-by: Steven Rostedt (VMware) <rostedt@goodmis.org>

-- Steve

> -		schedule();
> +		schedule_preempt_disabled();
> +		preempt_enable();
>  	}
>  	__set_current_state(TASK_RUNNING);
>  }
> @@ -245,8 +252,14 @@ static int kthread(void *_create)
>  	/* OK, tell user we're spawned, wait for stop or wakeup */
>  	__set_current_state(TASK_UNINTERRUPTIBLE);
>  	create->result = current;
> +	/*
> +	 * Thread is going to call schedule(), do not preempt it,
> +	 * or the creator may spend more time in wait_task_inactive().
> +	 */
> +	preempt_disable();
>  	complete(done);
> -	schedule();
> +	schedule_preempt_disabled();
> +	preempt_enable();
>  
>  	ret = -EINTR;
>  	if (!test_bit(KTHREAD_SHOULD_STOP, &self->flags)) {


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH v3 1/1] kthread: do not preempt current task if it is going to call schedule()
@ 2020-03-06 17:09     ` Steven Rostedt
  0 siblings, 0 replies; 7+ messages in thread
From: Steven Rostedt @ 2020-03-06 17:09 UTC (permalink / raw)
  To: cl
  Cc: juri.lelli, mark.rutland, heiko, geert+renesas, peterz,
	catalin.marinas, bsegall, will, mpe, linux, dietmar.eggemann,
	ben.dooks, mgorman, huangtao, keescook, anshuman.khandual, tglx,
	surenb, mingo, allison, linux-arm-kernel, wad, gregkh,
	linux-kernel, luto, george_davis, sudeep.holla, akpm, info,
	kstewart

On Fri,  6 Mar 2020 15:01:33 +0800
<cl@rock-chips.com> wrote:

> From: Liang Chen <cl@rock-chips.com>
> 
> when we create a kthread with ktrhead_create_on_cpu(),the child thread
> entry is ktread.c:ktrhead() which will be preempted by the parent after
> call complete(done) while schedule() is not called yet,then the parent
> will call wait_task_inactive(child) but the child is still on the runqueue,
> so the parent will schedule_hrtimeout() for 1 jiffy,it will waste a lot of
> time,especially on startup.
> 
>   parent                             child
> ktrhead_create_on_cpu()
>   wait_fo_completion(&done) -----> ktread.c:ktrhead()
>                              |----- complete(done);--wakeup and preempted by parent
>  kthread_bind() <------------|  |-> schedule();--dequeue here
>   wait_task_inactive(child)     |
>    schedule_hrtimeout(1 jiffy) -|
> 
> So we hope the child just wakeup parent but not preempted by parent, and the
> child is going to call schedule() soon,then the parent will not call
> schedule_hrtimeout(1 jiffy) as the child is already dequeue.
> 
> The same issue for ktrhead_park()&&kthread_parkme().
> This patch can save 120ms on rk312x startup with CONFIG_HZ=300.
> 
> Signed-off-by: Liang Chen <cl@rock-chips.com>
> ---
>  kernel/kthread.c | 17 +++++++++++++++--
>  1 file changed, 15 insertions(+), 2 deletions(-)
> 
> diff --git a/kernel/kthread.c b/kernel/kthread.c
> index b262f47046ca..bfbfa481be3a 100644
> --- a/kernel/kthread.c
> +++ b/kernel/kthread.c
> @@ -199,8 +199,15 @@ static void __kthread_parkme(struct kthread *self)
>  		if (!test_bit(KTHREAD_SHOULD_PARK, &self->flags))
>  			break;
>  
> +		/*
> +		 * Thread is going to call schedule(), do not preempt it,
> +		 * or the caller of kthread_park() may spend more time in
> +		 * wait_task_inactive().
> +		 */
> +		preempt_disable();
>  		complete(&self->parked);

I first was concerned that this could break PREEMPT_RT, as complete() calls
spin_locks() which are turned into sleeping locks when PREEMPT_RT is
enabled. But looking at the latest PREEMPT_RT patch, it appears that it
converts the locks in complete() into raw_spin_locks (and using swake).

I don't see any other issue with this patch.

Reviewed-by: Steven Rostedt (VMware) <rostedt@goodmis.org>

-- Steve

> -		schedule();
> +		schedule_preempt_disabled();
> +		preempt_enable();
>  	}
>  	__set_current_state(TASK_RUNNING);
>  }
> @@ -245,8 +252,14 @@ static int kthread(void *_create)
>  	/* OK, tell user we're spawned, wait for stop or wakeup */
>  	__set_current_state(TASK_UNINTERRUPTIBLE);
>  	create->result = current;
> +	/*
> +	 * Thread is going to call schedule(), do not preempt it,
> +	 * or the creator may spend more time in wait_task_inactive().
> +	 */
> +	preempt_disable();
>  	complete(done);
> -	schedule();
> +	schedule_preempt_disabled();
> +	preempt_enable();
>  
>  	ret = -EINTR;
>  	if (!test_bit(KTHREAD_SHOULD_STOP, &self->flags)) {


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH v3 1/1] kthread: do not preempt current task if it is going to call schedule()
  2020-03-06  7:01 ` [PATCH v3 1/1] kthread: do not preempt current task if it is going to call schedule() cl
@ 2020-03-11 15:39     ` Peter Zijlstra
  2020-03-11 15:39     ` Peter Zijlstra
  2020-03-20 12:58   ` [tip: sched/core] kthread: Do " tip-bot2 for Liang Chen
  2 siblings, 0 replies; 7+ messages in thread
From: Peter Zijlstra @ 2020-03-11 15:39 UTC (permalink / raw)
  To: cl
  Cc: heiko, mingo, juri.lelli, vincent.guittot, dietmar.eggemann,
	rostedt, bsegall, mgorman, akpm, tglx, mpe, surenb, ben.dooks,
	anshuman.khandual, catalin.marinas, will, keescook, luto, wad,
	mark.rutland, geert+renesas, george_davis, sudeep.holla, linux,
	gregkh, info, kstewart, allison, linux-arm-kernel, linux-kernel,
	huangtao

On Fri, Mar 06, 2020 at 03:01:33PM +0800, cl@rock-chips.com wrote:
> From: Liang Chen <cl@rock-chips.com>
> 
> when we create a kthread with ktrhead_create_on_cpu(),the child thread
> entry is ktread.c:ktrhead() which will be preempted by the parent after
> call complete(done) while schedule() is not called yet,then the parent
> will call wait_task_inactive(child) but the child is still on the runqueue,
> so the parent will schedule_hrtimeout() for 1 jiffy,it will waste a lot of
> time,especially on startup.
> 
>   parent                             child
> ktrhead_create_on_cpu()
>   wait_fo_completion(&done) -----> ktread.c:ktrhead()
>                              |----- complete(done);--wakeup and preempted by parent
>  kthread_bind() <------------|  |-> schedule();--dequeue here
>   wait_task_inactive(child)     |
>    schedule_hrtimeout(1 jiffy) -|
> 
> So we hope the child just wakeup parent but not preempted by parent, and the
> child is going to call schedule() soon,then the parent will not call
> schedule_hrtimeout(1 jiffy) as the child is already dequeue.
> 
> The same issue for ktrhead_park()&&kthread_parkme().
> This patch can save 120ms on rk312x startup with CONFIG_HZ=300.
> 
> Signed-off-by: Liang Chen <cl@rock-chips.com>

Thanks!


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH v3 1/1] kthread: do not preempt current task if it is going to call schedule()
@ 2020-03-11 15:39     ` Peter Zijlstra
  0 siblings, 0 replies; 7+ messages in thread
From: Peter Zijlstra @ 2020-03-11 15:39 UTC (permalink / raw)
  To: cl
  Cc: juri.lelli, mark.rutland, heiko, geert+renesas, catalin.marinas,
	bsegall, will, mpe, linux, dietmar.eggemann, ben.dooks, mgorman,
	huangtao, keescook, anshuman.khandual, rostedt, tglx, surenb,
	mingo, allison, linux-arm-kernel, wad, gregkh, linux-kernel,
	luto, george_davis, sudeep.holla, akpm, info, kstewart

On Fri, Mar 06, 2020 at 03:01:33PM +0800, cl@rock-chips.com wrote:
> From: Liang Chen <cl@rock-chips.com>
> 
> when we create a kthread with ktrhead_create_on_cpu(),the child thread
> entry is ktread.c:ktrhead() which will be preempted by the parent after
> call complete(done) while schedule() is not called yet,then the parent
> will call wait_task_inactive(child) but the child is still on the runqueue,
> so the parent will schedule_hrtimeout() for 1 jiffy,it will waste a lot of
> time,especially on startup.
> 
>   parent                             child
> ktrhead_create_on_cpu()
>   wait_fo_completion(&done) -----> ktread.c:ktrhead()
>                              |----- complete(done);--wakeup and preempted by parent
>  kthread_bind() <------------|  |-> schedule();--dequeue here
>   wait_task_inactive(child)     |
>    schedule_hrtimeout(1 jiffy) -|
> 
> So we hope the child just wakeup parent but not preempted by parent, and the
> child is going to call schedule() soon,then the parent will not call
> schedule_hrtimeout(1 jiffy) as the child is already dequeue.
> 
> The same issue for ktrhead_park()&&kthread_parkme().
> This patch can save 120ms on rk312x startup with CONFIG_HZ=300.
> 
> Signed-off-by: Liang Chen <cl@rock-chips.com>

Thanks!

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [tip: sched/core] kthread: Do not preempt current task if it is going to call schedule()
  2020-03-06  7:01 ` [PATCH v3 1/1] kthread: do not preempt current task if it is going to call schedule() cl
  2020-03-06 17:09     ` Steven Rostedt
  2020-03-11 15:39     ` Peter Zijlstra
@ 2020-03-20 12:58   ` tip-bot2 for Liang Chen
  2 siblings, 0 replies; 7+ messages in thread
From: tip-bot2 for Liang Chen @ 2020-03-20 12:58 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: Liang Chen, Peter Zijlstra (Intel), Steven Rostedt (VMware), x86, LKML

The following commit has been merged into the sched/core branch of tip:

Commit-ID:     26c7295be0c5e6da3fa45970e9748be983175b1b
Gitweb:        https://git.kernel.org/tip/26c7295be0c5e6da3fa45970e9748be983175b1b
Author:        Liang Chen <cl@rock-chips.com>
AuthorDate:    Fri, 06 Mar 2020 15:01:33 +08:00
Committer:     Peter Zijlstra <peterz@infradead.org>
CommitterDate: Fri, 20 Mar 2020 13:06:20 +01:00

kthread: Do not preempt current task if it is going to call schedule()

when we create a kthread with ktrhead_create_on_cpu(),the child thread
entry is ktread.c:ktrhead() which will be preempted by the parent after
call complete(done) while schedule() is not called yet,then the parent
will call wait_task_inactive(child) but the child is still on the runqueue,
so the parent will schedule_hrtimeout() for 1 jiffy,it will waste a lot of
time,especially on startup.

  parent                             child
ktrhead_create_on_cpu()
  wait_fo_completion(&done) -----> ktread.c:ktrhead()
                             |----- complete(done);--wakeup and preempted by parent
 kthread_bind() <------------|  |-> schedule();--dequeue here
  wait_task_inactive(child)     |
   schedule_hrtimeout(1 jiffy) -|

So we hope the child just wakeup parent but not preempted by parent, and the
child is going to call schedule() soon,then the parent will not call
schedule_hrtimeout(1 jiffy) as the child is already dequeue.

The same issue for ktrhead_park()&&kthread_parkme().
This patch can save 120ms on rk312x startup with CONFIG_HZ=300.

Signed-off-by: Liang Chen <cl@rock-chips.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Reviewed-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
Link: https://lkml.kernel.org/r/20200306070133.18335-2-cl@rock-chips.com
---
 kernel/kthread.c | 17 +++++++++++++++--
 1 file changed, 15 insertions(+), 2 deletions(-)

diff --git a/kernel/kthread.c b/kernel/kthread.c
index b262f47..bfbfa48 100644
--- a/kernel/kthread.c
+++ b/kernel/kthread.c
@@ -199,8 +199,15 @@ static void __kthread_parkme(struct kthread *self)
 		if (!test_bit(KTHREAD_SHOULD_PARK, &self->flags))
 			break;
 
+		/*
+		 * Thread is going to call schedule(), do not preempt it,
+		 * or the caller of kthread_park() may spend more time in
+		 * wait_task_inactive().
+		 */
+		preempt_disable();
 		complete(&self->parked);
-		schedule();
+		schedule_preempt_disabled();
+		preempt_enable();
 	}
 	__set_current_state(TASK_RUNNING);
 }
@@ -245,8 +252,14 @@ static int kthread(void *_create)
 	/* OK, tell user we're spawned, wait for stop or wakeup */
 	__set_current_state(TASK_UNINTERRUPTIBLE);
 	create->result = current;
+	/*
+	 * Thread is going to call schedule(), do not preempt it,
+	 * or the creator may spend more time in wait_task_inactive().
+	 */
+	preempt_disable();
 	complete(done);
-	schedule();
+	schedule_preempt_disabled();
+	preempt_enable();
 
 	ret = -EINTR;
 	if (!test_bit(KTHREAD_SHOULD_STOP, &self->flags)) {

^ permalink raw reply related	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2020-03-20 12:58 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-03-06  7:01 [PATCH v3 0/1] wait_task_inactive() spend too much time on system startup cl
2020-03-06  7:01 ` [PATCH v3 1/1] kthread: do not preempt current task if it is going to call schedule() cl
2020-03-06 17:09   ` Steven Rostedt
2020-03-06 17:09     ` Steven Rostedt
2020-03-11 15:39   ` Peter Zijlstra
2020-03-11 15:39     ` Peter Zijlstra
2020-03-20 12:58   ` [tip: sched/core] kthread: Do " tip-bot2 for Liang Chen

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.