Message ID | 20171215063817.GX7829@linux.vnet.ibm.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Hi Paul, On Fri, Dec 15, 2017 at 4:38 AM, Paul E. McKenney <paulmck@linux.vnet.ibm.com> wrote: > For your amusement, I have a patch below that takes a paranoid view of > the possible answers to these questions. This patch is untested and > probably does not even build. Plus its polling loop is quite naive. I tried to build it, but if fails to link: LD vmlinux.o MODPOST vmlinux.o arch/arm/kernel/smp.o: In function `__cpu_die': smp.c:(.text+0x44c): undefined reference to `__bad_xchg' Makefile:1024: recipe for target 'vmlinux' failed make: *** [vmlinux] Error 1 Thanks
On Fri, Dec 15, 2017 at 11:16:43AM -0200, Fabio Estevam wrote: > Hi Paul, > > On Fri, Dec 15, 2017 at 4:38 AM, Paul E. McKenney > <paulmck@linux.vnet.ibm.com> wrote: > > > For your amusement, I have a patch below that takes a paranoid view of > > the possible answers to these questions. This patch is untested and > > probably does not even build. Plus its polling loop is quite naive. > > I tried to build it, but if fails to link: > > LD vmlinux.o > MODPOST vmlinux.o > arch/arm/kernel/smp.o: In function `__cpu_die': > smp.c:(.text+0x44c): undefined reference to `__bad_xchg' > Makefile:1024: recipe for target 'vmlinux' failed > make: *** [vmlinux] Error 1 OK, I will need to make a better choice of atomic operation. Thank you for testing this! Thanx, Paul
diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c index b4fbf00ee4ad..da363923503b 100644 --- a/arch/arm/kernel/smp.c +++ b/arch/arm/kernel/smp.c @@ -241,7 +241,7 @@ int __cpu_disable(void) return 0; } -static DECLARE_COMPLETION(cpu_died); +static char cpu_died; /* * called on the thread which is asking for a CPU to be shutdown - @@ -249,7 +249,16 @@ static DECLARE_COMPLETION(cpu_died); */ void __cpu_die(unsigned int cpu) { - if (!wait_for_completion_timeout(&cpu_died, msecs_to_jiffies(5000))) { + unsigned long deadline = jiffies + msecs_to_jiffies(5000); + char ret; + + while (time_before(jiffies, deadline)) { + ret = xchg(&cpu_died, 0); + if (ret) + break; + schedule_timeout_interruptible(1); + } + if (!ret) { pr_err("CPU%u: cpu didn't die\n", cpu); return; } @@ -295,7 +304,7 @@ void arch_cpu_idle_dead(void) * this returns, power and/or clocks can be removed at any point * from this CPU and its cache by platform_cpu_kill(). */ - complete(&cpu_died); + WRITE_ONCE(cpu_died, 1); /* * Ensure that the cache lines associated with that completion are