Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > linux.kernel > #1369009 > unrolled thread

[PATCH RESEND] smp: make wake up idle cpus more generic

Started byLianwei Wang <lianwei.wang@gmail.com>
First post2016-04-01 08:00 +0200
Last post2016-04-02 15:20 +0200
Articles 4 — 3 participants

Back to article view | Back to linux.kernel


Contents

  [PATCH RESEND] smp: make wake up idle cpus more generic Lianwei Wang <lianwei.wang@gmail.com> - 2016-04-01 08:00 +0200
    Re: [PATCH RESEND] smp: make wake up idle cpus more generic Ingo Molnar <mingo@kernel.org> - 2016-04-01 09:10 +0200
      Re: [PATCH RESEND] smp: make wake up idle cpus more generic Lianwei Wang <lianwei.wang@gmail.com> - 2016-04-02 08:20 +0200
        Re: [PATCH RESEND] smp: make wake up idle cpus more generic Daniel Lezcano <daniel.lezcano@linaro.org> - 2016-04-02 15:20 +0200

#1369009 — [PATCH RESEND] smp: make wake up idle cpus more generic

FromLianwei Wang <lianwei.wang@gmail.com>
Date2016-04-01 08:00 +0200
Subject[PATCH RESEND] smp: make wake up idle cpus more generic
Message-ID<rj0hH-8nZ-5@gated-at.bofh.it>
The wake_up_all_idle_cpus API always wake up all the online
cpus, but sometimes we only want to wake up a set of cpus.

Use a generic function to wake up a group of cpus that is
specified by the cpumask parameter. This generic API can
benefit to the cases that only need to wake up a set of
cpus.

Signed-off-by: Lianwei Wang <lianwei.wang@gmail.com>
---
 drivers/cpuidle/cpuidle.c |  4 ++--
 include/linux/smp.h       |  4 ++--
 kernel/power/suspend.c    |  2 +-
 kernel/smp.c              | 12 +++++++-----
 4 files changed, 12 insertions(+), 10 deletions(-)

diff --git a/drivers/cpuidle/cpuidle.c b/drivers/cpuidle/cpuidle.c
index f996efc56605..c2a85c89e276 100644
--- a/drivers/cpuidle/cpuidle.c
+++ b/drivers/cpuidle/cpuidle.c
@@ -301,7 +301,7 @@ void cpuidle_uninstall_idle_handler(void)
 {
 	if (enabled_devices) {
 		initialized = 0;
-		wake_up_all_idle_cpus();
+		wake_up_idle_cpus(cpu_online_mask);
 	}
 
 	/*
@@ -620,7 +620,7 @@ EXPORT_SYMBOL_GPL(cpuidle_register);
 static int cpuidle_latency_notify(struct notifier_block *b,
 		unsigned long l, void *v)
 {
-	wake_up_all_idle_cpus();
+	wake_up_idle_cpus(cpu_online_mask);
 	return NOTIFY_OK;
 }
 
diff --git a/include/linux/smp.h b/include/linux/smp.h
index c4414074bd88..ee9d087c4c9a 100644
--- a/include/linux/smp.h
+++ b/include/linux/smp.h
@@ -100,7 +100,7 @@ int smp_call_function_any(const struct cpumask *mask,
 			  smp_call_func_t func, void *info, int wait);
 
 void kick_all_cpus_sync(void);
-void wake_up_all_idle_cpus(void);
+void wake_up_idle_cpus(const struct cpumask *mask);
 
 /*
  * Generic and arch helpers
@@ -149,7 +149,7 @@ smp_call_function_any(const struct cpumask *mask, smp_call_func_t func,
 }
 
 static inline void kick_all_cpus_sync(void) {  }
-static inline void wake_up_all_idle_cpus(void) {  }
+static inline void wake_up_idle_cpus(const struct cpumask *mask) {  }
 
 #ifdef CONFIG_UP_LATE_INIT
 extern void __init up_late_init(void);
diff --git a/kernel/power/suspend.c b/kernel/power/suspend.c
index 5b70d64b871e..a4176ab96b36 100644
--- a/kernel/power/suspend.c
+++ b/kernel/power/suspend.c
@@ -70,7 +70,7 @@ static void freeze_enter(void)
 	cpuidle_resume();
 
 	/* Push all the CPUs into the idle loop. */
-	wake_up_all_idle_cpus();
+	wake_up_idle_cpus(cpu_online_mask);
 	pr_debug("PM: suspend-to-idle\n");
 	/* Make the current CPU wait so it can enter the idle loop too. */
 	wait_event(suspend_freeze_wait_head,
diff --git a/kernel/smp.c b/kernel/smp.c
index 74165443c240..c2beecb5ef01 100644
--- a/kernel/smp.c
+++ b/kernel/smp.c
@@ -720,17 +720,19 @@ void kick_all_cpus_sync(void)
 EXPORT_SYMBOL_GPL(kick_all_cpus_sync);
 
 /**
- * wake_up_all_idle_cpus - break all cpus out of idle
- * wake_up_all_idle_cpus try to break all cpus which is in idle state even
+ * wake_up_idle_cpus - break a set of cpus out of idle
+ * @mask: The set of cpus to break out of idle
+ *
+ * wake_up_idle_cpus try to break a set of cpus which is in idle state even
  * including idle polling cpus, for non-idle cpus, we will do nothing
  * for them.
  */
-void wake_up_all_idle_cpus(void)
+void wake_up_idle_cpus(const struct cpumask *mask)
 {
 	int cpu;
 
 	preempt_disable();
-	for_each_online_cpu(cpu) {
+	for_each_cpu_and(cpu, mask, cpu_online_mask) {
 		if (cpu == smp_processor_id())
 			continue;
 
@@ -738,4 +740,4 @@ void wake_up_all_idle_cpus(void)
 	}
 	preempt_enable();
 }
-EXPORT_SYMBOL_GPL(wake_up_all_idle_cpus);
+EXPORT_SYMBOL_GPL(wake_up_idle_cpus);
-- 
1.9.1

[toc] | [next] | [standalone]


#1369038

FromIngo Molnar <mingo@kernel.org>
Date2016-04-01 09:10 +0200
Message-ID<rj1ns-TH-11@gated-at.bofh.it>
In reply to#1369009
* Lianwei Wang <lianwei.wang@gmail.com> wrote:

> The wake_up_all_idle_cpus API always wake up all the online
> cpus, but sometimes we only want to wake up a set of cpus.
> 
> Use a generic function to wake up a group of cpus that is
> specified by the cpumask parameter. This generic API can
> benefit to the cases that only need to wake up a set of
> cpus.

What is the new user of this new argument to the wake-up call?

Thanks,

	Ingo

[toc] | [prev] | [next] | [standalone]


#1369876

FromLianwei Wang <lianwei.wang@gmail.com>
Date2016-04-02 08:20 +0200
Message-ID<rjn4C-83d-3@gated-at.bofh.it>
In reply to#1369038
>
> * Lianwei Wang <lianwei.wang@gmail.com> wrote:
>
>> The wake_up_all_idle_cpus API always wake up all the online
>> cpus, but sometimes we only want to wake up a set of cpus.
>> Use a generic function to wake up a group of cpus that is
>> specified by the cpumask parameter. This generic API can
>> benefit to the cases that only need to wake up a set of
>> cpus.
>
> What is the new user of this new argument to the wake-up call?
>
> Thanks,
>
>         Ingo

The ARM big.LITTLE arch is one of the users to use the new wake up
call. Two clusters in these SoCs and each cluster has 2 or more CPUs.
For some cases, we only need to wake up the cpus on one cluster, not
all the cpus. The other cluster can keep in idle state to save power.
Another use case is that for the threads/irqs that bind to some cpus,
we also want to wake up the cpus that the threads/irqs bind to, and
the other cpus can stay in idle state. I'm updating the pm_qos code to
support binding the request to a set of cpus, and the
cpuidle_latency_notify call can pass the cpumask parameter to the new
wake-up call.

Maybe someone else can find new user to play with the generic wake-up
call in the future.

Thanks,
Lianwei

[toc] | [prev] | [next] | [standalone]


#1369943

FromDaniel Lezcano <daniel.lezcano@linaro.org>
Date2016-04-02 15:20 +0200
Message-ID<rjtD4-4c7-3@gated-at.bofh.it>
In reply to#1369876
On 04/02/2016 08:15 AM, Lianwei Wang wrote:
>>
>> * Lianwei Wang <lianwei.wang@gmail.com> wrote:
>>
>>> The wake_up_all_idle_cpus API always wake up all the online
>>> cpus, but sometimes we only want to wake up a set of cpus.
>>> Use a generic function to wake up a group of cpus that is
>>> specified by the cpumask parameter. This generic API can
>>> benefit to the cases that only need to wake up a set of
>>> cpus.
>>
>> What is the new user of this new argument to the wake-up call?
>>
>> Thanks,
>>
>>          Ingo
>
> The ARM big.LITTLE arch is one of the users to use the new wake up
> call. Two clusters in these SoCs and each cluster has 2 or more CPUs.
> For some cases, we only need to wake up the cpus on one cluster, not
> all the cpus. The other cluster can keep in idle state to save power.
> Another use case is that for the threads/irqs that bind to some cpus,
> we also want to wake up the cpus that the threads/irqs bind to, and
> the other cpus can stay in idle state. I'm updating the pm_qos code to
> support binding the request to a set of cpus, and the
> cpuidle_latency_notify call can pass the cpumask parameter to the new
> wake-up call.

Hi Lianwei,

a quick suggestion : cpuidle_driver->cpumask

   -- Daniel


-- 
  <http://www.linaro.org/> Linaro.org │ Open source software for ARM SoCs

Follow Linaro:  <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog

[toc] | [prev] | [standalone]


Back to top | Article view | linux.kernel


csiph-web