OSDN Git Service

powerpc/xmon: Avoid tripping SMP hardlockup watchdog
authorNicholas Piggin <npiggin@gmail.com>
Fri, 29 Sep 2017 03:29:40 +0000 (13:29 +1000)
committerMichael Ellerman <mpe@ellerman.id.au>
Wed, 4 Oct 2017 00:26:23 +0000 (11:26 +1100)
The SMP hardlockup watchdog cross-checks other CPUs for lockups, which
causes xmon headaches because it's assuming interrupts hard disabled
means no watchdog troubles. Try to improve that by calling
touch_nmi_watchdog() in obvious places where secondaries are spinning.

Also annotate these spin loops with spin_begin/end calls.

Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
arch/powerpc/xmon/xmon.c

index 33351c6..d9a1210 100644 (file)
@@ -530,14 +530,19 @@ static int xmon_core(struct pt_regs *regs, int fromipi)
 
  waiting:
        secondary = 1;
+       spin_begin();
        while (secondary && !xmon_gate) {
                if (in_xmon == 0) {
-                       if (fromipi)
+                       if (fromipi) {
+                               spin_end();
                                goto leave;
+                       }
                        secondary = test_and_set_bit(0, &in_xmon);
                }
-               barrier();
+               spin_cpu_relax();
+               touch_nmi_watchdog();
        }
+       spin_end();
 
        if (!secondary && !xmon_gate) {
                /* we are the first cpu to come in */
@@ -568,21 +573,25 @@ static int xmon_core(struct pt_regs *regs, int fromipi)
                mb();
                xmon_gate = 1;
                barrier();
+               touch_nmi_watchdog();
        }
 
  cmdloop:
        while (in_xmon) {
                if (secondary) {
+                       spin_begin();
                        if (cpu == xmon_owner) {
                                if (!test_and_set_bit(0, &xmon_taken)) {
                                        secondary = 0;
+                                       spin_end();
                                        continue;
                                }
                                /* missed it */
                                while (cpu == xmon_owner)
-                                       barrier();
+                                       spin_cpu_relax();
                        }
-                       barrier();
+                       spin_cpu_relax();
+                       touch_nmi_watchdog();
                } else {
                        cmd = cmds(regs);
                        if (cmd != 0) {