[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-devel] [PATCH 3/4] xen: print lock profile info in panic()



Print the lock profile data when the system crashes and add some more
information for each lock data (lock address, cpu holding the lock).

This is especially beneficial for watchdog triggered crashes in case
of deadlocks.

In order to have the cpu holding the lock available let the
LOCK_PROFILE config option select SPINLOCK_DEBUG.

As printing the lock profile data will make use of locking, too, we
need to disable spinlock debugging before calling
spinlock_profile_printall() from panic().

While at it remove a superfluous #ifdef CONFIG_LOCK_PROFILE.

Signed-off-by: Juergen Gross <jgross@xxxxxxxx>
---
 xen/Kconfig.debug          |  1 +
 xen/common/spinlock.c      | 11 +++++++----
 xen/drivers/char/console.c |  4 +++-
 xen/include/xen/spinlock.h |  1 +
 4 files changed, 12 insertions(+), 5 deletions(-)

diff --git a/xen/Kconfig.debug b/xen/Kconfig.debug
index 5db3e7ec25..a7387f1630 100644
--- a/xen/Kconfig.debug
+++ b/xen/Kconfig.debug
@@ -53,6 +53,7 @@ config SPINLOCK_DEBUG
 
 config LOCK_PROFILE
        bool "Lock Profiling"
+       select SPINLOCK_DEBUG
        ---help---
          Lock profiling allows you to see how often locks are taken and 
blocked.
          You can use serial console to print (and reset) using 'l' and 'L'
diff --git a/xen/common/spinlock.c b/xen/common/spinlock.c
index 16356ec9b7..5730076581 100644
--- a/xen/common/spinlock.c
+++ b/xen/common/spinlock.c
@@ -362,10 +362,13 @@ static void spinlock_profile_iterate(lock_profile_subfunc 
*sub, void *par)
 static void spinlock_profile_print_elem(struct lock_profile *data,
     int32_t type, int32_t idx, void *par)
 {
-    if ( type == LOCKPROF_TYPE_GLOBAL )
-        printk("%s %s:\n", lock_profile_ancs[type].name, data->name);
-    else
-        printk("%s %d %s:\n", lock_profile_ancs[type].name, idx, data->name);
+    struct spinlock *lock = data->lock;
+
+    printk("%s ", lock_profile_ancs[type].name);
+    if ( type != LOCKPROF_TYPE_GLOBAL )
+        printk("%d ", idx);
+    printk("%s: addr=%p, lockval=%04x, cpu=%d\n", data->name, lock,
+           lock->tickets.head_tail, lock->debug.cpu);
     printk("  lock:%12"PRId64"(%08X:%08X), block:%12"PRId64"(%08X:%08X)\n",
            data->lock_cnt, (u32)(data->time_hold >> 32), (u32)data->time_hold,
            data->block_cnt, (u32)(data->time_block >> 32),
diff --git a/xen/drivers/char/console.c b/xen/drivers/char/console.c
index 1680d078db..404d28a725 100644
--- a/xen/drivers/char/console.c
+++ b/xen/drivers/char/console.c
@@ -1167,7 +1167,9 @@ void panic(const char *fmt, ...)
     unsigned long flags;
     static DEFINE_SPINLOCK(lock);
     static char buf[128];
-    
+
+    spin_debug_disable();
+    spinlock_profile_printall('\0');
     debugtrace_dump();
 
     /* Protects buf[] and ensure multi-line message prints atomically. */
diff --git a/xen/include/xen/spinlock.h b/xen/include/xen/spinlock.h
index e3458f10dd..26891445fe 100644
--- a/xen/include/xen/spinlock.h
+++ b/xen/include/xen/spinlock.h
@@ -130,6 +130,7 @@ struct lock_profile_qhead { };
 #define spin_lock_init_prof(s, l) spin_lock_init(&((s)->l))
 #define lock_profile_register_struct(type, ptr, idx, print)
 #define lock_profile_deregister_struct(type, ptr)
+#define spinlock_profile_printall(key)
 
 #endif
 
-- 
2.16.4


_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/mailman/listinfo/xen-devel

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.