* [PATCH] add smp_call_function_map and smp_call_function_single
@ 2007-05-02 17:12 Will Schmidt
2007-05-03 0:53 ` Michael Ellerman
0 siblings, 1 reply; 3+ messages in thread
From: Will Schmidt @ 2007-05-02 17:12 UTC (permalink / raw)
To: linuxppc-dev, paulus, anton
Add a new function named smp_call_function_single(). This matches a generic
prototype from include/linux/smp.h.
Add a function smp_call_function_map(). This is, for the most part, a rename
of smp_call_function, with some added cpumask support. smp_call_function and
smp_call_function_single call into smp_call_function_map.
Lightly tested on 970mp (blade), power4 and power5.
Signed-off-by: Will Schmidt <will_schmidt@vnet.ibm.com>
cc: Anton Blanchard <anton@samba.org>
---
arch/powerpc/kernel/smp.c | 73 ++++++++++++++++++++++++++++++++-------------
1 files changed, 52 insertions(+), 21 deletions(-)
diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c
index 924d692..4878588 100644
--- a/arch/powerpc/kernel/smp.c
+++ b/arch/powerpc/kernel/smp.c
@@ -176,10 +176,10 @@ static struct call_data_struct {
#define SMP_CALL_TIMEOUT 8
/*
- * This function sends a 'generic call function' IPI to all other CPUs
- * in the system.
+ * These functions send a 'generic call function' IPI to other online
+ * CPUS in the system.
*
- * [SUMMARY] Run a function on all other CPUs.
+ * [SUMMARY] Run a function on other CPUs.
* <func> The function to run. This must be fast and non-blocking.
* <info> An arbitrary pointer to pass to the function.
* <nonatomic> currently unused.
@@ -190,18 +190,26 @@ static struct call_data_struct {
* You must not call this function with disabled interrupts or from a
* hardware interrupt handler or from a bottom half handler.
*/
-int smp_call_function (void (*func) (void *info), void *info, int nonatomic,
- int wait)
-{
+int smp_call_function_map(void (*func) (void *info), void *info, int nonatomic,
+ int wait, cpumask_t map)
+{
struct call_data_struct data;
- int ret = -1, cpus;
+ int ret = -1, num_cpus;
+ int cpu;
u64 timeout;
/* Can deadlock when called with interrupts disabled */
WARN_ON(irqs_disabled());
+ /* remove 'self' from the map */
+ if (cpu_isset(smp_processor_id(), map))
+ cpu_clear(smp_processor_id(), map);
+
+ /* sanity check the map, remove any non-online processors. */
+ cpus_and(map, map, cpu_online_map);
+
if (unlikely(smp_ops == NULL))
- return -1;
+ return ret;
data.func = func;
data.info = info;
@@ -213,40 +221,42 @@ int smp_call_function (void (*func) (void *info), void *info, int nonatomic,
spin_lock(&call_lock);
/* Must grab online cpu count with preempt disabled, otherwise
* it can change. */
- cpus = num_online_cpus() - 1;
- if (!cpus) {
+ num_cpus = num_online_cpus() - 1;
+ if (!num_cpus || cpus_empty(map)) {
ret = 0;
goto out;
}
call_data = &data;
smp_wmb();
- /* Send a message to all other CPUs and wait for them to respond */
- smp_ops->message_pass(MSG_ALL_BUT_SELF, PPC_MSG_CALL_FUNCTION);
+ /* Send a message to all CPUs in the map */
+ for_each_cpu_mask(cpu, map)
+ smp_ops->message_pass(cpu, PPC_MSG_CALL_FUNCTION);
timeout = get_tb() + (u64) SMP_CALL_TIMEOUT * tb_ticks_per_sec;
- /* Wait for response */
- while (atomic_read(&data.started) != cpus) {
+ /* Wait for indication that they have received the message */
+ while (atomic_read(&data.started) != num_cpus) {
HMT_low();
if (get_tb() >= timeout) {
printk("smp_call_function on cpu %d: other cpus not "
- "responding (%d)\n", smp_processor_id(),
- atomic_read(&data.started));
+ "responding (%d)\n", smp_processor_id(),
+ atomic_read(&data.started));
debugger(NULL);
goto out;
}
}
+ /* optionally wait for the CPUs to complete */
if (wait) {
- while (atomic_read(&data.finished) != cpus) {
+ while (atomic_read(&data.finished) != num_cpus) {
HMT_low();
if (get_tb() >= timeout) {
printk("smp_call_function on cpu %d: other "
- "cpus not finishing (%d/%d)\n",
- smp_processor_id(),
- atomic_read(&data.finished),
- atomic_read(&data.started));
+ "cpus not finishing (%d/%d)\n",
+ smp_processor_id(),
+ atomic_read(&data.finished),
+ atomic_read(&data.started));
debugger(NULL);
goto out;
}
@@ -262,8 +272,29 @@ int smp_call_function (void (*func) (void *info), void *info, int nonatomic,
return ret;
}
+int smp_call_function(void (*func) (void *info), void *info, int nonatomic,
+ int wait)
+{
+ return smp_call_function_map(func,info,nonatomic,wait,cpu_online_map);
+}
EXPORT_SYMBOL(smp_call_function);
+int smp_call_function_single(int cpu, void (*func) (void *info), void *info, int nonatomic,
+ int wait)
+{
+ cpumask_t map=CPU_MASK_NONE;
+
+ if (!cpu_online(cpu))
+ return -EINVAL;
+
+ if (cpu == smp_processor_id())
+ return -EBUSY;
+
+ cpu_set(cpu, map);
+ return smp_call_function_map(func,info,nonatomic,wait,map);
+}
+EXPORT_SYMBOL(smp_call_function_single);
+
void smp_call_function_interrupt(void)
{
void (*func) (void *info);
^ permalink raw reply related [flat|nested] 3+ messages in thread
* Re: [PATCH] add smp_call_function_map and smp_call_function_single
2007-05-02 17:12 [PATCH] add smp_call_function_map and smp_call_function_single Will Schmidt
@ 2007-05-03 0:53 ` Michael Ellerman
2007-05-03 21:47 ` [PATCH 2/1] comment fixup for smp_call_function Will Schmidt
0 siblings, 1 reply; 3+ messages in thread
From: Michael Ellerman @ 2007-05-03 0:53 UTC (permalink / raw)
To: Will Schmidt; +Cc: linuxppc-dev, paulus, anton, Kevin Corry
[-- Attachment #1: Type: text/plain, Size: 1825 bytes --]
On Wed, 2007-05-02 at 12:12 -0500, Will Schmidt wrote:
> Add a new function named smp_call_function_single(). This matches a generic
> prototype from include/linux/smp.h.
>
> Add a function smp_call_function_map(). This is, for the most part, a rename
> of smp_call_function, with some added cpumask support. smp_call_function and
> smp_call_function_single call into smp_call_function_map.
>
> Lightly tested on 970mp (blade), power4 and power5.
>
> Signed-off-by: Will Schmidt <will_schmidt@vnet.ibm.com>
> cc: Anton Blanchard <anton@samba.org>
> ---
>
> arch/powerpc/kernel/smp.c | 73 ++++++++++++++++++++++++++++++++-------------
> 1 files changed, 52 insertions(+), 21 deletions(-)
>
> diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c
> index 924d692..4878588 100644
> --- a/arch/powerpc/kernel/smp.c
> +++ b/arch/powerpc/kernel/smp.c
> @@ -176,10 +176,10 @@ static struct call_data_struct {
> #define SMP_CALL_TIMEOUT 8
>
> /*
> - * This function sends a 'generic call function' IPI to all other CPUs
> - * in the system.
> + * These functions send a 'generic call function' IPI to other online
> + * CPUS in the system.
> *
> - * [SUMMARY] Run a function on all other CPUs.
> + * [SUMMARY] Run a function on other CPUs.
> * <func> The function to run. This must be fast and non-blocking.
> * <info> An arbitrary pointer to pass to the function.
> * <nonatomic> currently unused.
While you're there, or as a separate patch, can you fix up this
not-quite-kernel-doc commenting?
cheers
--
Michael Ellerman
OzLabs, IBM Australia Development Lab
wwweb: http://michael.ellerman.id.au
phone: +61 2 6212 1183 (tie line 70 21183)
We do not inherit the earth from our ancestors,
we borrow it from our children. - S.M.A.R.T Person
[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 189 bytes --]
^ permalink raw reply [flat|nested] 3+ messages in thread
* [PATCH 2/1] comment fixup for smp_call_function
2007-05-03 0:53 ` Michael Ellerman
@ 2007-05-03 21:47 ` Will Schmidt
0 siblings, 0 replies; 3+ messages in thread
From: Will Schmidt @ 2007-05-03 21:47 UTC (permalink / raw)
To: michael; +Cc: linuxppc-dev, paulus, anton, Kevin Corry
Fix up the comment blob for smp_call_function and friends. Also just a
touch of whitespace cleanup.
Signed-off-by: Will Schmidt <will_schmidt@vnet.ibm.com>
---
diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c
index 4878588..1b82228 100644
--- a/arch/powerpc/kernel/smp.c
+++ b/arch/powerpc/kernel/smp.c
@@ -176,15 +176,13 @@ static struct call_data_struct {
#define SMP_CALL_TIMEOUT 8
/*
- * These functions send a 'generic call function' IPI to other online
- * CPUS in the system.
+ * smp_call_function(): Run a function on other CPUs.
+ * @func: The function to run. This must be fast and non-blocking.
+ * @info: An arbitrary pointer to pass to the function.
+ * @nonatomic: currently unused.
+ * @wait: If true, wait (atomically) until function has completed on other CPUs.
*
- * [SUMMARY] Run a function on other CPUs.
- * <func> The function to run. This must be fast and non-blocking.
- * <info> An arbitrary pointer to pass to the function.
- * <nonatomic> currently unused.
- * <wait> If true, wait (atomically) until function has completed on other CPUs.
- * [RETURNS] 0 on success, else a negative status code. Does not return until
+ * Returns 0 on success, else a negative status code. Does not return until
* remote CPUs are nearly ready to execute <<func>> or are or have executed.
*
* You must not call this function with disabled interrupts or from a
@@ -361,7 +359,7 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
DBG("smp_prepare_cpus\n");
- /*
+ /*
* setup_cpu may need to be called on the boot cpu. We havent
* spun any cpus up but lets be paranoid.
*/
@@ -375,7 +373,7 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
max_cpus = smp_ops->probe();
else
max_cpus = 1;
-
+
smp_space_timers(max_cpus);
for_each_possible_cpu(cpu)
@@ -585,7 +583,7 @@ void __init smp_cpus_done(unsigned int max_cpus)
*/
old_mask = current->cpus_allowed;
set_cpus_allowed(current, cpumask_of_cpu(boot_cpuid));
-
+
if (smp_ops)
smp_ops->setup_cpu(boot_cpuid);
^ permalink raw reply related [flat|nested] 3+ messages in thread
end of thread, other threads:[~2007-05-03 21:47 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-05-02 17:12 [PATCH] add smp_call_function_map and smp_call_function_single Will Schmidt
2007-05-03 0:53 ` Michael Ellerman
2007-05-03 21:47 ` [PATCH 2/1] comment fixup for smp_call_function Will Schmidt
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).