[Sound-open-firmware] [PATCH] lock: debug: Improve and document lock debug trace output.

Liam Girdwood liam.r.girdwood at linux.intel.com
Wed Nov 15 22:16:34 CET 2017


Make it easy to find deadlocks and lock holders in atomic and non
atomic contexts.

Signed-off-by: Liam Girdwood <liam.r.girdwood at linux.intel.com>
---
 src/include/reef/lock.h | 41 +++++++++++++++++++++++++++++++++++++----
 1 file changed, 37 insertions(+), 4 deletions(-)

diff --git a/src/include/reef/lock.h b/src/include/reef/lock.h
index 8b05ef2..eef2a3a 100644
--- a/src/include/reef/lock.h
+++ b/src/include/reef/lock.h
@@ -41,12 +41,42 @@
 #include <reef/interrupt.h>
 #include <reef/trace.h>
 
+/*
+ * Lock debugging provides a simple interface to debug deadlocks. The rmbox
+ * trace output will show an output :-
+ *
+ * 0xd70 [41.306406]	delta [0.359638]	lock eal
+ * 0xd80 [41.306409]	delta [0.000002]	value 0x00000000000001b7
+ * 0xd90 [41.306411]	delta [0.000002]	value 0x0000000000000001
+ * 0xda0 [41.306413]	delta [0.000002]	value 0x0000000001000348
+ *
+ * "eal" indicates we are holding a lock with interrupts OFF. The next value
+ * is the line number of where the lock was aquired. The second number is the
+ * number of other locks held whilst this lock is held and the subsequent
+ * numbers list each lock and the line number of it's holder. e.g. to find
+ * the locks :-
+ *
+ * grep -rn lock --include *.c | grep 840   (search for lock at line 0x348)
+ *     src/drivers/dw-dma.c:840:	spinlock_init(&dma->lock);
+ *
+ * grep -rn lock --include *.c | grep 439
+ *     src/lib/alloc.c:439:	spin_lock_irq(&memmap.lock, flags);
+ *
+ * Every lock entry and exit shows LcE and LcX in trace alonside the lock
+ * line numbers in hex. e.g.
+ *
+ * 0xfd60 [11032.730567]	delta [0.000004]	lock LcE
+ * 0xfd70 [11032.730569]	delta [0.000002]	value 0x00000000000000ae
+ *
+ * Deadlock would be a LcE without a subsequent LcX.
+ *
+ */
 
 #if DEBUG_LOCKS
 
 #define DBG_LOCK_USERS		8
 
-#define trace_lock(__e)		trace_event_atomic(TRACE_CLASS_LOCK, __e)
+#define trace_lock(__e)		trace_error_atomic(TRACE_CLASS_LOCK, __e)
 #define tracev_lock(__e)	tracev_event_atomic(TRACE_CLASS_LOCK, __e)
 #define trace_lock_error(__e)	trace_error_atomic(TRACE_CLASS_LOCK, __e)
 #define trace_lock_value(__e)	_trace_error_atomic(__e)
@@ -55,10 +85,12 @@ extern uint32_t lock_dbg_atomic;
 extern uint32_t lock_dbg_user[DBG_LOCK_USERS];
 
 #define spin_lock_dbg() \
-	trace_lock("LcE");
+	trace_lock("LcE"); \
+	trace_lock_value(__LINE__);
 
 #define spin_unlock_dbg() \
-	trace_lock("LcX");
+	trace_lock("LcX"); \
+	trace_lock_value(__LINE__); \
 
 /* all SMP spinlocks need init, nothing todo on UP */
 #define spinlock_init(lock) \
@@ -89,8 +121,9 @@ extern uint32_t lock_dbg_user[DBG_LOCK_USERS];
 /* disables all IRQ sources and takes lock - enter atomic context */
 #define spin_lock_irq(lock, flags) \
 	flags = interrupt_global_disable(); \
+	lock_dbg_atomic++; \
 	spin_lock(lock); \
-	if (++lock_dbg_atomic < DBG_LOCK_USERS) \
+	if (lock_dbg_atomic < DBG_LOCK_USERS) \
 		lock_dbg_user[lock_dbg_atomic - 1] = (lock)->user;
 
 /* re-enables current IRQ sources and releases lock - leave atomic context */
-- 
1.9.1



More information about the Sound-open-firmware mailing list