Patchwork [Precise,SRU] Fix oops in arch_trigger_all_cpu_backtrace

login
register
mail settings
Submitter Stefan Bader
Date May 8, 2013, 2:07 p.m.
Message ID <1368022075-16098-1-git-send-email-stefan.bader@canonical.com>
Download mbox | patch
Permalink /patch/242583/
State New
Headers show

Comments

Stefan Bader - May 8, 2013, 2:07 p.m.
Although there is one of the hooks that looks not completely right,
this is the upstream version (without the unnecessary declaration
in smp.h) which seemed to cause no issues. I was not able to see
any impact either. From previous tests of a kernel with this patch
it was said to resolve the issue.

This was added in 3.5 so it is only required for 3.2.

-Stefan

---

From 1e78425a8ddace467b9f4ef33a87ad81d476a319 Mon Sep 17 00:00:00 2001
From: Ben Guthro <ben@guthro.net>
Date: Sat, 21 Apr 2012 00:11:04 +0800
Subject: [PATCH] xen: implement apic ipi interface

Map native ipi vector to xen vector.
Implement apic ipi interface with xen_send_IPI_one.

Tested-by: Steven Noonan <steven@uplinklabs.net>
Signed-off-by: Ben Guthro <ben@guthro.net>
Signed-off-by: Lin Ming <mlin@ss.pku.edu.cn>
Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>

BugLink: http://bugs.launchpad.net/bugs/1168350

(backported from f447d56d36af18c5104ff29dcb1327c0c0ac3634 upstream)
[v2: Drop physflat_send_IPI_allbutself declaration from xen/smp.h]

Signed-off-by: Stefan Bader <stefan.bader@canonical.com>
---
 arch/x86/xen/enlighten.c |    9 ++++++
 arch/x86/xen/smp.c       |   81 +++++++++++++++++++++++++++++++++++++++++++---
 arch/x86/xen/smp.h       |   11 +++++++
 3 files changed, 97 insertions(+), 4 deletions(-)
 create mode 100644 arch/x86/xen/smp.h
Andy Whitcroft - May 9, 2013, 10:39 a.m.
On Wed, May 08, 2013 at 04:07:55PM +0200, Stefan Bader wrote:

> Although there is one of the hooks that looks not completely right,
> this is the upstream version (without the unnecessary declaration
> in smp.h) which seemed to cause no issues. I was not able to see
> any impact either. From previous tests of a kernel with this patch
> it was said to resolve the issue.
> 
> This was added in 3.5 so it is only required for 3.2.

Best to stay as close as possible to mainline regardless, so best to
leave it dubious as it is seemingly unused anyhow.

