linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v2] sched/fair: Optimize select_idle_cpu
@ 2019-12-13  2:45 Cheng Jian
  2019-12-13  5:13 ` Srikar Dronamraju
                   ` (3 more replies)
  0 siblings, 4 replies; 5+ messages in thread
From: Cheng Jian @ 2019-12-13  2:45 UTC (permalink / raw)
  To: mingo, peterz, linux-kernel
  Cc: cj.chengjian, chenwandun, xiexiuqi, liwei391, huawei.libin,
	bobo.shaobowang, juri.lelli, vincent.guittot

select_idle_cpu() will scan the LLC domain for idle CPUs,
it's always expensive. so the next commit :

	1ad3aaf3fcd2 ("sched/core: Implement new approach to scale select_idle_cpu()")

introduces a way to limit how many CPUs we scan.

But it consume some CPUs out of 'nr' that are not allowed
for the task and thus waste our attempts. The function
always return nr_cpumask_bits, and we can't find a CPU
which our task is allowed to run.

Cpumask may be too big, similar to select_idle_core(), use
per_cpu_ptr 'select_idle_mask' to prevent stack overflow.

Fixes: 1ad3aaf3fcd2 ("sched/core: Implement new approach to scale select_idle_cpu()")
Signed-off-by: Cheng Jian <cj.chengjian@huawei.com>
---
 kernel/sched/fair.c | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
