Whamcloud - gitweb
Add lu_ref tracking to obd_device.
authornikita <nikita>
Sat, 18 Oct 2008 17:30:57 +0000 (17:30 +0000)
committernikita <nikita>
Sat, 18 Oct 2008 17:30:57 +0000 (17:30 +0000)
b=16450

12 files changed:
lustre/ChangeLog
lustre/include/obd.h
lustre/include/obd_class.h
lustre/ldlm/ldlm_lib.c
lustre/mds/lproc_mds.c
lustre/mds/mds_lov.c
lustre/mdt/mdt_handler.c
lustre/mgc/mgc_request.c
lustre/obdclass/genops.c
lustre/obdclass/linux/linux-module.c
lustre/obdclass/obd_config.c
lustre/ptlrpc/lproc_ptlrpc.c

index ce82ea1..9d78901 100644 (file)
@@ -1670,6 +1670,11 @@ Bugzilla   : 16450
 Description: Add st_block checking to multistat.c.
 Details    : Add st_block checking to multistat.c.
 
+Severity   : minor
+Bugzilla   : 16450
+Description: Add lu_ref support to struct obd_device.
+Details    : Add lu_ref tracking to obd_device.
+
 --------------------------------------------------------------------------------
 
 2007-08-10         Cluster File Systems, Inc. <info@clusterfs.com>
index ebddaa2..76b354f 100644 (file)
@@ -61,6 +61,7 @@
 
 #include <lustre/lustre_idl.h>
 #include <lu_object.h>
+#include <lu_ref.h>
 #include <lustre_lib.h>
 #include <lustre_export.h>
 #include <lustre_quota.h>
@@ -1078,6 +1079,12 @@ struct obd_device {
         rwlock_t               obd_pool_lock;
         int                    obd_pool_limit;
         __u64                  obd_pool_slv;
+
+        /**
+         * A list of outstanding class_incref()'s against this obd. For
+         * debugging.
+         */
+        struct lu_ref          obd_reference;
 };
 
 #define OBD_OPT_FORCE           0x0001
index 1b9535f..2a7cd5e 100644 (file)
@@ -116,8 +116,10 @@ int class_attach(struct lustre_cfg *lcfg);
 int class_setup(struct obd_device *obd, struct lustre_cfg *lcfg);
 int class_cleanup(struct obd_device *obd, struct lustre_cfg *lcfg);
 int class_detach(struct obd_device *obd, struct lustre_cfg *lcfg);
-struct obd_device *class_incref(struct obd_device *obd);
-void class_decref(struct obd_device *obd);
+struct obd_device *class_incref(struct obd_device *obd,
+                                const char *scope, const void *source);
+void class_decref(struct obd_device *obd,
+                  const char *scope, const void *source);
 
 /*obdecho*/
 #ifdef LPROCFS
@@ -188,26 +190,8 @@ void class_del_profiles(void);
 })
 
 /* genops.c */
-#define class_export_get(exp)                                                  \
-({                                                                             \
-        struct obd_export *exp_ = exp;                                         \
-        atomic_inc(&exp_->exp_refcount);                                       \
-        CDEBUG(D_INFO, "GETting export %p : new refcount %d\n", exp_,          \
-               atomic_read(&exp_->exp_refcount));                              \
-        exp_;                                                                  \
-})
-
-#define class_export_put(exp)                                                  \
-do {                                                                           \
-        LASSERT((exp) != NULL);                                                \
-        CDEBUG(D_INFO, "PUTting export %p : new refcount %d\n", (exp),         \
-               atomic_read(&(exp)->exp_refcount) - 1);                         \
-        LASSERT(atomic_read(&(exp)->exp_refcount) > 0);                        \
-        LASSERT(atomic_read(&(exp)->exp_refcount) < 0x5a5a5a);                 \
-        __class_export_put(exp);                                               \
-} while (0)
-
-void __class_export_put(struct obd_export *);
+struct obd_export *class_export_get(struct obd_export *exp);
+void class_export_put(struct obd_export *exp);
 struct obd_export *class_new_export(struct obd_device *obddev,
                                     struct obd_uuid *cluuid);
 void class_unlink_export(struct obd_export *exp);
