mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-01-23 16:53:58 -05:00
powerpc/xmon: Don't loop forever in get_output_lock()
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>
This commit is contained in:
parent
b4d6c06c8d
commit
730efb6193
1 changed files with 5 additions and 5 deletions
|
@ -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)
|
||||
|
|
Loading…
Add table
Reference in a new issue