public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH] MIPS: add smp_call_function_single()
@ 2007-07-27 12:44 Stephane Eranian
  2007-07-27 12:55 ` Ralf Baechle
  0 siblings, 1 reply; 7+ messages in thread
From: Stephane Eranian @ 2007-07-27 12:44 UTC (permalink / raw)
  To: linux-kernel; +Cc: mucci, ralf, linux-mips, ak, akpm, Stephane Eranian

    [MIPS] add smp_call_function_single()
    
    signed-off-by: Stephane Eranian <eranian@hpl.hp.com>
    signed-off-by: Phil Mucci <mucci@cs.utk.edu>

diff --git a/arch/mips/kernel/smp.c b/arch/mips/kernel/smp.c
index be7362b..9e376e2 100644
--- a/arch/mips/kernel/smp.c
+++ b/arch/mips/kernel/smp.c
@@ -193,6 +193,53 @@ void smp_call_function_interrupt(void)
 	}
 }
 
+int smp_call_function_single(int cpu, void (*func) (void *info), void *info, int retry,
+			     int wait)
+{
+  struct call_data_struct data;
+  int me = smp_processor_id();
+
+  /*
+     * Can die spectacularly if this CPU isn't yet marked online
+      */
+  BUG_ON(!cpu_online(me));
+  if (cpu == me) {
+    WARN_ON(1);
+    return -EBUSY;
+    }
+
+  /* Can deadlock when called with interrupts disabled */
+  WARN_ON(irqs_disabled());
+
+  data.func = func;
+  data.info = info;
+  atomic_set(&data.started, 0);
+  data.wait = wait;
+  if (wait)
+    atomic_set(&data.finished, 0);
+
+  spin_lock(&smp_call_lock);
+  call_data = &data;
+  mb();
+
+  /* Send a message to the other CPU */
+  core_send_ipi(cpu, SMP_CALL_FUNCTION);
+
+  /* Wait for response */
+  /* FIXME: lock-up detection, backtrace on lock-up */
+  while (atomic_read(&data.started) != 1)
+    barrier();
+
+  if (wait)
+    while (atomic_read(&data.finished) != 1)
+      barrier();
+  call_data = NULL;
+  spin_unlock(&smp_call_lock);
+
+  return 0;
+}
+EXPORT_SYMBOL(smp_call_function_single);
+
 static void stop_this_cpu(void *dummy)
 {
 	/*
diff --git a/include/asm-mips/smp.h b/include/asm-mips/smp.h
index 13aef6a..5acbf38 100644
--- a/include/asm-mips/smp.h
+++ b/include/asm-mips/smp.h
@@ -102,6 +102,8 @@ static inline void smp_send_reschedule(int cpu)
 	core_send_ipi(cpu, SMP_RESCHEDULE_YOURSELF);
 }
 
+extern int smp_call_function_single(int cpuid, void (*func) (void *info),
+				void *info, int retry, int wait);
 extern asmlinkage void smp_call_function_interrupt(void);
 
 #endif /* CONFIG_SMP */

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

* Re: [PATCH] MIPS: add smp_call_function_single()
  2007-07-27 12:44 [PATCH] MIPS: add smp_call_function_single() Stephane Eranian
@ 2007-07-27 12:55 ` Ralf Baechle
  2007-07-27 13:53   ` Stephane Eranian
  0 siblings, 1 reply; 7+ messages in thread
From: Ralf Baechle @ 2007-07-27 12:55 UTC (permalink / raw)
  To: Stephane Eranian; +Cc: linux-kernel, mucci, linux-mips, ak, akpm

On Fri, Jul 27, 2007 at 05:44:51AM -0700, Stephane Eranian wrote:

> diff --git a/arch/mips/kernel/smp.c b/arch/mips/kernel/smp.c
> index be7362b..9e376e2 100644
> --- a/arch/mips/kernel/smp.c
> +++ b/arch/mips/kernel/smp.c
> @@ -193,6 +193,53 @@ void smp_call_function_interrupt(void)
>  	}
>  }
>  
> +int smp_call_function_single(int cpu, void (*func) (void *info), void *info, int retry,
> +			     int wait)
> +{
> +  struct call_data_struct data;
> +  int me = smp_processor_id();
> +
> +  /*
> +     * Can die spectacularly if this CPU isn't yet marked online
> +      */
> +  BUG_ON(!cpu_online(me));
> +  if (cpu == me) {
> +    WARN_ON(1);
> +    return -EBUSY;
> +    }
> +
> +  /* Can deadlock when called with interrupts disabled */
> +  WARN_ON(irqs_disabled());
> +
> +  data.func = func;
> +  data.info = info;
> +  atomic_set(&data.started, 0);
> +  data.wait = wait;
> +  if (wait)
> +    atomic_set(&data.finished, 0);
> +
> +  spin_lock(&smp_call_lock);
> +  call_data = &data;
> +  mb();
> +
> +  /* Send a message to the other CPU */
> +  core_send_ipi(cpu, SMP_CALL_FUNCTION);
> +
> +  /* Wait for response */
> +  /* FIXME: lock-up detection, backtrace on lock-up */
> +  while (atomic_read(&data.started) != 1)
> +    barrier();
> +
> +  if (wait)
> +    while (atomic_read(&data.finished) != 1)
> +      barrier();
> +  call_data = NULL;
> +  spin_unlock(&smp_call_lock);
> +
> +  return 0;
> +}
> +EXPORT_SYMBOL(smp_call_function_single);

Please fix the indentation to use tabs as per Documentation/CodingStyle.

>  static void stop_this_cpu(void *dummy)
>  {
>  	/*
> diff --git a/include/asm-mips/smp.h b/include/asm-mips/smp.h
> index 13aef6a..5acbf38 100644
> --- a/include/asm-mips/smp.h
> +++ b/include/asm-mips/smp.h
> @@ -102,6 +102,8 @@ static inline void smp_send_reschedule(int cpu)
>  	core_send_ipi(cpu, SMP_RESCHEDULE_YOURSELF);
>  }
>  
> +extern int smp_call_function_single(int cpuid, void (*func) (void *info),
> +				void *info, int retry, int wait);

The function is already declared in include/linux/smp.h so this segment
is unecessary.

  Ralf

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

* Re: [PATCH] MIPS: add smp_call_function_single()
  2007-07-27 12:55 ` Ralf Baechle
