]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
lockdep: do not automatically collect all backtraces 5296/head
authorJason Dillaman <dillaman@redhat.com>
Mon, 22 Jun 2015 19:30:02 +0000 (15:30 -0400)
committerJason Dillaman <dillaman@redhat.com>
Tue, 28 Jul 2015 20:36:35 +0000 (16:36 -0400)
It is expensive to collect backtraces every time a lock is
checked in order to provide cycle backtraces.  The backtraces
can be forced on for specific locks or globally via the new
config option "lockdep_force_backtrace".

Signed-off-by: Jason Dillaman <dillaman@redhat.com>
(cherry picked from commit 7354d25f56c5e004f288febdee2b6961c069163b)

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

index fb91d612a8b96a6595a10854e078259c7669ebe1..6a4e6b385eead8895879937a0fd380c4a203a006 100644 (file)
@@ -53,7 +53,7 @@ private:
     id = lockdep_register(name.c_str());
   }
   void _will_lock() { // about to lock
-    id = lockdep_will_lock(name.c_str(), id);
+    id = lockdep_will_lock(name.c_str(), id, backtrace);
   }
   void _locked() {    // just locked
     id = lockdep_locked(name.c_str(), id, backtrace);
index 85a602221f2f57bb82b3c99b3368a2c9ed890658..2c6bb038bb6d3807ae94a994b01a14dd9582a36f 100644 (file)
@@ -23,6 +23,7 @@ OPTION(num_client, OPT_INT, 1)
 OPTION(monmap, OPT_STR, "")
 OPTION(mon_host, OPT_STR, "")
 OPTION(lockdep, OPT_BOOL, false)
+OPTION(lockdep_force_backtrace, OPT_BOOL, false) // always gather current backtrace at every lock
 OPTION(run_dir, OPT_STR, "/var/run/ceph")       // the "/var/run/ceph" dir, created on daemon startup
 OPTION(admin_socket, OPT_STR, "$run_dir/$cluster-$name.asok") // default changed by common_preinit()
 
index e0b69e137249f3f74f29bd91b02f8856adaf4ede..ea3f6d55d17b08a59e3da01ca6102cdd3c24f509 100644 (file)
@@ -56,6 +56,12 @@ static list<int> free_ids;
 static ceph::unordered_map<pthread_t, map<int,BackTrace*> > held;
 static BackTrace *follows[MAX_LOCKS][MAX_LOCKS];       // follows[a][b] means b taken after a
 
+static bool lockdep_force_backtrace()
+{
+  return (g_lockdep_ceph_ctx != NULL &&
+          g_lockdep_ceph_ctx->_conf->lockdep_force_backtrace);
+}
+
 /******* Functions **********/
 void lockdep_register_ceph_context(CephContext *cct)
 {
@@ -204,7 +210,7 @@ static bool does_follow(int a, int b)
   return false;
 }
 
-int lockdep_will_lock(const char *name, int id)
+int lockdep_will_lock(const char *name, int id, bool force_backtrace)
 {
   pthread_t p = pthread_self();
   if (id < 0) id = lockdep_register(name);
@@ -234,8 +240,8 @@ int lockdep_will_lock(const char *name, int id)
       // new dependency
 
       // did we just create a cycle?
-      BackTrace *bt = new BackTrace(BACKTRACE_SKIP);
       if (does_follow(id, p->first)) {
+        BackTrace *bt = new BackTrace(BACKTRACE_SKIP);
        lockdep_dout(0) << "new dependency " << lock_names[p->first]
                << " (" << p->first << ") -> " << name << " (" << id << ")"
                << " creates a cycle at\n";
@@ -261,6 +267,10 @@ int lockdep_will_lock(const char *name, int id)
 
        assert(0);  // actually, we should just die here.
       } else {
+        BackTrace *bt = NULL;
+        if (force_backtrace || lockdep_force_backtrace()) {
+          bt = new BackTrace(BACKTRACE_SKIP);
+        }
        follows[p->first][id] = bt;
        lockdep_dout(10) << lock_names[p->first] << " -> " << name << " at" << dendl;
        //bt->print(*_dout);
@@ -280,7 +290,7 @@ int lockdep_locked(const char *name, int id, bool force_backtrace)
 
   pthread_mutex_lock(&lockdep_mutex);
   lockdep_dout(20) << "_locked " << name << dendl;
-  if (g_lockdep >= 2 || force_backtrace)
+  if (force_backtrace || lockdep_force_backtrace())
     held[p][id] = new BackTrace(BACKTRACE_SKIP);
   else
     held[p][id] = 0;
index e9949fd76fa17a902fcd3f6bd71d38f495c65df3..63d2f0dd68e135ec84ad858072b284a1dbabf59b 100644 (file)
@@ -23,7 +23,7 @@ extern void lockdep_register_ceph_context(CephContext *cct);
 extern void lockdep_unregister_ceph_context(CephContext *cct);
 extern int lockdep_register(const char *n);
 extern void lockdep_unregister(int id);
-extern int lockdep_will_lock(const char *n, int id);
+extern int lockdep_will_lock(const char *n, int id, bool force_backtrace=false);
 extern int lockdep_locked(const char *n, int id, bool force_backtrace=false);
 extern int lockdep_will_unlock(const char *n, int id);
 extern int lockdep_dump_locks();