linuxppc-dev.lists.ozlabs.org archive mirror
 help / color / mirror / Atom feed
* [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).