Skip to content

Commit

Permalink
powerpc/xmon: Don't loop forever in get_output_lock()
Browse files Browse the repository at this point in the history
If we enter with xmon_speaker != 0 we skip the first cmpxchg(), we also
skip the while loop because xmon_speaker != last_speaker (0) - meaning we
skip the second cmpxchg() also.

Following that code path the compiler sees no memory barriers and so is
within its rights to never reload xmon_speaker. The end result is we loop
forever.

This manifests as all cpus being in xmon ('c' command), but they refuse
to take control when you switch to them ('c x' for cpu # x).

I have seen this deadlock in practice and also checked the generated code to
confirm this is what's happening.

The simplest fix is just to always try the cmpxchg().

Signed-off-by: Michael Ellerman <michael@ellerman.id.au>
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
  • Loading branch information
Michael Ellerman authored and Benjamin Herrenschmidt committed Feb 11, 2014
1 parent b4d6c06 commit 730efb6
Showing 1 changed file with 5 additions and 5 deletions.
10 changes: 5 additions & 5 deletions arch/powerpc/xmon/xmon.c
Original file line number Diff line number Diff line change
Expand Up @@ -309,12 +309,12 @@ static void get_output_lock(void)

if (xmon_speaker == me)
return;

for (;;) {
if (xmon_speaker == 0) {
last_speaker = cmpxchg(&xmon_speaker, 0, me);
if (last_speaker == 0)
return;
}
last_speaker = cmpxchg(&xmon_speaker, 0, me);
if (last_speaker == 0)
return;

timeout = 10000000;
while (xmon_speaker == last_speaker) {
if (--timeout > 0)
Expand Down

0 comments on commit 730efb6

Please sign in to comment.