@ 2007-07-27 13:53   ` Stephane Eranian
  2007-07-28  9:19     ` Heiko Carstens
  0 siblings, 1 reply; 7+ messages in thread
From: Stephane Eranian @ 2007-07-27 13:53 UTC (permalink / raw)
  To: Ralf Baechle; +Cc: linux-kernel, mucci, linux-mips, ak, akpm

Ralf,

Here is take 2.

[MIPS] add smp_call_function_single (take 2)

signed-off-by: Stephane Eranian <eranian@hpl.hp.com>
signed-off-by: Phil Mucci <mucci@cs.utk.edu>

diff --git a/arch/mips/kernel/smp.c b/arch/mips/kernel/smp.c
index be7362b..d47234c 100644
--- a/arch/mips/kernel/smp.c
+++ b/arch/mips/kernel/smp.c
@@ -193,6 +193,53 @@ void smp_call_function_interrupt(void)
 	}
 }
 
+int smp_call_function_single(int cpu, void (*func) (void *info), void *info, int retry,
+			     int wait)
+{
+	struct call_data_struct data;
+	int me = smp_processor_id();
+
+	/*
+	 * Can die spectacularly if this CPU isn't yet marked online
+	 */
+	BUG_ON(!cpu_online(me));
+	if (cpu == me) {
+		WARN_ON(1);
+		return -EBUSY;
+	}
+
+	/* Can deadlock when called with interrupts disabled */
+	WARN_ON(irqs_disabled());
+
+	data.func = func;
+	data.info = info;
+	atomic_set(&data.started, 0);
+	data.wait = wait;
+	if (wait)
+		atomic_set(&data.finished, 0);
+
+	spin_lock(&smp_call_lock);
+	call_data = &data;
+	mb();
+
+	/* Send a message to the other CPU */
+	core_send_ipi(cpu, SMP_CALL_FUNCTION);
+
+	/* Wait for response */
+	/* FIXME: lock-up detection, backtrace on lock-up */
+	while (atomic_read(&data.started) != 1)
+		barrier();
+
+	if (wait)
+		while (atomic_read(&data.finished) != 1)
+			barrier();
+	call_data = NULL;
+	spin_unlock(&smp_call_lock);
+
+	return 0;
+}
+EXPORT_SYMBOL(smp_call_function_single);
+
 static void stop_this_cpu(void *dummy)
 {
 	/*

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

* Re: [PATCH] MIPS: add smp_call_function_single()
  2007-07-27 13:53   ` Stephane Eranian
@ 2007-07-28  9:19     ` Heiko Carstens
  2007-07-29  7:33       ` Avi Kivity
  2007-07-30  9:18       ` Stephane Eranian
  0 siblings, 2 replies; 7+ messages in thread
From: Heiko Carstens @ 2007-07-28  9:19 UTC (permalink / raw)
  To: Stephane Eranian
  Cc: Ralf Baechle, linux-kernel, mucci, linux-mips, ak, akpm,
	Tony Luck, Avi Kivity

On Fri, Jul 27, 2007 at 06:53:23AM -0700, Stephane Eranian wrote:
> Ralf,
> 
> Here is take 2.
> 
> [MIPS] add smp_call_function_single (take 2)
> 
> signed-off-by: Stephane Eranian <eranian@hpl.hp.com>
> signed-off-by: Phil Mucci <mucci@cs.utk.edu>
> 
> diff --git a/arch/mips/kernel/smp.c b/arch/mips/kernel/smp.c
> index be7362b..d47234c 100644
> --- a/arch/mips/kernel/smp.c
> +++ b/arch/mips/kernel/smp.c
> @@ -193,6 +193,53 @@ void smp_call_function_interrupt(void)
>  	}
>  }
> 
> +int smp_call_function_single(int cpu, void (*func) (void *info), void *info, int retry,
> +			     int wait)
> +{
> +	struct call_data_struct data;
> +	int me = smp_processor_id();
> +
> +	/*
> +	 * Can die spectacularly if this CPU isn't yet marked online
> +	 */
> +	BUG_ON(!cpu_online(me));
> +	if (cpu == me) {
> +		WARN_ON(1);
> +		return -EBUSY;
> +	}
> +
> +	/* Can deadlock when called with interrupts disabled */
> +	WARN_ON(irqs_disabled());
> +
> +	data.func = func;
> +	data.info = info;
> +	atomic_set(&data.started, 0);
> +	data.wait = wait;
> +	if (wait)
> +		atomic_set(&data.finished, 0);
> +
> +	spin_lock(&smp_call_lock);
> +	call_data = &data;
> +	mb();
> +
> +	/* Send a message to the other CPU */
> +	core_send_ipi(cpu, SMP_CALL_FUNCTION);
> +
> +	/* Wait for response */
> +	/* FIXME: lock-up detection, backtrace on lock-up */
> +	while (atomic_read(&data.started) != 1)
> +		barrier();
> +
> +	if (wait)
> +		while (atomic_read(&data.finished) != 1)
> +			barrier();
> +	call_data = NULL;
> +	spin_unlock(&smp_call_lock);
> +
> +	return 0;
> +}
> +EXPORT_SYMBOL(smp_call_function_single);
> +
>  static void stop_this_cpu(void *dummy)
>  {

This will not do the right thing. Semantics of smp_call_function_single()
changed recently. It now is supposed to call func() locally with irqs
disabled if cpu == smp_processor_id(). See i386/x86_64 and powerpc.
Unfortunately ia64 hasn't been changed yet, so it will behave differently.

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

* Re: [PATCH] MIPS: add smp_call_function_single()
  2007-07-28  9:19     ` Heiko Carstens
@ 2007-07-29  7:33       ` Avi Kivity
  2007-07-30  9:18       ` Stephane Eranian
  1 sibling, 0 replies; 7+ messages in thread
From: Avi Kivity @ 2007-07-29  7:33 UTC (permalink / raw)
  To: Heiko Carstens
  Cc: Stephane Eranian, Ralf Baechle, linux-kernel, mucci, linux-mips,
	ak, akpm, Tony Luck

Heiko Carstens wrote:
> This will not do the right thing. Semantics of smp_call_function_single()
> changed recently. It now is supposed to call func() locally with irqs
> disabled if cpu == smp_processor_id(). See i386/x86_64 and powerpc.
> Unfortunately ia64 hasn't been changed yet, so it will behave differently.
>   

A patch for ia64 has been submitted, presumably it's somewhere in the 
pipeline.

-- 
error compiling committee.c: too many arguments to function


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

* Re: [PATCH] MIPS: add smp_call_function_single()
  2007-07-28  9:19     ` Heiko Carstens
  2007-07-29  7:33       ` Avi Kivity
@ 2007-07-30  9:18       ` Stephane Eranian
  1 sibling, 0 replies; 7+ messages in thread
From: Stephane Eranian @ 2007-07-30  9:18 UTC (permalink / raw)
  To: Heiko Carstens
  Cc: mucci, pwatkins, Ralf Baechle, linux-kernel, mucci, linux-mips,
	ak, akpm, Tony Luck, Avi Kivity

Hello,

Thanks for catching this. We will resubmit an updated version.

PHil, Peter, would you be able/willing to do this?

thanks.

On Sat, Jul 28, 2007 at 11:19:50AM +0200, Heiko Carstens wrote:
> On Fri, Jul 27, 2007 at 06:53:23AM -0700, Stephane Eranian wrote:
> > Ralf,
> > 
> > Here is take 2.
> > 
> > [MIPS] add smp_call_function_single (take 2)
> > 
> > signed-off-by: Stephane Eranian <eranian@hpl.hp.com>
> > signed-off-by: Phil Mucci <mucci@cs.utk.edu>
> > 
> > diff --git a/arch/mips/kernel/smp.c b/arch/mips/kernel/smp.c
> > index be7362b..d47234c 100644
> > --- a/arch/mips/kernel/smp.c
> > +++ b/arch/mips/kernel/smp.c
> > @@ -193,6 +193,53 @@ void smp_call_function_interrupt(void)
> >  	}
> >  }
> > 
> > +int smp_call_function_single(int cpu, void (*func) (void *info), void *info, int retry,
> > +			     int wait)
> > +{
> > +	struct call_data_struct data;
> > +	int me = smp_processor_id();
> > +
> > +	/*
> > +	 * Can die spectacularly if this CPU isn't yet marked online
> > +	 */
> > +	BUG_ON(!cpu_online(me));
> > +	if (cpu == me) {
> > +		WARN_ON(1);
> > +		return -EBUSY;
> > +	}
> > +
> > +	/* Can deadlock when called with interrupts disabled */
> > +	WARN_ON(irqs_disabled());
> > +
> > +	data.func = func;
> > +	data.info = info;
> > +	atomic_set(&data.started, 0);
> > +	data.wait = wait;
> > +	if (wait)
> > +		atomic_set(&data.finished, 0);
> > +
> > +	spin_lock(&smp_call_lock);
> > +	call_data = &data;
> > +	mb();
> > +
> > +	/* Send a message to the other CPU */
> > +	core_send_ipi(cpu, SMP_CALL_FUNCTION);
> > +
> > +	/* Wait for response */
> > +	/* FIXME: lock-up detection, backtrace on lock-up */
> > +	while (atomic_read(&data.started) != 1)
> > +		barrier();
> > +
> > +	if (wait)
> > +		while (atomic_read(&data.finished) != 1)
> > +			barrier();
> > +	call_data = NULL;
> > +	spin_unlock(&smp_call_lock);
> > +
> > +	return 0;
> > +}
> > +EXPORT_SYMBOL(smp_call_function_single);
> > +
> >  static void stop_this_cpu(void *dummy)
> >  {
> 
> This will not do the right thing. Semantics of smp_call_function_single()
> changed recently. It now is supposed to call func() locally with irqs
> disabled if cpu == smp_processor_id(). See i386/x86_64 and powerpc.
> Unfortunately ia64 hasn't been changed yet, so it will behave differently.

-- 

-Stephane

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

* Re: [PATCH] MIPS: Add smp_call_function_single()
@ 2007-07-30 22:01 pwatkins
  0 siblings, 0 replies; 7+ messages in thread
From: pwatkins @ 2007-07-30 22:01 UTC (permalink / raw)
  To: eranian, heiko.carstens
  Cc: pwatkins, mucci, ralf, linux-kernel, linux-mips, ak, akpm,
	tony.luck, avi

How about this to handle the "call yourself" semantic?

In the other archs, there is more factoring of smp call code, and more care in
the use of get_cpu(). That can be a follow-up MIPS patch.

Signed-off-by: Peter Watkins <pwatkins@sicortex.com>

---
diff --git a/arch/mips/kernel/smp.c b/arch/mips/kernel/smp.c
index 67edfa7..33712ff 100644
--- a/arch/mips/kernel/smp.c
+++ b/arch/mips/kernel/smp.c
@@ -203,6 +203,61 @@ void smp_call_function_interrupt(void)
 	}
 }
 
