]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
lockdep: force backtraces on specific mutexes
authorSage Weil <sage@newdream.net>
Sat, 15 Nov 2008 00:58:17 +0000 (16:58 -0800)
committerSage Weil <sage@newdream.net>
Sat, 15 Nov 2008 05:14:53 +0000 (21:14 -0800)
Maintaining backtraces is expensive to do for every acquisition.  Make a
per-mutex flag so that specific deadlocks can be tracked down.

src/common/Mutex.h
src/common/lockdep.cc
src/common/lockdep.h

index a6490cc975192d40dbdd0044f3d76f8e4fb04ee0..913a312ee4fb4322387acef4b88c4a718f245375 100755 (executable)
@@ -28,6 +28,7 @@ private:
   int id;
   bool recursive;
   bool lockdep;
+  bool backtrace;  // gather backtrace on lock acquisition
 
   pthread_mutex_t _m;
   int nlock;
@@ -44,7 +45,7 @@ private:
     id = lockdep_will_lock(name, id);
   }
   void _locked() {    // just locked
-    id = lockdep_locked(name, id);
+    id = lockdep_locked(name, id, backtrace);
   }
   void _unlocked() {  // just unlocked
     id = lockdep_unlocked(name, id);
@@ -57,7 +58,8 @@ private:
 #endif
 
 public:
-  Mutex(const char *n, bool r = false, bool ld=true) : name(n), id(-1), recursive(r), lockdep(ld), nlock(0) {
+  Mutex(const char *n, bool r = false, bool ld=true, bool bt=false) :
+    name(n), id(-1), recursive(r), lockdep(ld), backtrace(bt), nlock(0) {
     if (recursive) {
       pthread_mutexattr_t attr;
       pthread_mutexattr_init(&attr);
index 2c5f017421180a26cc7666e25c2288405bbb43b3..4c0bf6296dbebdf48c67036e95c3d896f1bd4424 100644 (file)
@@ -104,7 +104,7 @@ int lockdep_will_lock(const char *name, int id)
       dout(0) << "recursive lock of " << name << " (" << id << ")" << std::endl;
       BackTrace *bt = new BackTrace(BACKTRACE_SKIP);
       bt->print(*_dout);
-      if (g_lockdep >= 2) {
+      if (p->second) {
        *_dout << std::endl;
        dout(0) << "previously locked at" << std::endl;
        p->second->print(*_dout);
@@ -129,7 +129,7 @@ int lockdep_will_lock(const char *name, int id)
             q != m.end();
             q++) {
          dout(0) << "  " << lock_names[q->first] << " (" << q->first << ")" << std::endl;
-         if (g_lockdep >= 2) {
+         if (q->second) {
            q->second->print(*_dout);
            *_dout << std::endl;
          }
@@ -154,7 +154,7 @@ int lockdep_will_lock(const char *name, int id)
   return id;
 }
 
-int lockdep_locked(const char *name, int id)
+int lockdep_locked(const char *name, int id, bool force_backtrace)
 {
   pthread_t p = pthread_self();
 
@@ -162,7 +162,7 @@ int lockdep_locked(const char *name, int id)
 
   pthread_mutex_lock(&lockdep_mutex);
   dout(20) << "_locked " << name << std::endl;
-  if (g_lockdep >= 2)
+  if (g_lockdep >= 2 || force_backtrace)
     held[p][id] = new BackTrace(BACKTRACE_SKIP);
   else
     held[p][id] = 0;
index 00026b30b972179f7f05600540d377e288a12370..6d39efeb510ec71337eae0f70cef44aa6a2b69b7 100644 (file)
@@ -5,7 +5,7 @@ extern int g_lockdep;
 
 extern int lockdep_register(const char *n);
 extern int lockdep_will_lock(const char *n, int id);
-extern int lockdep_locked(const char *n, int id);
+extern int lockdep_locked(const char *n, int id, bool force_backtrace=false);
 extern int lockdep_unlocked(const char *n, int id);
 
 #endif