From: nikita Date: Sat, 18 Oct 2008 17:30:57 +0000 (+0000) Subject: Add lu_ref tracking to obd_device. X-Git-Tag: v1_9_90~52 X-Git-Url: https://git.whamcloud.com/?p=fs%2Flustre-release.git;a=commitdiff_plain;h=b893c0d0269210b125da0481d17b18f5b06fec1d Add lu_ref tracking to obd_device. b=16450 --- diff --git a/lustre/ChangeLog b/lustre/ChangeLog index ce82ea1..9d78901 100644 --- a/lustre/ChangeLog +++ b/lustre/ChangeLog @@ -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. diff --git a/lustre/include/obd.h b/lustre/include/obd.h index ebddaa2..76b354f 100644 --- a/lustre/include/obd.h +++ b/lustre/include/obd.h @@ -61,6 +61,7 @@ #include #include +#include #include #include #include @@ -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 diff --git a/lustre/include/obd_class.h b/lustre/include/obd_class.h index 1b9535f..2a7cd5e 100644 --- a/lustre/include/obd_class.h +++ b/lustre/include/obd_class.h @@ -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) { diff --git a/lustre/ldlm/ldlm_lib.c b/lustre/ldlm/ldlm_lib.c index 1b21a8d..4d8a62d 100644 --- a/lustre/ldlm/ldlm_lib.c +++ b/lustre/ldlm/ldlm_lib.c @@ -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(©_req->rq_list); CFS_INIT_LIST_HEAD(©_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) { diff --git a/lustre/mds/lproc_mds.c b/lustre/mds/lproc_mds.c index 6349be1..cebd82e 100644 --- a/lustre/mds/lproc_mds.c +++ b/lustre/mds/lproc_mds.c @@ -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; diff --git a/lustre/mds/mds_lov.c b/lustre/mds/mds_lov.c index 01fcd1a..636c430 100644 --- a/lustre/mds/mds_lov.c +++ b/lustre/mds/mds_lov.c @@ -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, diff --git a/lustre/mdt/mdt_handler.c b/lustre/mdt/mdt_handler.c index ffc8a96..74b2f11 100644 --- a/lustre/mdt/mdt_handler.c +++ b/lustre/mdt/mdt_handler.c @@ -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); diff --git a/lustre/mgc/mgc_request.c b/lustre/mgc/mgc_request.c index a78460c..bd1f214 100644 --- a/lustre/mgc/mgc_request.c +++ b/lustre/mgc/mgc_request.c @@ -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; diff --git a/lustre/obdclass/genops.c b/lustre/obdclass/genops.c index 713a41c..3051655 100644 --- a/lustre/obdclass/genops.c +++ b/lustre/obdclass/genops.c @@ -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); diff --git a/lustre/obdclass/linux/linux-module.c b/lustre/obdclass/linux/linux-module.c index 0052ddb..a7feee4 100644 --- a/lustre/obdclass/linux/linux-module.c +++ b/lustre/obdclass/linux/linux-module.c @@ -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); diff --git a/lustre/obdclass/obd_config.c b/lustre/obdclass/obd_config.c index 68adf65..9968043 100644 --- a/lustre/obdclass/obd_config.c +++ b/lustre/obdclass/obd_config.c @@ -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); diff --git a/lustre/ptlrpc/lproc_ptlrpc.c b/lustre/ptlrpc/lproc_ptlrpc.c index 8eb11fc..abe69ed 100644 --- a/lustre/ptlrpc/lproc_ptlrpc.c +++ b/lustre/ptlrpc/lproc_ptlrpc.c @@ -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; }