From: Anton Blanchard Also add cpu_relax() to several spinloops in xmon which wait for other cpus. --- arch/ppc64/xmon/xmon.c | 14 +++++++++----- drivers/char/hvc_console.c | 9 +++++---- 2 files changed, 14 insertions(+), 9 deletions(-) diff -puN arch/ppc64/xmon/xmon.c~ppc64-xmon-cpumask arch/ppc64/xmon/xmon.c --- 25/arch/ppc64/xmon/xmon.c~ppc64-xmon-cpumask 2004-02-04 02:24:54.000000000 -0800 +++ 25-akpm/arch/ppc64/xmon/xmon.c 2004-02-04 02:24:54.000000000 -0800 @@ -16,6 +16,7 @@ #include #include #include +#include #include #include @@ -37,7 +38,7 @@ #define skipbl xmon_skipbl #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 volatile int take_xmon = -1; static volatile int leaving_xmon = 0; @@ -288,17 +289,18 @@ xmon(struct pt_regs *excp) leaving_xmon = 0; /* possible race condition here if a CPU is held up and gets * 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 */ printf("We are already in xmon\n"); for (;;) - ; + cpu_relax(); } while (test_and_set_bit(0, &got_xmon)) { if (take_xmon == smp_processor_id()) { take_xmon = -1; break; } + cpu_relax(); } /* * XXX: breakpoints are removed while any cpu is in xmon @@ -325,7 +327,7 @@ xmon(struct pt_regs *excp) leaving_xmon = 1; if (cmd != 's') clear_bit(0, &got_xmon); - clear_bit(smp_processor_id(), &cpus_in_xmon); + cpu_clear(smp_processor_id(), cpus_in_xmon); #endif /* CONFIG_SMP */ set_msrd(msr); /* restore interrupt enable */ } @@ -602,6 +604,7 @@ cmds(struct pt_regs *excp) printf(" (type ? for help)\n"); break; } + cpu_relax(); } } @@ -638,7 +641,7 @@ static void cpu_cmd(void) /* print cpus waiting or in xmon */ printf("cpus stopped:"); for (cpu = 0; cpu < NR_CPUS; ++cpu) { - if (test_bit(cpu, &cpus_in_xmon)) { + if (cpu_isset(cpu, cpus_in_xmon)) { printf(" %x", cpu); if (cpu == smp_processor_id()) printf("*", cpu); @@ -664,6 +667,7 @@ static void cpu_cmd(void) take_xmon = -1; break; } + cpu_relax(); } } #endif /* CONFIG_SMP */ diff -puN drivers/char/hvc_console.c~ppc64-xmon-cpumask drivers/char/hvc_console.c --- 25/drivers/char/hvc_console.c~ppc64-xmon-cpumask 2004-02-04 02:24:54.000000000 -0800 +++ 25-akpm/drivers/char/hvc_console.c 2004-02-04 02:24:54.000000000 -0800 @@ -29,6 +29,7 @@ #include #include #include +#include extern int hvc_count(int *); extern int hvc_get_chars(int index, char *buf, int count); @@ -223,10 +224,10 @@ static void hvc_poll(int index) spin_unlock_irqrestore(&hp->lock, flags); } -#if defined (CONFIG_XMON) -extern unsigned long cpus_in_xmon; +#if defined(CONFIG_XMON) && defined(CONFIG_SMP) +extern cpumask_t cpus_in_xmon; #else -unsigned long cpus_in_xmon=0; +static const cpumask_t cpus_in_xmon = CPU_MASK_NONE; #endif @@ -237,7 +238,7 @@ int khvcd(void *unused) daemonize("khvcd"); for (;;) { - if (!cpus_in_xmon) { + if (cpus_empty(cpus_in_xmon)) { for (i = 0; i < MAX_NR_HVC_CONSOLES; ++i) hvc_poll(i); } _