From: Colin Cross <ccross@android.com>
To: linux-kernel@vger.kernel.org
Cc: Kevin Hilman <khilman@ti.com>, Len Brown <len.brown@intel.com>,
Russell King <linux@arm.linux.org.uk>,
Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
Kay Sievers <kay.sievers@vrfy.org>,
Amit Kucheria <amit.kucheria@linaro.org>,
Colin Cross <ccross@android.com>,
linux-pm@lists.linux-foundation.org,
Arjan van de Ven <arjan@linux.intel.com>,
Arnd Bergmann <arnd.bergmann@linaro.org>,
linux-arm-kernel@lists.infradead.org
Subject: [PATCHv4 4/4] cpuidle: coupled: add parallel barrier function
Date: Mon, 7 May 2012 17:57:42 -0700 [thread overview]
Message-ID: <1336438662-10484-5-git-send-email-ccross@android.com> (raw)
In-Reply-To: <1336438662-10484-1-git-send-email-ccross@android.com>
Adds cpuidle_coupled_parallel_barrier, which can be used by coupled
cpuidle state enter functions to handle resynchronization after
determining if any cpu needs to abort. The normal use case will
be:
static bool abort_flag;
static atomic_t abort_barrier;
int arch_cpuidle_enter(struct cpuidle_device *dev, ...)
{
if (arch_turn_off_irq_controller()) {
/* returns an error if an irq is pending and would be lost
if idle continued and turned off power */
abort_flag = true;
}
cpuidle_coupled_parallel_barrier(dev, &abort_barrier);
if (abort_flag) {
/* One of the cpus didn't turn off it's irq controller */
arch_turn_on_irq_controller();
return -EINTR;
}
/* continue with idle */
...
}
This will cause all cpus to abort idle together if one of them needs
to abort.
Reviewed-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
Tested-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
Reviewed-by: Kevin Hilman <khilman@ti.com>
Tested-by: Kevin Hilman <khilman@ti.com>
Signed-off-by: Colin Cross <ccross@android.com>
---
drivers/cpuidle/coupled.c | 37 +++++++++++++++++++++++++++++++++++++
include/linux/cpuidle.h | 4 ++++
2 files changed, 41 insertions(+), 0 deletions(-)
diff --git a/drivers/cpuidle/coupled.c b/drivers/cpuidle/coupled.c
index 93101fb..3e65de1 100644
--- a/drivers/cpuidle/coupled.c
+++ b/drivers/cpuidle/coupled.c
@@ -130,6 +130,43 @@ struct cpuidle_coupled {
static cpumask_t cpuidle_coupled_poked_mask;
/**
+ * cpuidle_coupled_parallel_barrier - synchronize all online coupled cpus
+ * @dev: cpuidle_device of the calling cpu
+ * @a: atomic variable to hold the barrier
+ *
+ * No caller to this function will return from this function until all online
+ * cpus in the same coupled group have called this function. Once any caller
+ * has returned from this function, the barrier is immediately available for
+ * reuse.
+ *
+ * The atomic variable a must be initialized to 0 before any cpu calls
+ * this function, will be reset to 0 before any cpu returns from this function.
+ *
+ * Must only be called from within a coupled idle state handler
+ * (state.enter when state.flags has CPUIDLE_FLAG_COUPLED set).
+ *
+ * Provides full smp barrier semantics before and after calling.
+ */
+void cpuidle_coupled_parallel_barrier(struct cpuidle_device *dev, atomic_t *a)
+{
+ int n = dev->coupled->online_count;
+
+ smp_mb__before_atomic_inc();
+ atomic_inc(a);
+
+ while (atomic_read(a) < n)
+ cpu_relax();
+
+ if (atomic_inc_return(a) == n * 2) {
+ atomic_set(a, 0);
+ return;
+ }
+
+ while (atomic_read(a) > n)
+ cpu_relax();
+}
+
+/**
* cpuidle_state_is_coupled - check if a state is part of a coupled set
* @dev: struct cpuidle_device for the current cpu
* @drv: struct cpuidle_driver for the platform
diff --git a/include/linux/cpuidle.h b/include/linux/cpuidle.h
index 6038448..5ab7183 100644
--- a/include/linux/cpuidle.h
+++ b/include/linux/cpuidle.h
@@ -183,6 +183,10 @@ static inline int cpuidle_wrap_enter(struct cpuidle_device *dev,
#endif
+#ifdef CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED
+void cpuidle_coupled_parallel_barrier(struct cpuidle_device *dev, atomic_t *a);
+#endif
+
/******************************
* CPUIDLE GOVERNOR INTERFACE *
******************************/
--
1.7.7.3
WARNING: multiple messages have this Message-ID (diff)
From: ccross@android.com (Colin Cross)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCHv4 4/4] cpuidle: coupled: add parallel barrier function
Date: Mon, 7 May 2012 17:57:42 -0700 [thread overview]
Message-ID: <1336438662-10484-5-git-send-email-ccross@android.com> (raw)
In-Reply-To: <1336438662-10484-1-git-send-email-ccross@android.com>
Adds cpuidle_coupled_parallel_barrier, which can be used by coupled
cpuidle state enter functions to handle resynchronization after
determining if any cpu needs to abort. The normal use case will
be:
static bool abort_flag;
static atomic_t abort_barrier;
int arch_cpuidle_enter(struct cpuidle_device *dev, ...)
{
if (arch_turn_off_irq_controller()) {
/* returns an error if an irq is pending and would be lost
if idle continued and turned off power */
abort_flag = true;
}
cpuidle_coupled_parallel_barrier(dev, &abort_barrier);
if (abort_flag) {
/* One of the cpus didn't turn off it's irq controller */
arch_turn_on_irq_controller();
return -EINTR;
}
/* continue with idle */
...
}
This will cause all cpus to abort idle together if one of them needs
to abort.
Reviewed-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
Tested-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
Reviewed-by: Kevin Hilman <khilman@ti.com>
Tested-by: Kevin Hilman <khilman@ti.com>
Signed-off-by: Colin Cross <ccross@android.com>
---
drivers/cpuidle/coupled.c | 37 +++++++++++++++++++++++++++++++++++++
include/linux/cpuidle.h | 4 ++++
2 files changed, 41 insertions(+), 0 deletions(-)
diff --git a/drivers/cpuidle/coupled.c b/drivers/cpuidle/coupled.c
index 93101fb..3e65de1 100644
--- a/drivers/cpuidle/coupled.c
+++ b/drivers/cpuidle/coupled.c
@@ -130,6 +130,43 @@ struct cpuidle_coupled {
static cpumask_t cpuidle_coupled_poked_mask;
/**
+ * cpuidle_coupled_parallel_barrier - synchronize all online coupled cpus
+ * @dev: cpuidle_device of the calling cpu
+ * @a: atomic variable to hold the barrier
+ *
+ * No caller to this function will return from this function until all online
+ * cpus in the same coupled group have called this function. Once any caller
+ * has returned from this function, the barrier is immediately available for
+ * reuse.
+ *
+ * The atomic variable a must be initialized to 0 before any cpu calls
+ * this function, will be reset to 0 before any cpu returns from this function.
+ *
+ * Must only be called from within a coupled idle state handler
+ * (state.enter when state.flags has CPUIDLE_FLAG_COUPLED set).
+ *
+ * Provides full smp barrier semantics before and after calling.
+ */
+void cpuidle_coupled_parallel_barrier(struct cpuidle_device *dev, atomic_t *a)
+{
+ int n = dev->coupled->online_count;
+
+ smp_mb__before_atomic_inc();
+ atomic_inc(a);
+
+ while (atomic_read(a) < n)
+ cpu_relax();
+
+ if (atomic_inc_return(a) == n * 2) {
+ atomic_set(a, 0);
+ return;
+ }
+
+ while (atomic_read(a) > n)
+ cpu_relax();
+}
+
+/**
* cpuidle_state_is_coupled - check if a state is part of a coupled set
* @dev: struct cpuidle_device for the current cpu
* @drv: struct cpuidle_driver for the platform
diff --git a/include/linux/cpuidle.h b/include/linux/cpuidle.h
index 6038448..5ab7183 100644
--- a/include/linux/cpuidle.h
+++ b/include/linux/cpuidle.h
@@ -183,6 +183,10 @@ static inline int cpuidle_wrap_enter(struct cpuidle_device *dev,
#endif
+#ifdef CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED
+void cpuidle_coupled_parallel_barrier(struct cpuidle_device *dev, atomic_t *a);
+#endif
+
/******************************
* CPUIDLE GOVERNOR INTERFACE *
******************************/
--
1.7.7.3
WARNING: multiple messages have this Message-ID (diff)
From: Colin Cross <ccross@android.com>
To: linux-kernel@vger.kernel.org
Cc: linux-arm-kernel@lists.infradead.org,
linux-pm@lists.linux-foundation.org,
Kevin Hilman <khilman@ti.com>, Len Brown <len.brown@intel.com>,
Trinabh Gupta <g.trinabh@gmail.com>,
Arjan van de Ven <arjan@linux.intel.com>,
Deepthi Dharwar <deepthi@linux.vnet.ibm.com>,
Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
Kay Sievers <kay.sievers@vrfy.org>,
Santosh Shilimkar <santosh.shilimkar@ti.com>,
Daniel Lezcano <daniel.lezcano@linaro.org>,
Amit Kucheria <amit.kucheria@linaro.org>,
Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>,
Arnd Bergmann <arnd.bergmann@linaro.org>,
Russell King <linux@arm.linux.org.uk>,
"Rafael J. Wysocki" <rjw@sisk.pl>,
Colin Cross <ccross@android.com>
Subject: [PATCHv4 4/4] cpuidle: coupled: add parallel barrier function
Date: Mon, 7 May 2012 17:57:42 -0700 [thread overview]
Message-ID: <1336438662-10484-5-git-send-email-ccross@android.com> (raw)
In-Reply-To: <1336438662-10484-1-git-send-email-ccross@android.com>
Adds cpuidle_coupled_parallel_barrier, which can be used by coupled
cpuidle state enter functions to handle resynchronization after
determining if any cpu needs to abort. The normal use case will
be:
static bool abort_flag;
static atomic_t abort_barrier;
int arch_cpuidle_enter(struct cpuidle_device *dev, ...)
{
if (arch_turn_off_irq_controller()) {
/* returns an error if an irq is pending and would be lost
if idle continued and turned off power */
abort_flag = true;
}
cpuidle_coupled_parallel_barrier(dev, &abort_barrier);
if (abort_flag) {
/* One of the cpus didn't turn off it's irq controller */
arch_turn_on_irq_controller();
return -EINTR;
}
/* continue with idle */
...
}
This will cause all cpus to abort idle together if one of them needs
to abort.
Reviewed-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
Tested-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
Reviewed-by: Kevin Hilman <khilman@ti.com>
Tested-by: Kevin Hilman <khilman@ti.com>
Signed-off-by: Colin Cross <ccross@android.com>
---
drivers/cpuidle/coupled.c | 37 +++++++++++++++++++++++++++++++++++++
include/linux/cpuidle.h | 4 ++++
2 files changed, 41 insertions(+), 0 deletions(-)
diff --git a/drivers/cpuidle/coupled.c b/drivers/cpuidle/coupled.c
index 93101fb..3e65de1 100644
--- a/drivers/cpuidle/coupled.c
+++ b/drivers/cpuidle/coupled.c
@@ -130,6 +130,43 @@ struct cpuidle_coupled {
static cpumask_t cpuidle_coupled_poked_mask;
/**
+ * cpuidle_coupled_parallel_barrier - synchronize all online coupled cpus
+ * @dev: cpuidle_device of the calling cpu
+ * @a: atomic variable to hold the barrier
+ *
+ * No caller to this function will return from this function until all online
+ * cpus in the same coupled group have called this function. Once any caller
+ * has returned from this function, the barrier is immediately available for
+ * reuse.
+ *
+ * The atomic variable a must be initialized to 0 before any cpu calls
+ * this function, will be reset to 0 before any cpu returns from this function.
+ *
+ * Must only be called from within a coupled idle state handler
+ * (state.enter when state.flags has CPUIDLE_FLAG_COUPLED set).
+ *
+ * Provides full smp barrier semantics before and after calling.
+ */
+void cpuidle_coupled_parallel_barrier(struct cpuidle_device *dev, atomic_t *a)
+{
+ int n = dev->coupled->online_count;
+
+ smp_mb__before_atomic_inc();
+ atomic_inc(a);
+
+ while (atomic_read(a) < n)
+ cpu_relax();
+
+ if (atomic_inc_return(a) == n * 2) {
+ atomic_set(a, 0);
+ return;
+ }
+
+ while (atomic_read(a) > n)
+ cpu_relax();
+}
+
+/**
* cpuidle_state_is_coupled - check if a state is part of a coupled set
* @dev: struct cpuidle_device for the current cpu
* @drv: struct cpuidle_driver for the platform
diff --git a/include/linux/cpuidle.h b/include/linux/cpuidle.h
index 6038448..5ab7183 100644
--- a/include/linux/cpuidle.h
+++ b/include/linux/cpuidle.h
@@ -183,6 +183,10 @@ static inline int cpuidle_wrap_enter(struct cpuidle_device *dev,
#endif
+#ifdef CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED
+void cpuidle_coupled_parallel_barrier(struct cpuidle_device *dev, atomic_t *a);
+#endif
+
/******************************
* CPUIDLE GOVERNOR INTERFACE *
******************************/
--
1.7.7.3
next prev parent reply other threads:[~2012-05-08 0:57 UTC|newest]
Thread overview: 44+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-05-08 0:57 [PATCHv3 0/4] coupled cpuidle state support Colin Cross
2012-05-08 0:57 ` Colin Cross
2012-05-08 0:57 ` Colin Cross
2012-05-08 0:57 ` [PATCHv4 1/4] cpuidle: refactor out cpuidle_enter_state Colin Cross
2012-05-08 0:57 ` Colin Cross
2012-05-09 21:03 ` Rafael J. Wysocki
2012-05-09 21:03 ` Rafael J. Wysocki
2012-05-09 21:03 ` Rafael J. Wysocki
2012-05-08 0:57 ` [PATCHv4 2/4] cpuidle: fix error handling in __cpuidle_register_device Colin Cross
2012-05-08 0:57 ` Colin Cross
2012-05-08 0:57 ` Colin Cross
2012-05-09 21:04 ` Rafael J. Wysocki
2012-05-09 21:04 ` Rafael J. Wysocki
2012-05-09 21:04 ` Rafael J. Wysocki
2012-05-08 0:57 ` [PATCHv4 3/4] cpuidle: add support for states that affect multiple cpus Colin Cross
2012-05-08 0:57 ` Colin Cross
2012-05-08 0:57 ` Colin Cross
2012-05-09 21:19 ` Rafael J. Wysocki
2012-05-09 21:19 ` Rafael J. Wysocki
2012-05-09 21:19 ` Rafael J. Wysocki
2012-05-08 0:57 ` Colin Cross [this message]
2012-05-08 0:57 ` [PATCHv4 4/4] cpuidle: coupled: add parallel barrier function Colin Cross
2012-05-08 0:57 ` Colin Cross
2012-05-09 21:31 ` Rafael J. Wysocki
2012-05-09 21:31 ` Rafael J. Wysocki
2012-05-09 21:31 ` Rafael J. Wysocki
2012-05-10 22:47 ` Colin Cross
2012-05-10 22:47 ` Colin Cross
2012-05-10 22:47 ` Colin Cross
2012-05-11 18:32 ` Rafael J. Wysocki
2012-05-11 18:32 ` Rafael J. Wysocki
2012-05-11 18:32 ` Rafael J. Wysocki
2012-05-18 10:36 ` [PATCHv3 0/4] coupled cpuidle state support Santosh Shilimkar
2012-05-18 10:36 ` Santosh Shilimkar
2012-05-18 10:36 ` Santosh Shilimkar
2012-05-18 19:03 ` Rafael J. Wysocki
2012-05-18 19:03 ` Rafael J. Wysocki
2012-05-18 19:03 ` Rafael J. Wysocki
2012-05-18 20:18 ` Colin Cross
2012-05-18 20:18 ` Colin Cross
2012-05-18 20:18 ` Colin Cross
2012-05-19 7:04 ` Shilimkar, Santosh
2012-05-19 7:04 ` Shilimkar, Santosh
2012-05-19 7:04 ` Shilimkar, Santosh
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=1336438662-10484-5-git-send-email-ccross@android.com \
--to=ccross@android.com \
--cc=amit.kucheria@linaro.org \
--cc=arjan@linux.intel.com \
--cc=arnd.bergmann@linaro.org \
--cc=gregkh@linuxfoundation.org \
--cc=kay.sievers@vrfy.org \
--cc=khilman@ti.com \
--cc=len.brown@intel.com \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-pm@lists.linux-foundation.org \
--cc=linux@arm.linux.org.uk \
/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 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.