> From 1e78425a8ddace467b9f4ef33a87ad81d476a319 Mon Sep 17 00:00:00 2001
> From: Ben Guthro <ben@guthro.net>
> Date: Sat, 21 Apr 2012 00:11:04 +0800
> Subject: [PATCH] xen: implement apic ipi interface
> 
> Map native ipi vector to xen vector.
> Implement apic ipi interface with xen_send_IPI_one.
> 
> Tested-by: Steven Noonan <steven@uplinklabs.net>
> Signed-off-by: Ben Guthro <ben@guthro.net>
> Signed-off-by: Lin Ming <mlin@ss.pku.edu.cn>
> Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
> 
> BugLink: http://bugs.launchpad.net/bugs/1168350
> 
> (backported from f447d56d36af18c5104ff29dcb1327c0c0ac3634 upstream)
> [v2: Drop physflat_send_IPI_allbutself declaration from xen/smp.h]
> 
> Signed-off-by: Stefan Bader <stefan.bader@canonical.com>
> ---
>  arch/x86/xen/enlighten.c |    9 ++++++
>  arch/x86/xen/smp.c       |   81 +++++++++++++++++++++++++++++++++++++++++++---
>  arch/x86/xen/smp.h       |   11 +++++++
>  3 files changed, 97 insertions(+), 4 deletions(-)
>  create mode 100644 arch/x86/xen/smp.h
> 
> diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c
> index bb03ff0..b284aa3 100644
> --- a/arch/x86/xen/enlighten.c
> +++ b/arch/x86/xen/enlighten.c
> @@ -69,6 +69,7 @@
>  
>  #include "xen-ops.h"
>  #include "mmu.h"
> +#include "smp.h"
>  #include "multicalls.h"
>  
>  EXPORT_SYMBOL_GPL(hypercall_page);
> @@ -821,6 +822,14 @@ static void set_xen_basic_apic_ops(void)
>  	apic->safe_wait_icr_idle = xen_safe_apic_wait_icr_idle;
>  	apic->set_apic_id = xen_set_apic_id;
>  	apic->get_apic_id = xen_get_apic_id;
> +
> +#ifdef CONFIG_SMP
> +	apic->send_IPI_allbutself = xen_send_IPI_allbutself;
> +	apic->send_IPI_mask_allbutself = xen_send_IPI_mask_allbutself;
> +	apic->send_IPI_mask = xen_send_IPI_mask;
> +	apic->send_IPI_all = xen_send_IPI_all;
> +	apic->send_IPI_self = xen_send_IPI_self;
> +#endif
>  }
>  
>  #endif
> diff --git a/arch/x86/xen/smp.c b/arch/x86/xen/smp.c
> index 9a23fff..36a143f 100644
> --- a/arch/x86/xen/smp.c
> +++ b/arch/x86/xen/smp.c
> @@ -467,8 +467,8 @@ static void xen_smp_send_reschedule(int cpu)
>  	xen_send_IPI_one(cpu, XEN_RESCHEDULE_VECTOR);
>  }
>  
> -static void xen_send_IPI_mask(const struct cpumask *mask,
> -			      enum ipi_vector vector)
> +static void __xen_send_IPI_mask(const struct cpumask *mask,
> +			      int vector)
>  {
>  	unsigned cpu;
>  
> @@ -480,7 +480,7 @@ static void xen_smp_send_call_function_ipi(const struct cpumask *mask)
>  {
>  	int cpu;
>  
> -	xen_send_IPI_mask(mask, XEN_CALL_FUNCTION_VECTOR);
> +	__xen_send_IPI_mask(mask, XEN_CALL_FUNCTION_VECTOR);
>  
>  	/* Make sure other vcpus get a chance to run if they need to. */
>  	for_each_cpu(cpu, mask) {
> @@ -493,10 +493,83 @@ static void xen_smp_send_call_function_ipi(const struct cpumask *mask)
>  
>  static void xen_smp_send_call_function_single_ipi(int cpu)
>  {
> -	xen_send_IPI_mask(cpumask_of(cpu),
> +	__xen_send_IPI_mask(cpumask_of(cpu),
>  			  XEN_CALL_FUNCTION_SINGLE_VECTOR);
>  }
>  
> +static inline int xen_map_vector(int vector)
> +{
> +	int xen_vector;
> +
> +	switch (vector) {
> +	case RESCHEDULE_VECTOR:
> +		xen_vector = XEN_RESCHEDULE_VECTOR;
> +		break;
> +	case CALL_FUNCTION_VECTOR:
> +		xen_vector = XEN_CALL_FUNCTION_VECTOR;
> +		break;
> +	case CALL_FUNCTION_SINGLE_VECTOR:
> +		xen_vector = XEN_CALL_FUNCTION_SINGLE_VECTOR;
> +		break;
> +	default:
> +		xen_vector = -1;
> +		printk(KERN_ERR "xen: vector 0x%x is not implemented\n",
> +			vector);
> +	}
> +
> +	return xen_vector;
> +}
> +
> +void xen_send_IPI_mask(const struct cpumask *mask,
> +			      int vector)
> +{
> +	int xen_vector = xen_map_vector(vector);
> +
> +	if (xen_vector >= 0)
> +		__xen_send_IPI_mask(mask, xen_vector);
> +}
> +
> +void xen_send_IPI_all(int vector)
> +{
> +	int xen_vector = xen_map_vector(vector);
> +
> +	if (xen_vector >= 0)
> +		__xen_send_IPI_mask(cpu_online_mask, xen_vector);
> +}
> +
> +void xen_send_IPI_self(int vector)
> +{
> +	int xen_vector = xen_map_vector(vector);
> +
> +	if (xen_vector >= 0)
> +		xen_send_IPI_one(smp_processor_id(), xen_vector);
> +}
> +
> +void xen_send_IPI_mask_allbutself(const struct cpumask *mask,
> +				int vector)
> +{
> +	unsigned cpu;
> +	unsigned int this_cpu = smp_processor_id();
> +
> +	if (!(num_online_cpus() > 1))
> +		return;
> +
> +	for_each_cpu_and(cpu, mask, cpu_online_mask) {
> +		if (this_cpu == cpu)
> +			continue;
> +
> +		xen_smp_send_call_function_single_ipi(cpu);
> +	}
> +}
> +
> +void xen_send_IPI_allbutself(int vector)
> +{
> +	int xen_vector = xen_map_vector(vector);
> +
> +	if (xen_vector >= 0)
> +		xen_send_IPI_mask_allbutself(cpu_online_mask, xen_vector);
> +}
> +
>  static irqreturn_t xen_call_function_interrupt(int irq, void *dev_id)
>  {
>  	irq_enter();
> diff --git a/arch/x86/xen/smp.h b/arch/x86/xen/smp.h
> new file mode 100644
> index 0000000..c7c2d89
> --- /dev/null
> +++ b/arch/x86/xen/smp.h
> @@ -0,0 +1,11 @@
> +#ifndef _XEN_SMP_H
> +
> +extern void xen_send_IPI_mask(const struct cpumask *mask,
> +			      int vector);
> +extern void xen_send_IPI_mask_allbutself(const struct cpumask *mask,
> +				int vector);
> +extern void xen_send_IPI_allbutself(int vector);
> +extern void xen_send_IPI_all(int vector);
> +extern void xen_send_IPI_self(int vector);
> +
> +#endif

Looks feasable, assuming this has tested well then it seems ok to me.

Acked-by: Andy Whitcroft <apw@canonical.com>

-apw
Tim Gardner - May 9, 2013, 2:35 p.m.

Patch

diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c
index bb03ff0..b284aa3 100644
--- a/arch/x86/xen/enlighten.c
+++ b/arch/x86/xen/enlighten.c
@@ -69,6 +69,7 @@ 
 
 #include "xen-ops.h"
 #include "mmu.h"
+#include "smp.h"
 #include "multicalls.h"
 
 EXPORT_SYMBOL_GPL(hypercall_page);
@@ -821,6 +822,14 @@  static void set_xen_basic_apic_ops(void)
 	apic->safe_wait_icr_idle = xen_safe_apic_wait_icr_idle;
 	apic->set_apic_id = xen_set_apic_id;
 	apic->get_apic_id = xen_get_apic_id;
+
+#ifdef CONFIG_SMP
+	apic->send_IPI_allbutself = xen_send_IPI_allbutself;
+	apic->send_IPI_mask_allbutself = xen_send_IPI_mask_allbutself;
+	apic->send_IPI_mask = xen_send_IPI_mask;
+	apic->send_IPI_all = xen_send_IPI_all;
+	apic->send_IPI_self = xen_send_IPI_self;
+#endif
 }
 
 #endif
diff --git a/arch/x86/xen/smp.c b/arch/x86/xen/smp.c
index 9a23fff..36a143f 100644
--- a/arch/x86/xen/smp.c
+++ b/arch/x86/xen/smp.c
@@ -467,8 +467,8 @@  static void xen_smp_send_reschedule(int cpu)
 	xen_send_IPI_one(cpu, XEN_RESCHEDULE_VECTOR);
 }
 
-static void xen_send_IPI_mask(const struct cpumask *mask,
-			      enum ipi_vector vector)
+static void __xen_send_IPI_mask(const struct cpumask *mask,
+			      int vector)
 {
 	unsigned cpu;
 
@@ -480,7 +480,7 @@  static void xen_smp_send_call_function_ipi(const struct cpumask *mask)
 {
 	int cpu;
 
-	xen_send_IPI_mask(mask, XEN_CALL_FUNCTION_VECTOR);
+	__xen_send_IPI_mask(mask, XEN_CALL_FUNCTION_VECTOR);
 
 	/* Make sure other vcpus get a chance to run if they need to. */
 	for_each_cpu(cpu, mask) {
@@ -493,10 +493,83 @@  static void xen_smp_send_call_function_ipi(const struct cpumask *mask)
 
 static void xen_smp_send_call_function_single_ipi(int cpu)
 {
-	xen_send_IPI_mask(cpumask_of(cpu),
+	__xen_send_IPI_mask(cpumask_of(cpu),
 			  XEN_CALL_FUNCTION_SINGLE_VECTOR);
 }
 
+static inline int xen_map_vector(int vector)
+{
+	int xen_vector;
+
+	switch (vector) {
+	case RESCHEDULE_VECTOR:
+		xen_vector = XEN_RESCHEDULE_VECTOR;
+		break;
+	case CALL_FUNCTION_VECTOR:
+		xen_vector = XEN_CALL_FUNCTION_VECTOR;
+		break;
+	case CALL_FUNCTION_SINGLE_VECTOR:
+		xen_vector = XEN_CALL_FUNCTION_SINGLE_VECTOR;
+		break;
+	default:
+		xen_vector = -1;
+		printk(KERN_ERR "xen: vector 0x%x is not implemented\n",
+			vector);
+	}
+
+	return xen_vector;
+}
+
+void xen_send_IPI_mask(const struct cpumask *mask,
+			      int vector)
+{
+	int xen_vector = xen_map_vector(vector);
+
+	if (xen_vector >= 0)
+		__xen_send_IPI_mask(mask, xen_vector);
+}
+
+void xen_send_IPI_all(int vector)
+{
+	int xen_vector = xen_map_vector(vector);
+
+	if (xen_vector >= 0)
+		__xen_send_IPI_mask(cpu_online_mask, xen_vector);
+}
+
+void xen_send_IPI_self(int vector)
+{
+	int xen_vector = xen_map_vector(vector);
+
+	if (xen_vector >= 0)
+		xen_send_IPI_one(smp_processor_id(), xen_vector);
+}
+
+void xen_send_IPI_mask_allbutself(const struct cpumask *mask,
+				int vector)
+{
+	unsigned cpu;
+	unsigned int this_cpu = smp_processor_id();
+
+	if (!(num_online_cpus() > 1))
+		return;
+
+	for_each_cpu_and(cpu, mask, cpu_online_mask) {
+		if (this_cpu == cpu)
+			continue;
+
+		xen_smp_send_call_function_single_ipi(cpu);
+	}
+}
+
+void xen_send_IPI_allbutself(int vector)
+{
+	int xen_vector = xen_map_vector(vector);
+
+	if (xen_vector >= 0)
+		xen_send_IPI_mask_allbutself(cpu_online_mask, xen_vector);
+}
+
 static irqreturn_t xen_call_function_interrupt(int irq, void *dev_id)
 {
 	irq_enter();
diff --git a/arch/x86/xen/smp.h b/arch/x86/xen/smp.h
new file mode 100644
index 0000000..c7c2d89
--- /dev/null
+++ b/arch/x86/xen/smp.h
@@ -0,0 +1,11 @@ 
+#ifndef _XEN_SMP_H
+
+extern void xen_send_IPI_mask(const struct cpumask *mask,
+			      int vector);
+extern void xen_send_IPI_mask_allbutself(const struct cpumask *mask,
+				int vector);
+extern void xen_send_IPI_allbutself(int vector);
+extern void xen_send_IPI_all(int vector);
+extern void xen_send_IPI_self(int vector);
+
+#endif