Palacios Public Git Repository

To checkout Palacios execute

  git clone http://v3vee.org/palacios/palacios.web/palacios.git
This will give you the master branch. You probably want the devel branch or one of the release branches. To switch to the devel branch, simply execute
  cd palacios
  git checkout --track -b devel origin/devel
The other branches are similar.


Lock checking enhancement to find frequently used (hot) locks
Peter Dinda [Tue, 18 Jun 2013 19:00:58 +0000 (14:00 -0500)]
linux_module/lockcheck.c
linux_module/lockcheck.h

index 26a33ae..585e314 100644 (file)
@@ -1,6 +1,7 @@
 #include <linux/kernel.h>
 #include <linux/kthread.h>
 #include <linux/spinlock.h>
+#include <linux/sort.h>
 
 #include "palacios.h"
 
 #define CHECK_IRQ_LAST_RELEASE   0
 #define CHECK_IRQ_FIRST_ACQUIRE  1
 
+// Show hottest locks every this many locks or lock_irqsaves
+// 0 indicates this should not be shown
+#define HOT_LOCK_INTERVAL        1000
+
 //
 // Whether lockcheck should lock its own data structures during an
 // event (alloc, dealloc, lock, unlock, etc) and the subsequent
@@ -73,6 +78,7 @@ typedef struct {
   void *lastirqunlocker[STEP_BACK_DEPTH]
                     ; // who last unlocked
   unsigned long lastunlockflags; // their flags
+  int   hotlockcount; // how many times it's been locked
 } lockcheck_state_t;
 
 
@@ -80,9 +86,12 @@ typedef struct {
 // allocation of entries in the global state
 static spinlock_t mylock; 
 static lockcheck_state_t state[NUM_LOCKS];
+static lockcheck_state_t *sorted_state[NUM_LOCKS];
 
 static int numout=0;
 
+static int globallockcount=0;
+
 #define DEBUG_OUTPUT(fmt, args...)                                     \
 do {                                                                   \
   numout++;                                                            \
@@ -282,6 +291,58 @@ static void lock_stack_unlock(void *lock, char irq, unsigned long flags)
 
 }
 
+
+// pointers are to the pointers in the sorted_state array
+int compare(const void *a, const void *b)
+{
+  lockcheck_state_t *l = *((lockcheck_state_t **)a);
+  lockcheck_state_t *r = *((lockcheck_state_t **)b);
+
+  return -(l->hotlockcount - r->hotlockcount);
+}
+
+static void hot_lock_show(void)
+{
+  int n, i;
+  char buf[64];
+
+  n=0;
+  for (i=0;i<NUM_LOCKS;i++) { 
+    if (state[i].inuse) { 
+      sorted_state[n]=&(state[i]);
+      n++;
+    }
+  }
+
+  sort(sorted_state,n,sizeof(lockcheck_state_t *),compare,NULL);
+  
+  for (i=0;i<n;i++) {
+    snprintf(buf,64,"HOT LOCK (%d of %d) %d acquires", i,n,sorted_state[i]->hotlockcount);
+    printlock(buf,sorted_state[i]);
+  }
+}
+
+
+static void hot_lock_lock(void *lock)
+{ 
+  lockcheck_state_t *l = find_lock_entry(lock);
+   
+  if (!l) { return; }
+
+  l->hotlockcount++;
+  globallockcount++;
+
+  if (HOT_LOCK_INTERVAL && !(globallockcount % HOT_LOCK_INTERVAL )) {
+    DEBUG_OUTPUT("LOCKCHECK: Hot locks after %d acquires Follow\n",globallockcount);
+    hot_lock_show();
+  }
+}
+
+
+#define hot_lock_unlock(X) // nothing for now
+
+
+
 void palacios_lockcheck_init()
 {
   memset(state,0,sizeof(lockcheck_state_t)*NUM_LOCKS);
@@ -534,6 +595,8 @@ void palacios_lockcheck_lock(void *lock)
 
   lock_stack_lock(lock,0,0);
 
+  hot_lock_lock(lock);
+
 #if PRINT_LOCK_LOCK
   printlock("LOCK",l);
 #endif
@@ -567,6 +630,8 @@ void palacios_lockcheck_unlock(void *lock)
   }
 
   lock_stack_unlock(lock,0,0);
+
+  hot_lock_unlock(lock);
   
   l->holder=0;
   l->holdingcpu=0;
@@ -616,6 +681,8 @@ void palacios_lockcheck_lock_irqsave(void *lock,unsigned long flags)
 
   lock_stack_lock(lock,1,flags);
 
+  hot_lock_lock(lock);
+
 #if PRINT_LOCK_LOCK
   printlock("LOCK_IRQSAVE",l);
 #endif
@@ -688,6 +755,8 @@ void palacios_lockcheck_unlock_irqrestore_post(void *lock,unsigned long flags)
 
   lock_stack_unlock(lock,1,flags);
 
+  hot_lock_unlock(lock);
+
   backtrace(l->lastirqunlocker);
 
 #if PRINT_LOCK_UNLOCK
index bba3b7e..d80060b 100644 (file)
@@ -47,13 +47,13 @@ void palacios_lockcheck_deinit(void);
 #define LOCKCHECK_INIT()
 #define LOCKCHECK_ALLOC(lock) 
 #define LOCKCHECK_FREE(lock)  
-#define LOCKCHECK_LOCK(lock)  
+#define LOCKCHECK_LOCK_PRE(lock)
+#define LOCKCHECK_LOCK_POST(lock)  
 #define LOCKCHECK_UNLOCK_PRE(lock) 
+#define LOCKCHECK_UNLOCK_POST(lock)
 #define LOCKCHECK_LOCK_IRQSAVE_PRE(lock, flags)  
-#define LOCKCHECK_UNLOCK_IRQRESTORE_PRE(lock, flags) 
-#define LOCKCHECK_LOCK_POST(lock)  
-#define LOCKCHECK_UNLOCK_POST(lock) 
 #define LOCKCHECK_LOCK_IRQSAVE_POST(lock, flags)  
+#define LOCKCHECK_UNLOCK_IRQRESTORE_PRE(lock, flags) 
 #define LOCKCHECK_UNLOCK_IRQRESTORE_POST(lock, flags) 
 #define LOCKCHECK_DEINIT()