+int smp_call_function_single (int cpu, void (*func) (void *info), void *info, int retry,
+			      int wait)
+{
+	struct call_data_struct data;
+	int me;
+
+	/*
+	 * Can die spectacularly if this CPU isn't yet marked online
+	 */
+	if (!cpu_online(cpu))
+		return 0;
+
+	me = get_cpu();
+	BUG_ON(!cpu_online(me));
+
+	if (cpu == me) {
+		local_irq_disable()
+		func(info);
+		local_irq_enable();
+		put_cpu();
+		return 0;
+	}
+
+	/* Can deadlock when called with interrupts disabled */
+	WARN_ON(irqs_disabled());
+
+	data.func = func;
+	data.info = info;
+	atomic_set(&data.started, 0);
+	data.wait = wait;
+	if (wait)
+		atomic_set(&data.finished, 0);
+
+	spin_lock(&smp_call_lock);
+	call_data = &data;
+	smp_mb();
+
+	/* Send a message to the other CPU */
+	core_send_ipi(cpu, SMP_CALL_FUNCTION);
+
+	/* Wait for response */
+	/* FIXME: lock-up detection, backtrace on lock-up */
+	while (atomic_read(&data.started) != 1)
+		barrier();
+
+	if (wait)
+		while (atomic_read(&data.finished) != 1)
+			barrier();
+	call_data = NULL;
+	spin_unlock(&smp_call_lock);
+
+	put_cpu();
+	return 0;
+}
+
 static void stop_this_cpu(void *dummy)
 {
 	/*

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

end of thread, other threads:[~2007-07-30 22:31 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-07-30 22:01 [PATCH] MIPS: Add smp_call_function_single() pwatkins
  -- strict thread matches above, loose matches on Subject: below --
2007-07-27 12:44 [PATCH] MIPS: add smp_call_function_single() Stephane Eranian
2007-07-27 12:55 ` Ralf Baechle
2007-07-27 13:53   ` Stephane Eranian
2007-07-28  9:19     ` Heiko Carstens
2007-07-29  7:33       ` Avi Kivity
2007-07-30  9:18       ` Stephane Eranian

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox