From cbfee37be595d9f378e25b81f516839caa3ee7ff Mon Sep 17 00:00:00 2001 From: nikita <nikita> Date: Sat, 18 Oct 2008 17:19:11 +0000 Subject: [PATCH] Add lu_ref support to lu_object and lu_device. lu_ref is used to track leaked references. b=16450 --- lustre/ChangeLog | 6 +++++ lustre/cmm/cmm_device.c | 4 +++- lustre/include/lu_object.h | 24 +++++++++++++++++++ lustre/obdclass/lu_object.c | 46 ++++++++++++++++++++++++------------- lustre/osd/osd_handler.c | 19 ++++++++------- 5 files changed, 74 insertions(+), 25 deletions(-) diff --git a/lustre/ChangeLog b/lustre/ChangeLog index a0e72e8760..ba2f2f2d52 100644 --- a/lustre/ChangeLog +++ b/lustre/ChangeLog @@ -1615,6 +1615,12 @@ Details : Introduce two new methods in lu_device_type_operations, that are invoked when first instance of a given type is created and last one is destroyed respectively. This is need by CLIO. +Severity : normal +Bugzilla : 16450 +Description: Add lu_ref support to struct lu_device. +Details : Add lu_ref support to lu_object and lu_device. lu_ref is used to + track leaked references. + -------------------------------------------------------------------------------- 2007-08-10 Cluster File Systems, Inc. <info@clusterfs.com> diff --git a/lustre/cmm/cmm_device.c b/lustre/cmm/cmm_device.c index 38c62da657..a5263079e2 100644 --- a/lustre/cmm/cmm_device.c +++ b/lustre/cmm/cmm_device.c @@ -168,6 +168,7 @@ static int cmm_add_mdc(const struct lu_env *env, struct mdc_device *mc, *tmp; struct lu_fld_target target; struct lu_device *ld; + struct lu_device *cmm_lu = cmm2lu_dev(cm); mdsno_t mdc_num; int rc; ENTRY; @@ -223,7 +224,8 @@ static int cmm_add_mdc(const struct lu_env *env, cm->cmm_tgt_count++; spin_unlock(&cm->cmm_tgt_guard); - lu_device_get(cmm2lu_dev(cm)); + lu_device_get(cmm_lu); + lu_ref_add(&cmm_lu->ld_reference, "mdc-child", ld); target.ft_srv = NULL; target.ft_idx = mc->mc_num; diff --git a/lustre/include/lu_object.h b/lustre/include/lu_object.h index 50665df760..138c58669a 100644 --- a/lustre/include/lu_object.h +++ b/lustre/include/lu_object.h @@ -465,6 +465,10 @@ struct lu_object { * Flags from enum lu_object_flags. */ unsigned long lo_flags; + /** + * Link to the device, for debugging. + */ + struct lu_ref_link *lo_dev_ref; }; enum lu_object_header_flags { @@ -869,6 +873,26 @@ static inline __u32 lu_object_attr(const struct lu_object *o) return o->lo_header->loh_attr; } +static inline struct lu_ref_link *lu_object_ref_add(struct lu_object *o, + const char *scope, + const void *source) +{ + return lu_ref_add(&o->lo_header->loh_reference, scope, source); +} + +static inline void lu_object_ref_del(struct lu_object *o, + const char *scope, const void *source) +{ + lu_ref_del(&o->lo_header->loh_reference, scope, source); +} + +static inline void lu_object_ref_del_at(struct lu_object *o, + struct lu_ref_link *link, + const char *scope, const void *source) +{ + lu_ref_del_at(&o->lo_header->loh_reference, link, scope, source); +} + struct lu_rdpg { /* input params, should be filled out by mdt */ __u64 rp_hash; /* hash */ diff --git a/lustre/obdclass/lu_object.c b/lustre/obdclass/lu_object.c index a097d69e85..5077327efe 100644 --- a/lustre/obdclass/lu_object.c +++ b/lustre/obdclass/lu_object.c @@ -596,7 +596,7 @@ enum { LU_CACHE_PERCENT = 20, }; -/* +/** * Return desired hash table order. */ static int lu_htable_order(void) @@ -628,8 +628,10 @@ static int lu_htable_order(void) return bits; } -/* - * Initialize site @s, with @d as the top level device. +static struct lock_class_key lu_site_guard_class; + +/** + * Initialize site \a s, with \a d as the top level device. */ int lu_site_init(struct lu_site *s, struct lu_device *top) { @@ -640,11 +642,14 @@ int lu_site_init(struct lu_site *s, struct lu_device *top) memset(s, 0, sizeof *s); rwlock_init(&s->ls_guard); + lockdep_set_class(&s->ls_guard, &lu_site_guard_class); CFS_INIT_LIST_HEAD(&s->ls_lru); CFS_INIT_LIST_HEAD(&s->ls_linkage); + cfs_waitq_init(&s->ls_marche_funebre); s->ls_top_dev = top; top->ld_site = s; lu_device_get(top); + lu_ref_add(&top->ld_reference, "site-top", s); for (bits = lu_htable_order(), size = 1 << bits; (s->ls_hash = @@ -667,8 +672,8 @@ int lu_site_init(struct lu_site *s, struct lu_device *top) } EXPORT_SYMBOL(lu_site_init); -/* - * Finalize @s and release its resources. +/** + * Finalize \a s and release its resources. */ void lu_site_fini(struct lu_site *s) { @@ -688,13 +693,14 @@ void lu_site_fini(struct lu_site *s) } if (s->ls_top_dev != NULL) { s->ls_top_dev->ld_site = NULL; + lu_ref_del(&s->ls_top_dev->ld_reference, "site-top", s); lu_device_put(s->ls_top_dev); s->ls_top_dev = NULL; } } EXPORT_SYMBOL(lu_site_fini); -/* +/** * Called when initialization of stack for this site is completed. */ int lu_site_init_finish(struct lu_site *s) @@ -775,27 +781,32 @@ int lu_object_init(struct lu_object *o, o->lo_header = h; o->lo_dev = d; lu_device_get(d); + o->lo_dev_ref = lu_ref_add(&d->ld_reference, "lu_object", o); CFS_INIT_LIST_HEAD(&o->lo_linkage); return 0; } EXPORT_SYMBOL(lu_object_init); -/* +/** * Finalize object and release its resources. */ void lu_object_fini(struct lu_object *o) { + struct lu_device *dev = o->lo_dev; + LASSERT(list_empty(&o->lo_linkage)); - if (o->lo_dev != NULL) { - lu_device_put(o->lo_dev); + if (dev != NULL) { + lu_ref_del_at(&dev->ld_reference, + o->lo_dev_ref , "lu_object", o); + lu_device_put(dev); o->lo_dev = NULL; } } EXPORT_SYMBOL(lu_object_fini); -/* - * Add object @o as first layer of compound object @h +/** + * Add object \a o as first layer of compound object \a h * * This is typically called by the ->ldo_object_alloc() method of top-level * device. @@ -828,11 +839,12 @@ int lu_object_header_init(struct lu_object_header *h) INIT_HLIST_NODE(&h->loh_hash); CFS_INIT_LIST_HEAD(&h->loh_lru); CFS_INIT_LIST_HEAD(&h->loh_layers); + lu_ref_init(&h->loh_reference); return 0; } EXPORT_SYMBOL(lu_object_header_init); -/* +/** * Finalize compound object. */ void lu_object_header_fini(struct lu_object_header *h) @@ -840,15 +852,16 @@ void lu_object_header_fini(struct lu_object_header *h) LASSERT(list_empty(&h->loh_layers)); LASSERT(list_empty(&h->loh_lru)); LASSERT(hlist_unhashed(&h->loh_hash)); + lu_ref_fini(&h->loh_reference); } EXPORT_SYMBOL(lu_object_header_fini); -/* +/** * Given a compound object, find its slice, corresponding to the device type - * @dtype. + * \a dtype. */ struct lu_object *lu_object_locate(struct lu_object_header *h, - struct lu_device_type *dtype) + const struct lu_device_type *dtype) { struct lu_object *o; @@ -862,7 +875,7 @@ EXPORT_SYMBOL(lu_object_locate); -/* +/** * Finalize and free devices in the device stack. * * Finalize device stack by purging object cache, and calling @@ -878,6 +891,7 @@ void lu_stack_fini(const struct lu_env *env, struct lu_device *top) lu_site_purge(env, site, ~0); for (scan = top; scan != NULL; scan = next) { next = scan->ld_type->ldt_ops->ldto_device_fini(env, scan); + lu_ref_del(&scan->ld_reference, "lu-stack", &lu_site_init); lu_device_put(scan); } diff --git a/lustre/osd/osd_handler.c b/lustre/osd/osd_handler.c index 8fedb2c9b2..ee58e92274 100644 --- a/lustre/osd/osd_handler.c +++ b/lustre/osd/osd_handler.c @@ -231,6 +231,9 @@ struct osd_thandle { struct thandle ot_super; handle_t *ot_handle; struct journal_callback ot_jcb; + /* Link to the device, for debugging. */ + struct lu_ref_link *ot_dev_link; + }; /* @@ -571,6 +574,7 @@ static void osd_trans_commit_cb(struct journal_callback *jcb, int error) struct osd_thandle *oh = container_of0(jcb, struct osd_thandle, ot_jcb); struct thandle *th = &oh->ot_super; struct dt_device *dev = th->th_dev; + struct lu_device *lud = &dev->dd_lu_dev; LASSERT(dev != NULL); LASSERT(oh->ot_handle == NULL); @@ -588,7 +592,8 @@ static void osd_trans_commit_cb(struct journal_callback *jcb, int error) lu_context_exit(&env->le_ctx); } - lu_device_put(&dev->dd_lu_dev); + lu_ref_del_at(&lud->ld_reference, oh->ot_dev_link, "osd-tx", th); + lu_device_put(lud); th->th_dev = NULL; lu_context_exit(&th->th_ctx); @@ -618,6 +623,8 @@ static struct thandle *osd_trans_start(const struct lu_env *env, if (osd_param_is_sane(dev, p)) { OBD_ALLOC_GFP(oh, sizeof *oh, CFS_ALLOC_IO); if (oh != NULL) { + struct osd_thread_info *oti = osd_oti_get(env); + /* * XXX temporary stuff. Some abstraction layer should * be used. @@ -631,22 +638,18 @@ static struct thandle *osd_trans_start(const struct lu_env *env, th->th_result = 0; jh->h_sync = p->tp_sync; lu_device_get(&d->dd_lu_dev); + oh->ot_dev_link = lu_ref_add + (&d->dd_lu_dev.ld_reference, + "osd-tx", th); /* add commit callback */ lu_context_init(&th->th_ctx, LCT_TX_HANDLE); lu_context_enter(&th->th_ctx); journal_callback_set(jh, osd_trans_commit_cb, (struct journal_callback *)&oh->ot_jcb); -#if OSD_COUNTERS - { - struct osd_thread_info *oti = - osd_oti_get(env); - LASSERT(oti->oti_txns == 0); LASSERT(oti->oti_r_locks == 0); LASSERT(oti->oti_w_locks == 0); oti->oti_txns++; - } -#endif } else { OBD_FREE_PTR(oh); th = (void *)jh; -- GitLab