index 08a233e97a01..d48244388ce9 100644
--- a/kernel/sched/fair.c
+++ b/kernel/sched/fair.c
@@ -5828,6 +5828,7 @@ static inline int select_idle_smt(struct task_struct *p, int target)
  */
 static int select_idle_cpu(struct task_struct *p, struct sched_domain *sd, int target)
 {
+	struct cpumask *cpus = this_cpu_cpumask_var_ptr(select_idle_mask);
 	struct sched_domain *this_sd;
 	u64 avg_cost, avg_idle;
 	u64 time, cost;
@@ -5859,11 +5860,11 @@ static int select_idle_cpu(struct task_struct *p, struct sched_domain *sd, int t
 
 	time = cpu_clock(this);
 
-	for_each_cpu_wrap(cpu, sched_domain_span(sd), target) {
+	cpumask_and(cpus, sched_domain_span(sd), p->cpus_ptr);
+
+	for_each_cpu_wrap(cpu, cpus, target) {
 		if (!--nr)
 			return si_cpu;
-		if (!cpumask_test_cpu(cpu, p->cpus_ptr))
-			continue;
 		if (available_idle_cpu(cpu))
 			break;
 		if (si_cpu == -1 && sched_idle_cpu(cpu))
-- 
2.20.1


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

* Re: [PATCH v2] sched/fair: Optimize select_idle_cpu
  2019-12-13  2:45 [PATCH v2] sched/fair: Optimize select_idle_cpu Cheng Jian
@ 2019-12-13  5:13 ` Srikar Dronamraju
  2019-12-13  8:37 ` Vincent Guittot
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 5+ messages in thread
From: Srikar Dronamraju @ 2019-12-13  5:13 UTC (permalink / raw)
  To: Cheng Jian
  Cc: mingo, peterz, linux-kernel, chenwandun, xiexiuqi, liwei391,
	huawei.libin, bobo.shaobowang, juri.lelli, vincent.guittot

* Cheng Jian <cj.chengjian@huawei.com> [2019-12-13 10:45:30]:

> Fixes: 1ad3aaf3fcd2 ("sched/core: Implement new approach to scale select_idle_cpu()")
> Signed-off-by: Cheng Jian <cj.chengjian@huawei.com>
> ---
>  kernel/sched/fair.c | 7 ++++---
>  1 file changed, 4 insertions(+), 3 deletions(-)
> 
> diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
> index 08a233e97a01..d48244388ce9 100644
> --- a/kernel/sched/fair.c
> +++ b/kernel/sched/fair.c
> @@ -5828,6 +5828,7 @@ static inline int select_idle_smt(struct task_struct *p, int target)
>   */
>  static int select_idle_cpu(struct task_struct *p, struct sched_domain *sd, int target)
>  {
> +	struct cpumask *cpus = this_cpu_cpumask_var_ptr(select_idle_mask);
>  	struct sched_domain *this_sd;
>  	u64 avg_cost, avg_idle;
>  	u64 time, cost;
> @@ -5859,11 +5860,11 @@ static int select_idle_cpu(struct task_struct *p, struct sched_domain *sd, int t
>  
>  	time = cpu_clock(this);
>  
> -	for_each_cpu_wrap(cpu, sched_domain_span(sd), target) {
> +	cpumask_and(cpus, sched_domain_span(sd), p->cpus_ptr);
> +
> +	for_each_cpu_wrap(cpu, cpus, target) {
>  		if (!--nr)
>  			return si_cpu;
> -		if (!cpumask_test_cpu(cpu, p->cpus_ptr))
> -			continue;
>  		if (available_idle_cpu(cpu))
>  			break;
>  		if (si_cpu == -1 && sched_idle_cpu(cpu))
Looks good to me.

Reviewed-by: Srikar Dronamraju <srikar@linux.vnet.ibm.com>

-- 
Thanks and Regards
Srikar Dronamraju


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

* Re: [PATCH v2] sched/fair: Optimize select_idle_cpu
  2019-12-13  2:45 [PATCH v2] sched/fair: Optimize select_idle_cpu Cheng Jian
  2019-12-13  5:13 ` Srikar Dronamraju
@ 2019-12-13  8:37 ` Vincent Guittot
  2019-12-13 11:48 ` Valentin Schneider
  2019-12-17 12:39 ` [tip: sched/core] " tip-bot2 for Cheng Jian
  3 siblings, 0 replies; 5+ messages in thread
From: Vincent Guittot @ 2019-12-13  8:37 UTC (permalink / raw)
  To: Cheng Jian
  Cc: Ingo Molnar, Peter Zijlstra, linux-kernel, chenwandun, Xie XiuQi,
	liwei391, huawei.libin, bobo.shaobowang, Juri Lelli

On Fri, 13 Dec 2019 at 03:48, Cheng Jian <cj.chengjian@huawei.com> wrote:
>
> select_idle_cpu() will scan the LLC domain for idle CPUs,
> it's always expensive. so the next commit :
>
>         1ad3aaf3fcd2 ("sched/core: Implement new approach to scale select_idle_cpu()")
>
> introduces a way to limit how many CPUs we scan.
>
> But it consume some CPUs out of 'nr' that are not allowed
> for the task and thus waste our attempts. The function
> always return nr_cpumask_bits, and we can't find a CPU
> which our task is allowed to run.
>
> Cpumask may be too big, similar to select_idle_core(), use
> per_cpu_ptr 'select_idle_mask' to prevent stack overflow.
>
> Fixes: 1ad3aaf3fcd2 ("sched/core: Implement new approach to scale select_idle_cpu()")
> Signed-off-by: Cheng Jian <cj.chengjian@huawei.com>

Reviewed-by: Vincent Guittot <vincent.guittot@linaro.org>

> ---
>  kernel/sched/fair.c | 7 ++++---
>  1 file changed, 4 insertions(+), 3 deletions(-)
>
> diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
> index 08a233e97a01..d48244388ce9 100644
> --- a/kernel/sched/fair.c
> +++ b/kernel/sched/fair.c
> @@ -5828,6 +5828,7 @@ static inline int select_idle_smt(struct task_struct *p, int target)
>   */
>  static int select_idle_cpu(struct task_struct *p, struct sched_domain *sd, int target)
>  {
> +       struct cpumask *cpus = this_cpu_cpumask_var_ptr(select_idle_mask);
>         struct sched_domain *this_sd;
>         u64 avg_cost, avg_idle;
>         u64 time, cost;
> @@ -5859,11 +5860,11 @@ static int select_idle_cpu(struct task_struct *p, struct sched_domain *sd, int t
>
>         time = cpu_clock(this);
>
> -       for_each_cpu_wrap(cpu, sched_domain_span(sd), target) {
> +       cpumask_and(cpus, sched_domain_span(sd), p->cpus_ptr);
> +
> +       for_each_cpu_wrap(cpu, cpus, target) {
>                 if (!--nr)
>                         return si_cpu;
> -               if (!cpumask_test_cpu(cpu, p->cpus_ptr))
> -                       continue;
>                 if (available_idle_cpu(cpu))
>                         break;
>                 if (si_cpu == -1 && sched_idle_cpu(cpu))
> --
> 2.20.1
>

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

* Re: [PATCH v2] sched/fair: Optimize select_idle_cpu
  2019-12-13  2:45 [PATCH v2] sched/fair: Optimize select_idle_cpu Cheng Jian
  2019-12-13  5:13 ` Srikar Dronamraju
  2019-12-13  8:37 ` Vincent Guittot
@ 2019-12-13 11:48 ` Valentin Schneider
  2019-12-17 12:39 ` [tip: sched/core] " tip-bot2 for Cheng Jian
  3 siblings, 0 replies; 5+ messages in thread
From: Valentin Schneider @ 2019-12-13 11:48 UTC (permalink / raw)
  To: Cheng Jian, mingo, peterz, linux-kernel
  Cc: chenwandun, xiexiuqi, liwei391, huawei.libin, bobo.shaobowang,
	juri.lelli, vincent.guittot

On 13/12/2019 02:45, Cheng Jian wrote:
> select_idle_cpu() will scan the LLC domain for idle CPUs,
> it's always expensive. so the next commit :
> 
> 	1ad3aaf3fcd2 ("sched/core: Implement new approach to scale select_idle_cpu()")
> 
> introduces a way to limit how many CPUs we scan.
> 
> But it consume some CPUs out of 'nr' that are not allowed
> for the task and thus waste our attempts. The function
> always return nr_cpumask_bits, and we can't find a CPU
> which our task is allowed to run.
> 
> Cpumask may be too big, similar to select_idle_core(), use
> per_cpu_ptr 'select_idle_mask' to prevent stack overflow.
> 
> Fixes: 1ad3aaf3fcd2 ("sched/core: Implement new approach to scale select_idle_cpu()")
> Signed-off-by: Cheng Jian <cj.chengjian@huawei.com>

Reviewed-by: Valentin Schneider <valentin.schneider@arm.com>

> ---
>  kernel/sched/fair.c | 7 ++++---
>  1 file changed, 4 insertions(+), 3 deletions(-)
> 
> diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
> index 08a233e97a01..d48244388ce9 100644
> --- a/kernel/sched/fair.c
> +++ b/kernel/sched/fair.c
> @@ -5828,6 +5828,7 @@ static inline int select_idle_smt(struct task_struct *p, int target)
>   */
>  static int select_idle_cpu(struct task_struct *p, struct sched_domain *sd, int target)
>  {
> +	struct cpumask *cpus = this_cpu_cpumask_var_ptr(select_idle_mask);
>  	struct sched_domain *this_sd;
>  	u64 avg_cost, avg_idle;
>  	u64 time, cost;
> @@ -5859,11 +5860,11 @@ static int select_idle_cpu(struct task_struct *p, struct sched_domain *sd, int t
>  
>  	time = cpu_clock(this);
>  
> -	for_each_cpu_wrap(cpu, sched_domain_span(sd), target) {
> +	cpumask_and(cpus, sched_domain_span(sd), p->cpus_ptr);
> +
> +	for_each_cpu_wrap(cpu, cpus, target) {
>  		if (!--nr)
>  			return si_cpu;
> -		if (!cpumask_test_cpu(cpu, p->cpus_ptr))
> -			continue;
>  		if (available_idle_cpu(cpu))
>  			break;
>  		if (si_cpu == -1 && sched_idle_cpu(cpu))
> 

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

* [tip: sched/core] sched/fair: Optimize select_idle_cpu
  2019-12-13  2:45 [PATCH v2] sched/fair: Optimize select_idle_cpu Cheng Jian
                   ` (2 preceding siblings ...)
  2019-12-13 11:48 ` Valentin Schneider
@ 2019-12-17 12:39 ` tip-bot2 for Cheng Jian
  3 siblings, 0 replies; 5+ messages in thread
From: tip-bot2 for Cheng Jian @ 2019-12-17 12:39 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: Cheng Jian, Peter Zijlstra (Intel),
	Srikar Dronamraju, Vincent Guittot, Valentin Schneider, x86,
	LKML

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

Commit-ID:     60588bfa223ff675b95f866249f90616613fbe31
Gitweb:        https://git.kernel.org/tip/60588bfa223ff675b95f866249f90616613fbe31
Author:        Cheng Jian <cj.chengjian@huawei.com>
AuthorDate:    Fri, 13 Dec 2019 10:45:30 +08:00
Committer:     Peter Zijlstra <peterz@infradead.org>
CommitterDate: Tue, 17 Dec 2019 13:32:51 +01:00

sched/fair: Optimize select_idle_cpu

select_idle_cpu() will scan the LLC domain for idle CPUs,
it's always expensive. so the next commit :

	1ad3aaf3fcd2 ("sched/core: Implement new approach to scale select_idle_cpu()")

introduces a way to limit how many CPUs we scan.

But it consume some CPUs out of 'nr' that are not allowed
for the task and thus waste our attempts. The function
always return nr_cpumask_bits, and we can't find a CPU
which our task is allowed to run.

Cpumask may be too big, similar to select_idle_core(), use
per_cpu_ptr 'select_idle_mask' to prevent stack overflow.

Fixes: 1ad3aaf3fcd2 ("sched/core: Implement new approach to scale select_idle_cpu()")
Signed-off-by: Cheng Jian <cj.chengjian@huawei.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Reviewed-by: Srikar Dronamraju <srikar@linux.vnet.ibm.com>
Reviewed-by: Vincent Guittot <vincent.guittot@linaro.org>
Reviewed-by: Valentin Schneider <valentin.schneider@arm.com>
Link: https://lkml.kernel.org/r/20191213024530.28052-1-cj.chengjian@huawei.com
---
 kernel/sched/fair.c | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
index 846f50b..280d54c 100644
--- a/kernel/sched/fair.c
+++ b/kernel/sched/fair.c
@@ -5828,6 +5828,7 @@ static inline int select_idle_smt(struct task_struct *p, int target)
  */
 static int select_idle_cpu(struct task_struct *p, struct sched_domain *sd, int target)
 {
+	struct cpumask *cpus = this_cpu_cpumask_var_ptr(select_idle_mask);
 	struct sched_domain *this_sd;
 	u64 avg_cost, avg_idle;
 	u64 time, cost;
@@ -5859,11 +5860,11 @@ static int select_idle_cpu(struct task_struct *p, struct sched_domain *sd, int t
 
 	time = cpu_clock(this);
 
-	for_each_cpu_wrap(cpu, sched_domain_span(sd), target) {
+	cpumask_and(cpus, sched_domain_span(sd), p->cpus_ptr);
+
+	for_each_cpu_wrap(cpu, cpus, target) {
 		if (!--nr)
 			return si_cpu;
-		if (!cpumask_test_cpu(cpu, p->cpus_ptr))
-			continue;
 		if (available_idle_cpu(cpu))
 			break;
 		if (si_cpu == -1 && sched_idle_cpu(cpu))

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

end of thread, other threads:[~2019-12-17 12:40 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-12-13  2:45 [PATCH v2] sched/fair: Optimize select_idle_cpu Cheng Jian
2019-12-13  5:13 ` Srikar Dronamraju
2019-12-13  8:37 ` Vincent Guittot
2019-12-13 11:48 ` Valentin Schneider
2019-12-17 12:39 ` [tip: sched/core] " tip-bot2 for Cheng Jian

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).