@@ -478,8 +462,7 @@ static inline int obd_precleanup(struct obd_device *obd,
 #ifdef __KERNEL__
         ldt = obd->obd_type->typ_lu;
         d = obd->obd_lu_dev;
-        if (ldt != NULL) {
-                LASSERT(d != NULL);
+        if (ldt != NULL && d != NULL) {
                 if (cleanup_stage == OBD_CLEANUP_EXPORTS) {
                         struct lu_env env;
 
@@ -513,9 +496,8 @@ static inline int obd_cleanup(struct obd_device *obd)
 #ifdef __KERNEL__
         ldt = obd->obd_type->typ_lu;
         d = obd->obd_lu_dev;
-        if (ldt != NULL) {
+        if (ldt != NULL && d != NULL) {
                 struct lu_env env;
-                LASSERT(d != NULL);
 
                 rc = lu_env_init(&env, NULL, ldt->ldt_ctx_tags);
                 if (rc == 0) {
index 1b21a8d..4d8a62d 100644 (file)
@@ -642,7 +642,7 @@ int target_handle_connect(struct ptlrpc_request *req)
         /* Make sure the target isn't cleaned up while we're here. Yes,
            there's still a race between the above check and our incref here.
            Really, class_uuid2obd should take the ref. */
-        targref = class_incref(target);
+        targref = class_incref(target, __FUNCTION__, cfs_current());
 
 
         str = req_capsule_client_get(&req->rq_pill, &RMF_CLUUID);
@@ -1007,7 +1007,7 @@ out:
                 spin_unlock(&export->exp_lock);
         }
         if (targref)
-                class_decref(targref);
+                class_decref(targref, __FUNCTION__, cfs_current());
         if (rc)
                 req->rq_status = rc;
         RETURN(rc);
@@ -1078,7 +1078,7 @@ struct ptlrpc_request *ptlrpc_clone_req( struct ptlrpc_request *orig_req)
         copy_req->rq_reqmsg = copy_reqmsg;
         copy_req->rq_user_desc = udesc;
 
-        class_export_get(copy_req->rq_export);
+        class_export_rpc_get(copy_req->rq_export);
         CFS_INIT_LIST_HEAD(&copy_req->rq_list);
         CFS_INIT_LIST_HEAD(&copy_req->rq_replay_list);
         sptlrpc_svc_ctx_addref(copy_req);
@@ -1100,7 +1100,7 @@ void ptlrpc_free_clone(struct ptlrpc_request *req)
 
         ptlrpc_req_drop_rs(req);
         sptlrpc_svc_ctx_decref(req);
-        class_export_put(req->rq_export);
+        class_export_rpc_put(req->rq_export);
         list_del(&req->rq_list);
 
         if (req->rq_user_desc) {
index 6349be1..cebd82e 100644 (file)
@@ -112,7 +112,7 @@ static int lprocfs_mds_wr_evict_client(struct file *file, const char *buffer,
 
         /* See the comments in function lprocfs_wr_evict_client() 
          * in ptlrpc/lproc_ptlrpc.c for details. - jay */
-        class_incref(obd);
+        class_incref(obd, __FUNCTION__, cfs_current());
         LPROCFS_EXIT();
 
         obd_export_evict_by_nid(obd, tmpbuf+4);
@@ -124,7 +124,7 @@ static int lprocfs_mds_wr_evict_client(struct file *file, const char *buffer,
                        rc);
 
         LPROCFS_ENTRY();
-        class_decref(obd);
+        class_decref(obd,  __FUNCTION__, cfs_current());
 
         ptlrpc_set_destroy(set);
         return count;
index 01fcd1a..636c430 100644 (file)
@@ -690,7 +690,7 @@ out:
                                    OBD_NOTIFY_INACTIVE, NULL);
         }
 
-        class_decref(obd);
+        class_decref(obd, "mds_lov_synchronize", obd);
         return rc;
 }
 
@@ -733,7 +733,7 @@ int mds_lov_start_synchronize(struct obd_device *obd,
            still disconnected. Taking an obd reference insures that we don't
            disconnect the LOV.  This of course means a cleanup won't
            finish for as long as the sync is blocking. */
-        class_incref(obd);
+        class_incref(obd, "mds_lov_synchronize", obd);
 
         if (nonblock) {
                 /* Synchronize in the background */
@@ -742,7 +742,7 @@ int mds_lov_start_synchronize(struct obd_device *obd,
                 if (rc < 0) {
                         CERROR("%s: error starting mds_lov_synchronize: %d\n",
                                obd->obd_name, rc);
-                        class_decref(obd);
+                        class_decref(obd, "mds_lov_synchronize", obd);
                 } else {
                         CDEBUG(D_HA, "%s: mds_lov_synchronize idx=%d "
                                "thread=%d\n", obd->obd_name,
index ffc8a96..74b2f11 100644 (file)
@@ -3741,6 +3741,7 @@ static struct lu_device *mdt_layer_setup(struct lu_env *env,
                 GOTO(out_alloc, rc);
         }
         lu_device_get(d);
+        lu_ref_add(&d->ld_reference, "lu-stack", &lu_site_init);
 
         RETURN(d);
 
index a78460c..bd1f214 100644 (file)
@@ -421,7 +421,7 @@ static int mgc_fs_setup(struct obd_device *obd, struct super_block *sb,
 
         /* We take an obd ref to insure that we can't get to mgc_cleanup
            without calling mgc_fs_cleanup first. */
-        class_incref(obd);
+        class_incref(obd, "mgc_fs", obd);
 
         label = fsfilt_get_label(obd, mnt->mnt_sb);
         if (label)
@@ -452,7 +452,7 @@ static int mgc_fs_cleanup(struct obd_device *obd)
                 l_dput(cli->cl_mgc_configs_dir);
                 cli->cl_mgc_configs_dir = NULL;
                 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
-                class_decref(obd);
+                class_decref(obd, "mgc_fs", obd);
         }
 
         cli->cl_mgc_vfsmnt = NULL;
index 713a41c..3051655 100644 (file)
@@ -89,9 +89,9 @@ static void obd_device_free(struct obd_device *obd)
                        obd, obd->obd_namespace, obd->obd_force);
                 LBUG();
         }
+        lu_ref_fini(&obd->obd_reference);
         OBD_SLAB_FREE_PTR(obd, obd_device_cachep);
 }
-EXPORT_SYMBOL(obd_device_free);
 
 struct obd_type *class_search_type(const char *name)
 {
@@ -678,8 +678,23 @@ static void export_handle_addref(void *export)
         class_export_get(export);
 }
 
-void __class_export_put(struct obd_export *exp)
+struct obd_export *class_export_get(struct obd_export *exp)
 {
+        atomic_inc(&exp->exp_refcount);
+        CDEBUG(D_INFO, "GETting export %p : new refcount %d\n", exp,
+               atomic_read(&exp->exp_refcount));
+        return exp;
+}
+EXPORT_SYMBOL(class_export_get);
+
+void class_export_put(struct obd_export *exp)
+{
+        LASSERT(exp != NULL);
+        CDEBUG(D_INFO, "PUTting export %p : new refcount %d\n", exp,
+               atomic_read(&exp->exp_refcount) - 1);
+        LASSERT(atomic_read(&exp->exp_refcount) > 0);
+        LASSERT(atomic_read(&exp->exp_refcount) < 0x5a5a5a);
+
         if (atomic_dec_and_test(&exp->exp_refcount)) {
                 LASSERT (list_empty(&exp->exp_obd_chain));
 
@@ -694,9 +709,9 @@ void __class_export_put(struct obd_export *exp)
                         obd_zombie_impexp_notify();
         }
 }
-EXPORT_SYMBOL(__class_export_put);
+EXPORT_SYMBOL(class_export_put);
 
-void class_export_destroy(struct obd_export *exp)
+static void class_export_destroy(struct obd_export *exp)
 {
         struct obd_device *obd = exp->exp_obd;
         ENTRY;
@@ -715,9 +730,9 @@ void class_export_destroy(struct obd_export *exp)
         LASSERT(list_empty(&exp->exp_outstanding_replies));
         LASSERT(list_empty(&exp->exp_req_replay_queue));
         obd_destroy_export(exp);
+        class_decref(obd, "export", exp);
 
         OBD_FREE_RCU(exp, sizeof(*exp), &exp->exp_handle);
-        class_decref(obd);
         EXIT;
 }
 
@@ -768,7 +783,7 @@ struct obd_export *class_new_export(struct obd_device *obd,
         }
 
         LASSERT(!obd->obd_stopping); /* shouldn't happen, but might race */
-        class_incref(obd);
+        class_incref(obd, "export", export);
         list_add(&export->exp_obd_chain, &export->exp_obd->obd_exports);
         list_add_tail(&export->exp_obd_chain_timed,
                       &export->exp_obd->obd_exports_timed);
@@ -865,7 +880,7 @@ void class_import_destroy(struct obd_import *import)
         }
 
         LASSERT(import->imp_sec == NULL);
-        class_decref(import->imp_obd);
+        class_decref(import->imp_obd, "import", import);
         OBD_FREE_RCU(import, sizeof(*import), &import->imp_handle);
         EXIT;
 }
@@ -897,7 +912,7 @@ struct obd_import *class_new_import(struct obd_device *obd)
         spin_lock_init(&imp->imp_lock);
         imp->imp_last_success_conn = 0;
         imp->imp_state = LUSTRE_IMP_NEW;
-        imp->imp_obd = class_incref(obd);
+        imp->imp_obd = class_incref(obd, "import", imp);
         sema_init(&imp->imp_sec_mutex, 1);
         cfs_waitq_init(&imp->imp_recovery_waitq);
 
index 0052ddb..a7feee4 100644 (file)
@@ -298,7 +298,7 @@ static int obd_proc_read_health(char *page, char **start, off_t off,
                 if (obd->obd_stopping)
                         continue;
 
-                class_incref(obd);
+                class_incref(obd, __FUNCTION__, cfs_current());
                 spin_unlock(&obd_dev_lock);
 
                 if (obd_health_check(obd)) {
@@ -306,7 +306,7 @@ static int obd_proc_read_health(char *page, char **start, off_t off,
                                        "device %s reported unhealthy\n",
                                        obd->obd_name);
                 }
-                class_decref(obd);
+                class_decref(obd, __FUNCTION__, cfs_current());
                 spin_lock(&obd_dev_lock);
         }
         spin_unlock(&obd_dev_lock);
index 68adf65..9968043 100644 (file)
@@ -232,6 +232,8 @@ int class_attach(struct lustre_cfg *lcfg)
         spin_lock(&obd->obd_dev_lock);
         atomic_set(&obd->obd_refcount, 1);
         spin_unlock(&obd->obd_dev_lock);
+        lu_ref_init(&obd->obd_reference);
+        lu_ref_add(&obd->obd_reference, "attach", obd);
 
         obd->obd_attached = 1;
         CDEBUG(D_IOCTL, "OBD: dev %d attached type %s with refcount %d\n",
@@ -320,7 +322,7 @@ int class_setup(struct obd_device *obd, struct lustre_cfg *lcfg)
 
         spin_lock(&obd->obd_dev_lock);
         /* cleanup drops this */
-        class_incref(obd);
+        class_incref(obd, "setup", obd);
         spin_unlock(&obd->obd_dev_lock);
 
         CDEBUG(D_IOCTL, "finished setup of obd %s (uuid %s)\n",
@@ -361,7 +363,7 @@ int class_detach(struct obd_device *obd, struct lustre_cfg *lcfg)
         CDEBUG(D_IOCTL, "detach on obd %s (uuid %s)\n",
                obd->obd_name, obd->obd_uuid.uuid);
 
-        class_decref(obd);
+        class_decref(obd, "attach", obd);
 
         /* not strictly necessary, but cleans up eagerly */
         obd_zombie_impexp_cull();
@@ -479,13 +481,15 @@ int class_cleanup(struct obd_device *obd, struct lustre_cfg *lcfg)
         if (err)
                 CERROR("Precleanup %s returned %d\n",
                        obd->obd_name, err);
-        class_decref(obd);
+        class_decref(obd, "setup", obd);
         obd->obd_set_up = 0;
         RETURN(0);
 }
 
-struct obd_device *class_incref(struct obd_device *obd)
+struct obd_device *class_incref(struct obd_device *obd,
+                                const char *scope, const void *source)
 {
+        lu_ref_add_atomic(&obd->obd_reference, scope, source);
         atomic_inc(&obd->obd_refcount);
         CDEBUG(D_INFO, "incref %s (%p) now %d\n", obd->obd_name, obd,
                atomic_read(&obd->obd_refcount));
@@ -493,7 +497,7 @@ struct obd_device *class_incref(struct obd_device *obd)
         return obd;
 }
 
-void class_decref(struct obd_device *obd)
+void class_decref(struct obd_device *obd, const char *scope, const void *source)
 {
         int err;
         int refs;
@@ -502,6 +506,7 @@ void class_decref(struct obd_device *obd)
         atomic_dec(&obd->obd_refcount);
         refs = atomic_read(&obd->obd_refcount);
         spin_unlock(&obd->obd_dev_lock);
+        lu_ref_del(&obd->obd_reference, scope, source);
 
         CDEBUG(D_INFO, "Decref %s (%p) now %d\n", obd->obd_name, obd, refs);
 
index 8eb11fc..abe69ed 100644 (file)
@@ -631,7 +631,7 @@ int lprocfs_wr_evict_client(struct file *file, const char *buffer,
          * the proc entries under the being destroyed export{}, so I have
          * to drop the lock at first here.
          * - jay, jxiong@clusterfs.com */
-        class_incref(obd);
+        class_incref(obd, __FUNCTION__, cfs_current());
         LPROCFS_EXIT();
 
         sscanf(buffer, "%40s", tmpbuf);
@@ -643,7 +643,7 @@ int lprocfs_wr_evict_client(struct file *file, const char *buffer,
                 obd_export_evict_by_uuid(obd, tmpbuf);
 
         LPROCFS_ENTRY();
-        class_decref(obd);
+        class_decref(obd, __FUNCTION__, cfs_current());
 
         return count;
 }