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);
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()
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)
{
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);
// 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";
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);
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;
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();