Commit 697556d4 authored by Andrew Morton's avatar Andrew Morton Committed by Linus Torvalds

[PATCH] ppc64: cpus_in_xmon needs to be a cpumask_t, from Milton Miller

From: Anton Blanchard <anton@samba.org>

Also add cpu_relax() to several spinloops in xmon which wait for other cpus.
parent d4e883c1
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
#include <linux/reboot.h> #include <linux/reboot.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/kallsyms.h> #include <linux/kallsyms.h>
#include <linux/cpumask.h>
#include <asm/ptrace.h> #include <asm/ptrace.h>
#include <asm/string.h> #include <asm/string.h>
...@@ -37,7 +38,7 @@ ...@@ -37,7 +38,7 @@
#define skipbl xmon_skipbl #define skipbl xmon_skipbl
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
volatile unsigned long cpus_in_xmon = 0; volatile cpumask_t cpus_in_xmon = CPU_MASK_NONE;
static unsigned long got_xmon = 0; static unsigned long got_xmon = 0;
static volatile int take_xmon = -1; static volatile int take_xmon = -1;
static volatile int leaving_xmon = 0; static volatile int leaving_xmon = 0;
...@@ -288,17 +289,18 @@ xmon(struct pt_regs *excp) ...@@ -288,17 +289,18 @@ xmon(struct pt_regs *excp)
leaving_xmon = 0; leaving_xmon = 0;
/* possible race condition here if a CPU is held up and gets /* possible race condition here if a CPU is held up and gets
* here while we are exiting */ * here while we are exiting */
if (test_and_set_bit(smp_processor_id(), &cpus_in_xmon)) { if (cpu_test_and_set(smp_processor_id(), cpus_in_xmon)) {
/* xmon probably caused an exception itself */ /* xmon probably caused an exception itself */
printf("We are already in xmon\n"); printf("We are already in xmon\n");
for (;;) for (;;)
; cpu_relax();
} }
while (test_and_set_bit(0, &got_xmon)) { while (test_and_set_bit(0, &got_xmon)) {
if (take_xmon == smp_processor_id()) { if (take_xmon == smp_processor_id()) {
take_xmon = -1; take_xmon = -1;
break; break;
} }
cpu_relax();
} }
/* /*
* XXX: breakpoints are removed while any cpu is in xmon * XXX: breakpoints are removed while any cpu is in xmon
...@@ -325,7 +327,7 @@ xmon(struct pt_regs *excp) ...@@ -325,7 +327,7 @@ xmon(struct pt_regs *excp)
leaving_xmon = 1; leaving_xmon = 1;
if (cmd != 's') if (cmd != 's')
clear_bit(0, &got_xmon); clear_bit(0, &got_xmon);
clear_bit(smp_processor_id(), &cpus_in_xmon); cpu_clear(smp_processor_id(), cpus_in_xmon);
#endif /* CONFIG_SMP */ #endif /* CONFIG_SMP */
set_msrd(msr); /* restore interrupt enable */ set_msrd(msr); /* restore interrupt enable */
} }
...@@ -602,6 +604,7 @@ cmds(struct pt_regs *excp) ...@@ -602,6 +604,7 @@ cmds(struct pt_regs *excp)
printf(" (type ? for help)\n"); printf(" (type ? for help)\n");
break; break;
} }
cpu_relax();
} }
} }
...@@ -638,7 +641,7 @@ static void cpu_cmd(void) ...@@ -638,7 +641,7 @@ static void cpu_cmd(void)
/* print cpus waiting or in xmon */ /* print cpus waiting or in xmon */
printf("cpus stopped:"); printf("cpus stopped:");
for (cpu = 0; cpu < NR_CPUS; ++cpu) { for (cpu = 0; cpu < NR_CPUS; ++cpu) {
if (test_bit(cpu, &cpus_in_xmon)) { if (cpu_isset(cpu, cpus_in_xmon)) {
printf(" %x", cpu); printf(" %x", cpu);
if (cpu == smp_processor_id()) if (cpu == smp_processor_id())
printf("*", cpu); printf("*", cpu);
...@@ -664,6 +667,7 @@ static void cpu_cmd(void) ...@@ -664,6 +667,7 @@ static void cpu_cmd(void)
take_xmon = -1; take_xmon = -1;
break; break;
} }
cpu_relax();
} }
} }
#endif /* CONFIG_SMP */ #endif /* CONFIG_SMP */
......
...@@ -29,6 +29,7 @@ ...@@ -29,6 +29,7 @@
#include <linux/kbd_kern.h> #include <linux/kbd_kern.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
#include <linux/spinlock.h> #include <linux/spinlock.h>
#include <linux/cpumask.h>
extern int hvc_count(int *); extern int hvc_count(int *);
extern int hvc_get_chars(int index, char *buf, int count); extern int hvc_get_chars(int index, char *buf, int count);
...@@ -223,10 +224,10 @@ static void hvc_poll(int index) ...@@ -223,10 +224,10 @@ static void hvc_poll(int index)
spin_unlock_irqrestore(&hp->lock, flags); spin_unlock_irqrestore(&hp->lock, flags);
} }
#if defined (CONFIG_XMON) #if defined(CONFIG_XMON) && defined(CONFIG_SMP)
extern unsigned long cpus_in_xmon; extern cpumask_t cpus_in_xmon;
#else #else
unsigned long cpus_in_xmon=0; static const cpumask_t cpus_in_xmon = CPU_MASK_NONE;
#endif #endif
...@@ -237,7 +238,7 @@ int khvcd(void *unused) ...@@ -237,7 +238,7 @@ int khvcd(void *unused)
daemonize("khvcd"); daemonize("khvcd");
for (;;) { for (;;) {
if (!cpus_in_xmon) { if (cpus_empty(cpus_in_xmon)) {
for (i = 0; i < MAX_NR_HVC_CONSOLES; ++i) for (i = 0; i < MAX_NR_HVC_CONSOLES; ++i)
hvc_poll(i); hvc_poll(i);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment