lib: ipipe: make dump_stack() domain-aware
authorPhilippe Gerum <rpm@xenomai.org>
Thu, 9 Nov 2017 11:24:04 +0000 (12:24 +0100)
committerMarek Szyprowski <m.szyprowski@samsung.com>
Fri, 27 Apr 2018 09:21:34 +0000 (11:21 +0200)
When dumping a stack backtrace, we neither need nor want to disable
root stage IRQs over the head stage, where CPU migration can't
happen.

Conversely, we neither need nor want to disable hard IRQs from the
head stage, so that latency won't skyrocket either.

lib/dump_stack.c

index c5edbedd364dce20f028614c0b7679878e70913d..898178dc667b39dad899a937e93fbc2ea7907d89 100644 (file)
@@ -10,6 +10,7 @@
 #include <linux/sched/debug.h>
 #include <linux/smp.h>
 #include <linux/atomic.h>
+#include <linux/ipipe.h>
 
 static void __dump_stack(void)
 {
@@ -25,6 +26,29 @@ static void __dump_stack(void)
 #ifdef CONFIG_SMP
 static atomic_t dump_lock = ATOMIC_INIT(-1);
 
+static unsigned long disable_local_irqs(void)
+{
+       unsigned long flags = 0; /* only to trick the UMR detection */
+
+       /*
+        * We neither need nor want to disable root stage IRQs over
+        * the head stage, where CPU migration can't
+        * happen. Conversely, we neither need nor want to disable
+        * hard IRQs from the head stage, so that latency won't
+        * skyrocket as a result of dumping the stack backtrace.
+        */
+       if (ipipe_root_p)
+               local_irq_save(flags);
+
+       return flags;
+}
+
+static void restore_local_irqs(unsigned long flags)
+{
+       if (ipipe_root_p)
+               local_irq_restore(flags);
+}
+
 asmlinkage __visible void dump_stack(void)
 {
        unsigned long flags;
@@ -37,7 +61,7 @@ asmlinkage __visible void dump_stack(void)
         * against other CPUs
         */
 retry:
-       local_irq_save(flags);
+       flags = disable_local_irqs();
        cpu = smp_processor_id();
        old = atomic_cmpxchg(&dump_lock, -1, cpu);
        if (old == -1) {
@@ -45,7 +69,7 @@ retry:
        } else if (old == cpu) {
                was_locked = 1;
        } else {
-               local_irq_restore(flags);
+               restore_local_irqs(flags);
                cpu_relax();
                goto retry;
        }
@@ -55,7 +79,7 @@ retry:
        if (!was_locked)
                atomic_set(&dump_lock, -1);
 
-       local_irq_restore(flags);
+       restore_local_irqs(flags);
 }
 #else
 asmlinkage __visible void dump_stack(void)