From: Peter Dinda Date: Tue, 18 Jun 2013 19:00:58 +0000 (-0500) Subject: Lock checking enhancement to find frequently used (hot) locks X-Git-Url: http://v3vee.org/palacios/gitweb/gitweb.cgi?a=commitdiff_plain;h=2e60260d6bcf3ebe22011b7d65746c001162f739;p=palacios.releases.git Lock checking enhancement to find frequently used (hot) locks --- diff --git a/linux_module/lockcheck.c b/linux_module/lockcheck.c index 26a33ae..585e314 100644 --- a/linux_module/lockcheck.c +++ b/linux_module/lockcheck.c @@ -1,6 +1,7 @@ #include #include #include +#include #include "palacios.h" @@ -41,6 +42,10 @@ #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;ihotlockcount); + 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 diff --git a/linux_module/lockcheck.h b/linux_module/lockcheck.h index bba3b7e..d80060b 100644 --- a/linux_module/lockcheck.h +++ b/linux_module/lockcheck.h @@ -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()