Whamcloud - gitweb
Add lu_ref support to lu_object and lu_device. lu_ref is used to track leaked
authornikita <nikita>
Sat, 18 Oct 2008 17:19:11 +0000 (17:19 +0000)
committernikita <nikita>
Sat, 18 Oct 2008 17:19:11 +0000 (17:19 +0000)
references.
b=16450

lustre/ChangeLog
lustre/cmm/cmm_device.c
lustre/include/lu_object.h
lustre/obdclass/lu_object.c
lustre/osd/osd_handler.c

index a0e72e8..ba2f2f2 100644 (file)
@@ -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>
index 38c62da..a526307 100644 (file)
@@ -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;
index 50665df..138c586 100644 (file)
@@ -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 */
index a097d69..5077327 100644 (file)
@@ -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);
         }
 
index 8fedb2c..ee58e92 100644 (file)
@@ -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;