AC_SUBST(ENABLE_INVARIANTS, no)
])
-AC_MSG_CHECKING([whether to track references with lu_ref])
-AC_ARG_ENABLE([lu_ref],
- AS_HELP_STRING([--enable-lu_ref],
- [enable lu_ref reference tracking code]),
- [], [enable_lu_ref="no"])
-AC_MSG_RESULT([$enable_lu_ref])
-AS_IF([test "x$enable_lu_ref" = xyes], [
- AC_DEFINE([CONFIG_LUSTRE_DEBUG_LU_REF], 1,
- [enable lu_ref reference tracking code])
- AC_SUBST(ENABLE_LU_REF, yes)
-], [
- AC_SUBST(ENABLE_LU_REF, no)
-])
-
AC_MSG_CHECKING([whether to enable page state tracking])
AC_ARG_ENABLE([pgstate-track],
AS_HELP_STRING([--enable-pgstate-track],
llog_swab.h \
lprocfs_status.h \
lu_object.h \
- lu_ref.h \
lustre_acl.h \
lustre_barrier.h \
lustre_compat.h \
* by sub-io. Protected by a VM lock.
*/
struct cl_io *cp_owner;
- /** List of references to this page, for debugging. */
- struct lu_ref cp_reference;
- /** Link to an object, for debugging. */
- struct lu_ref_link cp_obj_ref;
- /** Link to a queue, for debugging. */
- struct lu_ref_link cp_queue_ref;
/** Assigned if doing a sync_io */
struct cl_sync_io *cp_sync_io;
};
#endif
#include <libcfs/libcfs.h>
#include <uapi/linux/lustre/lustre_idl.h>
-#include <lu_ref.h>
#include <linux/percpu_counter.h>
#include <linux/rhashtable.h>
#include <linux/ctype.h>
/** \todo XXX: temporary back pointer into obd. */
struct obd_device *ld_obd;
- /**
- * A list of references to this object, for debugging.
- */
- struct lu_ref ld_reference;
+
/**
* Link the device to the site.
**/
* Linkage into list of all layers.
*/
struct list_head lo_linkage;
- /**
- * Link to the device, for debugging.
- */
- struct lu_ref_link lo_dev_ref;
};
enum lu_object_header_flags {
* during object destruction). No locking is necessary.
*/
struct list_head loh_layers;
- /**
- * A list of references to this object, for debugging.
- */
- struct lu_ref loh_reference;
/*
* Handle used for kfree_rcu() or similar.
*/
return o->lo_header->loh_attr & S_IFMT;
}
-static inline void lu_object_ref_add_atomic(struct lu_object *o,
- const char *scope,
- const void *source)
-{
- lu_ref_add_atomic(&o->lo_header->loh_reference, scope, source);
-}
-
-static inline void lu_object_ref_add(struct lu_object *o,
- const char *scope,
- const void *source)
-{
- lu_ref_add(&o->lo_header->loh_reference, scope, source);
-}
-
-static inline void lu_object_ref_add_at(struct lu_object *o,
- struct lu_ref_link *link,
- const char *scope,
- const void *source)
-{
- lu_ref_add_at(&o->lo_header->loh_reference, link, 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);
-}
-
-/** input params, should be filled out by mdt */
+/* input params, should be filled out by mdt */
struct lu_rdpg {
/** hash */
__u64 rp_hash;
* Internal implementation detail: module for this key.
*/
struct module *lct_owner;
- /**
- * References to this key. For debugging.
- */
- struct lu_ref lct_reference;
};
#define LU_KEY_INIT(mod, type) \
+++ /dev/null
-// SPDX-License-Identifier: GPL-2.0
-/*
- * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
- * Use is subject to license terms.
- *
- * Copyright (c) 2012, 2013, Intel Corporation.
- *
- * Author: Nikita Danilov <nikita.danilov@sun.com>
- *
- * This file is part of Lustre, http://www.lustre.org.
- *
- * Lustre is free software; you can redistribute it and/or
- * modify it under the terms of version 2 of the GNU General Public
- * License as published by the Free Software Foundation.
- *
- * Lustre is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- */
-
-#ifndef __LUSTRE_LU_REF_H
-#define __LUSTRE_LU_REF_H
-
-#include <linux/list.h>
-
-/** \defgroup lu_ref lu_ref
- *
- * An interface to track references between objects. Mostly for debugging.
- *
- * Suppose there is a reference counted data-structure struct foo. To track
- * who acquired references to instance of struct foo, add lu_ref field to it:
- *
- * \code
- * struct foo {
- * atomic_t foo_refcount;
- * struct lu_ref foo_reference;
- * ...
- * };
- * \endcode
- *
- * foo::foo_reference has to be initialized by calling
- * lu_ref_init(). Typically there will be functions or macros to increment and
- * decrement foo::foo_refcount, let's say they are foo_get(struct foo *foo)
- * and foo_put(struct foo *foo), respectively.
- *
- * Whenever foo_get() is called to acquire a reference on a foo, lu_ref_add()
- * has to be called to insert into foo::foo_reference a record, describing
- * acquired reference. Dually, lu_ref_del() removes matching record. Typical
- * usages are:
- *
- * \code
- * struct bar *bar;
- *
- * // bar owns a reference to foo.
- * bar->bar_foo = foo_get(foo);
- * lu_ref_add(&foo->foo_reference, "bar", bar);
- *
- * ...
- *
- * // reference from bar to foo is released.
- * lu_ref_del(&foo->foo_reference, "bar", bar);
- * foo_put(bar->bar_foo);
- *
- *
- * // current thread acquired a temporary reference to foo.
- * foo_get(foo);
- * lu_ref_add(&foo->reference, __func__, current);
- *
- * ...
- *
- * // temporary reference is released.
- * lu_ref_del(&foo->reference, __func__, current);
- * foo_put(foo);
- * \endcode
- *
- * \e Et \e cetera. Often it makes sense to include lu_ref_add() and
- * lu_ref_del() calls into foo_get() and foo_put(). When an instance of struct
- * foo is destroyed, lu_ref_fini() has to be called that checks that no
- * pending references remain. lu_ref_print() can be used to dump a list of
- * pending references, while hunting down a leak.
- *
- * For objects to which a large number of references can be acquired,
- * lu_ref_del() can become cpu consuming, as it has to scan the list of
- * references. To work around this, remember result of lu_ref_add() (usually
- * in the same place where pointer to struct foo is stored), and use
- * lu_ref_del_at():
- *
- * \code
- * // There is a large number of bar's for a single foo.
- * bar->bar_foo = foo_get(foo);
- * bar->bar_foo_ref = lu_ref_add(&foo->foo_reference, "bar", bar);
- *
- * ...
- *
- * // reference from bar to foo is released.
- * lu_ref_del_at(&foo->foo_reference, bar->bar_foo_ref, "bar", bar);
- * foo_put(bar->bar_foo);
- * \endcode
- *
- * lu_ref interface degrades gracefully in case of memory shortages.
- *
- * @{
- */
-
-#ifdef CONFIG_LUSTRE_DEBUG_LU_REF
-
-/**
- * Data-structure to keep track of references to a given object. This is used
- * for debugging.
- *
- * lu_ref is embedded into an object which other entities (objects, threads,
- * etc.) refer to.
- */
-struct lu_ref {
- /**
- * Spin-lock protecting lu_ref::lf_list.
- */
- spinlock_t lf_guard;
- /**
- * List of all outstanding references (each represented by struct
- * lu_ref_link), pointing to this object.
- */
- struct list_head lf_list;
- /**
- * # of links.
- */
- short lf_refs;
- /**
- * Flag set when lu_ref_add() failed to allocate lu_ref_link. It is
- * used to mask spurious failure of the following lu_ref_del().
- */
- short lf_failed;
- /**
- * flags - attribute for the lu_ref, for pad and future use.
- */
- short lf_flags;
- /**
- * Where was I initialized?
- */
- short lf_line;
- const char *lf_func;
- /**
- * Linkage into a global list of all lu_ref's (lu_ref_refs).
- */
- struct list_head lf_linkage;
-};
-
-struct lu_ref_link {
- struct lu_ref *ll_ref;
- struct list_head ll_linkage;
- const char *ll_scope;
- const void *ll_source;
-};
-
-void lu_ref_init_loc(struct lu_ref *ref, const char *func, const int line);
-void lu_ref_fini(struct lu_ref *ref);
-#define lu_ref_init(ref) lu_ref_init_loc(ref, __func__, __LINE__)
-
-void lu_ref_add(struct lu_ref *ref, const char *scope, const void *source);
-
-void lu_ref_add_atomic(struct lu_ref *ref, const char *scope,
- const void *source);
-
-void lu_ref_add_at(struct lu_ref *ref, struct lu_ref_link *link,
- const char *scope, const void *source);
-
-void lu_ref_del(struct lu_ref *ref, const char *scope, const void *source);
-
-void lu_ref_set_at(struct lu_ref *ref, struct lu_ref_link *link,
- const char *scope, const void *source0, const void *source1);
-
-void lu_ref_del_at(struct lu_ref *ref, struct lu_ref_link *link,
- const char *scope, const void *source);
-
-void lu_ref_print(const struct lu_ref *ref);
-
-void lu_ref_print_all(void);
-
-int lu_ref_global_init(void);
-
-void lu_ref_global_fini(void);
-
-#else /* !CONFIG_LUSTRE_DEBUG_LU_REF */
-
-struct lu_ref {
-};
-
-struct lu_ref_link {
-};
-
-static inline void lu_ref_init(struct lu_ref *ref)
-{
-}
-
-static inline void lu_ref_fini(struct lu_ref *ref)
-{
-}
-
-static inline void lu_ref_add(struct lu_ref *ref,
- const char *scope,
- const void *source)
-{
-}
-
-static inline void lu_ref_add_atomic(struct lu_ref *ref,
- const char *scope,
- const void *source)
-{
-}
-
-static inline void lu_ref_add_at(struct lu_ref *ref,
- struct lu_ref_link *link,
- const char *scope,
- const void *source)
-{
-}
-
-static inline void lu_ref_del(struct lu_ref *ref, const char *scope,
- const void *source)
-{
-}
-
-static inline void lu_ref_set_at(struct lu_ref *ref, struct lu_ref_link *link,
- const char *scope, const void *source0,
- const void *source1)
-{
-}
-
-static inline void lu_ref_del_at(struct lu_ref *ref, struct lu_ref_link *link,
- const char *scope, const void *source)
-{
-}
-
-static inline int lu_ref_global_init(void)
-{
- return 0;
-}
-
-static inline void lu_ref_global_fini(void)
-{
-}
-
-static inline void lu_ref_print(const struct lu_ref *ref)
-{
-}
-
-static inline void lu_ref_print_all(void)
-{
-}
-#endif /* CONFIG_LUSTRE_DEBUG_LU_REF */
-
-/** @} lu */
-
-#endif /* __LUSTRE_LU_REF_H */
#include <lustre_import.h>
#include <lustre_handles.h>
#include <linux/interval_tree_generic.h>
-#include <lu_ref.h>
#include "lustre_dlm_flags.h"
*/
struct ldlm_lock *l_blocking_lock;
- /** Reference tracking structure to debug leaked locks. */
- struct lu_ref l_reference;
#if LUSTRE_TRACKS_LOCK_EXP_REFS
/* Debugging stuff for bug 20498, for tracking export references. */
/** number of export references taken */
void *lr_lvb_data;
/** is lvb initialized ? */
bool lr_lvb_initialized;
-
- /** List of references to this resource. For debugging. */
- struct lu_ref lr_reference;
};
static inline int ldlm_is_granted(struct ldlm_lock *lock)
return __ldlm_handle2lock(h, 0);
}
-#define LDLM_LOCK_REF_DEL(lock) \
- lu_ref_del(&lock->l_reference, "handle", lock)
-
static inline struct ldlm_lock *
ldlm_handle2lock_long(const struct lustre_handle *h, __u64 flags)
{
struct ldlm_lock *lock;
lock = __ldlm_handle2lock(h, flags);
- if (lock != NULL)
- LDLM_LOCK_REF_DEL(lock);
return lock;
}
/* Release temporary lock got by ldlm_handle2lock() or __ldlm_handle2lock() */
#define LDLM_LOCK_PUT(lock) \
do { \
- LDLM_LOCK_REF_DEL(lock); \
- /*LDLM_DEBUG((lock), "put");*/ \
ldlm_lock_put(lock); \
} while (0)
int ldlm_lock_change_resource(struct ldlm_namespace *ln, struct ldlm_lock *ll,
const struct ldlm_res_id *lri);
-#define LDLM_RESOURCE_ADDREF(res) \
- lu_ref_add_atomic(&(res)->lr_reference, __FUNCTION__, current)
-
-#define LDLM_RESOURCE_DELREF(res) \
- lu_ref_del(&(res)->lr_reference, __FUNCTION__, current)
-
/* ldlm_request.c */
/** \defgroup ldlm_local_ast Default AST handlers for local locks
* These AST handlers are typically used for server-side local locks and are
#include <uapi/linux/lustre/lustre_idl.h>
#include <lustre_lib.h>
-#include <lu_ref.h>
#include <lustre_export.h>
#include <lustre_fid.h>
#include <lustre_fld.h>
atomic_t obd_conn_inprogress;
- /**
- * List of outstanding class_incref()'s fo this OBD. For debugging. */
- struct lu_ref obd_reference;
-
struct kset obd_kset; /* sysfs object collection */
struct kobj_type obd_ktype;
struct completion obd_kobj_unregister;
lprocfs_counter_decr(ldlm_res_to_ns(res)->ns_stats,
LDLM_NSS_LOCKS);
- lu_ref_del(&res->lr_reference, "lock", lock);
if (lock->l_export) {
class_export_lock_put(lock->l_export, lock);
lock->l_export = NULL;
}
ldlm_resource_putref(res);
lock->l_resource = NULL;
- lu_ref_fini(&lock->l_reference);
if (lock->l_flags & BIT(63))
/* Performance testing - bypassing RCU removes overhead */
lock_handle_free(&lock->l_handle.h_rcu);
/* drop reference from hashtable only for first destroy */
if (first) {
- lu_ref_del(&lock->l_reference, "hash", lock);
LDLM_LOCK_RELEASE(lock);
}
EXIT;
first = ldlm_lock_destroy_internal(lock);
/* drop reference from hashtable only for first destroy */
if (first) {
- lu_ref_del(&lock->l_reference, "hash", lock);
LDLM_LOCK_RELEASE(lock);
}
EXIT;
RETURN(NULL);
RCU_INIT_POINTER(lock->l_resource, resource);
- lu_ref_add(&resource->lr_reference, "lock", lock);
refcount_set(&lock->l_handle.h_ref, 2);
INIT_LIST_HEAD(&lock->l_res_link);
INIT_HLIST_NODE(&lock->l_handle.h_link);
class_handle_hash(&lock->l_handle, lock_handle_owner);
- lu_ref_init(&lock->l_reference);
- lu_ref_add(&lock->l_reference, "hash", lock);
lock->l_callback_timestamp = 0;
lock->l_activity = 0;
if (IS_ERR(newres))
RETURN(PTR_ERR(newres));
- lu_ref_add(&newres->lr_reference, "lock", lock);
/*
* To flip the lock from the old to the new resource, oldres
* and newres have to be locked. Resource spin-locks are taken
unlock_res(newres);
/* ...and the flowers are still standing! */
- lu_ref_del(&oldres->lr_reference, "lock", lock);
ldlm_resource_putref(oldres);
RETURN(0);
* destroyed after we did handle2object on it
*/
if ((flags == 0) && !ldlm_is_destroyed(lock)) {
- lu_ref_add_atomic(&lock->l_reference, "handle", lock);
RETURN(lock);
}
LASSERT(lock->l_resource != NULL);
- lu_ref_add_atomic(&lock->l_reference, "handle", lock);
if (unlikely(ldlm_is_destroyed(lock))) {
unlock_res_and_lock(lock);
CDEBUG(D_INFO, "lock already destroyed: lock %p\n", lock);
ldlm_lock_remove_from_lru(lock);
if (mode & (LCK_NL | LCK_CR | LCK_PR)) {
lock->l_readers++;
- lu_ref_add_atomic(&lock->l_reference, "reader", lock);
}
if (mode & (LCK_EX | LCK_CW | LCK_PW | LCK_GROUP | LCK_COS | LCK_TXN)) {
lock->l_writers++;
- lu_ref_add_atomic(&lock->l_reference, "writer", lock);
}
LDLM_LOCK_GET(lock);
- lu_ref_add_atomic(&lock->l_reference, "user", lock);
LDLM_DEBUG(lock, "ldlm_lock_addref(%s)", ldlm_lockname[mode]);
}
LDLM_DEBUG(lock, "ldlm_lock_decref(%s)", ldlm_lockname[mode]);
if (mode & (LCK_NL | LCK_CR | LCK_PR)) {
LASSERT(lock->l_readers > 0);
- lu_ref_del(&lock->l_reference, "reader", lock);
lock->l_readers--;
}
if (mode & (LCK_EX | LCK_CW | LCK_PW | LCK_GROUP | LCK_COS | LCK_TXN)) {
LASSERT(lock->l_writers > 0);
- lu_ref_del(&lock->l_reference, "writer", lock);
lock->l_writers--;
}
- lu_ref_del(&lock->l_reference, "user", lock);
LDLM_LOCK_RELEASE(lock); /* matches the LDLM_LOCK_GET() in addref */
}
repeat:
group_lock = NULL;
- LDLM_RESOURCE_ADDREF(res);
lock_res(res);
if (res->lr_type == LDLM_EXTENT)
lock = search_itree(res, &data);
(data.lmd_match & LDLM_MATCH_GROUP))
group_lock = lock;
unlock_res(res);
- LDLM_RESOURCE_DELREF(res);
if (group_lock) {
l_wait_event_abortable(group_lock->l_waitq,
if (res != pres) {
if (pres != NULL) {
ldlm_reprocess_all(pres, 0);
- LDLM_RESOURCE_DELREF(pres);
ldlm_resource_putref(pres);
}
if (res != NULL) {
ldlm_resource_getref(res);
- LDLM_RESOURCE_ADDREF(res);
if (!ldlm_is_discard_data(lock))
ldlm_lvbo_update(res, lock,
}
if (pres != NULL) {
ldlm_reprocess_all(pres, 0);
- LDLM_RESOURCE_DELREF(pres);
ldlm_resource_putref(pres);
}
LDLM_DEBUG_NOLOCK("server-side cancel handler END");
LDLM_LOCK_GET(lock);
spin_unlock(&ns->ns_lock);
- lu_ref_add(&lock->l_reference, __FUNCTION__, current);
/*
* Pass the lock through the policy filter and see if it
*/
result = pf(ns, lock, added, min);
if (result == LDLM_POLICY_KEEP_LOCK) {
- lu_ref_del(&lock->l_reference, __func__, current);
LDLM_LOCK_RELEASE(lock);
break;
}
if (result == LDLM_POLICY_SKIP_LOCK) {
- lu_ref_del(&lock->l_reference, __func__, current);
if (no_wait) {
spin_lock(&ns->ns_lock);
if (!list_empty(&lock->l_lru) &&
* pages could be put under it.
*/
unlock_res_and_lock(lock);
- lu_ref_del(&lock->l_reference, __FUNCTION__, current);
LDLM_LOCK_RELEASE(lock);
continue;
}
LASSERT(list_empty(&lock->l_bl_ast));
list_add(&lock->l_bl_ast, cancels);
unlock_res_and_lock(lock);
- lu_ref_del(&lock->l_reference, __FUNCTION__, current);
added++;
/* Once a lock added, batch the requested amount */
if (min == 0)
RETURN(0);
}
- LDLM_RESOURCE_ADDREF(res);
count = ldlm_cancel_resource_local(res, &cancels, policy, mode,
0, flags | LCF_BL_AST, opaque);
rc = ldlm_cli_cancel_list(&cancels, count, NULL, flags);
CERROR("canceling unused lock "DLDLMRES": rc = %d\n",
PLDLMRES(res), rc);
- LDLM_RESOURCE_DELREF(res);
ldlm_resource_putref(res);
RETURN(0);
}
if (IS_ERR(res))
RETURN(0);
- LDLM_RESOURCE_ADDREF(res);
rc = ldlm_resource_foreach(res, iter, data);
- LDLM_RESOURCE_DELREF(res);
ldlm_resource_putref(res);
RETURN(rc);
}
refcount_set(&res->lr_refcount, 1);
spin_lock_init(&res->lr_lock);
- lu_ref_init(&res->lr_reference);
/* Since LVB init can be delayed now, there is no longer need to
* immediatelly acquire mutex here.
if (hnode != NULL) {
/* Someone won the race and already added the resource. */
cfs_hash_bd_unlock(ns->ns_rs_hash, &bd, 1);
- /* Clean lu_ref for failed resource. */
- lu_ref_fini(&res->lr_reference);
ldlm_resource_free(res);
found:
res = hlist_entry(hnode, struct ldlm_resource, lr_hash);
cfs_hash_bd_del_locked(nsb->nsb_namespace->ns_rs_hash,
bd, &res->lr_hash);
- lu_ref_fini(&res->lr_reference);
if (atomic_dec_and_test(&nsb->nsb_count))
ldlm_namespace_put(nsb->nsb_namespace);
}
* locked by I_NEW bit.
*/
lli->lli_clob = clob;
- lu_object_ref_add(&clob->co_lu, "inode", inode);
} else {
result = PTR_ERR(clob);
}
* when its master is evicted.
*/
cl_object_kill(env, clob);
- lu_object_ref_del(&clob->co_lu, "inode", inode);
cl_object_put_last(env, clob);
lli->lli_clob = NULL;
if (emergency)
GOTO(out, rc = PTR_ERR(cp));
}
- lu_ref_add(&cp->cp_reference, "ra", current);
cl_page_assume(env, io, cp);
if (!cp->cp_defer_uptodate && !PageUptodate(vmpage)) {
rc = 1;
}
- lu_ref_del(&cp->cp_reference, "ra", current);
cl_page_put(env, cp);
out:
page = cl_page_find(env, clob, vmpage->index,
vmpage, CPT_CACHEABLE);
if (!IS_ERR(page)) {
- lu_ref_add(&page->cp_reference, "writepage",
- current);
cl_page_assume(env, io, page);
result = cl_page_flush(env, io, page);
if (result != 0) {
}
cl_page_disown(env, io, page);
unlocked = true;
- lu_ref_del(&page->cp_reference,
- "writepage", current);
cl_page_put(env, page);
} else {
result = PTR_ERR(page);
GOTO(out, result = PTR_ERR(page));
lcc->lcc_page = page;
- lu_ref_add(&page->cp_reference, "cl_io", io);
cl_page_assume(env, io, page);
if (!PageUptodate(vmpage)) {
}
/* On tiny_write failure, page and io are always null. */
if (!IS_ERR_OR_NULL(page)) {
- lu_ref_del(&page->cp_reference, "cl_io", io);
cl_page_put(env, page);
}
if (io)
cl_page_disown(env, io, page);
lcc->lcc_page = NULL;
- lu_ref_del(&page->cp_reference, "cl_io", io);
cl_page_put(env, page);
/* page list is not contiguous now, commit it now */
env, next, next->ld_type->ldt_name, NULL);
if (rc == 0) {
lu_device_get(next);
- lu_ref_add(&next->ld_reference, "lu-stack", &lu_site_init);
}
RETURN(rc);
}
continue;
priv->vsp_clob = lu2cl(lu_obj);
- lu_object_ref_add_atomic(lu_obj, "dump", current);
priv->vsp_page_index = 0;
}
priv->vsp_page_index = vmpage->index;
break;
}
- lu_object_ref_del(&priv->vsp_clob->co_lu, "dump", current);
cl_object_put(priv->vsp_env, priv->vsp_clob);
priv->vsp_clob = NULL;
priv->vsp_page_index = 0;
rhashtable_walk_enter(&s->ls_obj_hash, &priv->vsp_iter);
priv->vvp_prev_pos = 0;
if (priv->vsp_clob) {
- lu_object_ref_del(&priv->vsp_clob->co_lu, "dump",
- current);
cl_object_put(priv->vsp_env, priv->vsp_clob);
}
priv->vsp_clob = NULL;
struct vvp_seq_private *priv = seq->private;
if (priv->vsp_clob) {
- lu_object_ref_del(&priv->vsp_clob->co_lu, "dump", current);
cl_object_put(priv->vsp_env, priv->vsp_clob);
}
cl_env_put(priv->vsp_env, &priv->vsp_refcheck);
CLOBINVRNT(env, io->ci_obj, vvp_object_invariant(io->ci_obj));
if (page != NULL) {
- lu_ref_del(&page->cp_reference, "fault", io);
cl_page_put(env, page);
io->u.ci_fault.ft_page = NULL;
}
cl_page_disown(env, io, page);
/* held in ll_cl_init() */
- lu_ref_del(&page->cp_reference, "cl_io", io);
cl_page_put(env, page);
}
}
vmpage = fbatch_at_pg(fbatch, i, pg);
page = (struct cl_page *) vmpage->private;
cl_page_disown(env, io, page);
- lu_ref_del(&page->cp_reference, "cl_io", cl_io_top(io));
cl_page_put(env, page);
}
}
cl_page_disown(env, io, page);
/* held in ll_cl_init() */
- lu_ref_del(&page->cp_reference, "cl_io", io);
cl_page_put(env, page);
}
cl_page_list_fini(env, queue);
io->ci_noquota = 1;
cl_page_own(env, io, page);
cl_page_list_add(plist, page, true);
- lu_ref_add(&page->cp_reference,
- "cl_io", io);
result = cl_io_commit_async(env, io,
plist, 0, to,
mkwrite_commit_callback);
else
fio->ft_bytes = PAGE_SIZE;
- lu_ref_add(&page->cp_reference, "fault", io);
fio->ft_page = page;
EXIT;
subhdr->coh_parent = hdr;
spin_unlock(&subhdr->coh_attr_guard);
subhdr->coh_nesting = hdr->coh_nesting + 1;
- lu_object_ref_add(&subobj->co_lu, "lov-parent", lov);
lso->lso_super = lov;
lso->lso_index = idx;
result = 0;
cl_object_kill(env, sub);
/* release a reference to the sub-object and ... */
- lu_object_ref_del(&sub->co_lu, "lov-parent", lov);
cl_object_put(env, sub);
/* ... wait until it is actually destroyed---sub-object clears its
}
lu_device_get(next);
- lu_ref_add(&next->ld_reference, "lu-stack", &lu_site_init);
lsd->acid_next = lu2cl_dev(next);
RETURN(rc);
}
/* lock reference taken by ldlm_handle2lock_long() is
* owned by osc_lock and released in osc_lock_detach()
*/
- lu_ref_add_atomic(&dlmlock->l_reference, "osc_lock", oscl);
oscl->ols_has_ref = 1;
LASSERT(oscl->ols_dlmlock == NULL);
res = ldlm_resource_get(ns, res_id, 0, 0);
if (IS_ERR(res))
RETURN(0);
- LDLM_RESOURCE_ADDREF(res);
/* Initialize ibits lock policy. */
policy.l_inodebits.bits = bits;
count = ldlm_cancel_resource_local(res, cancels, &policy, mode, 0, 0,
NULL);
- LDLM_RESOURCE_DELREF(res);
ldlm_resource_putref(res);
RETURN(count);
}
* possible blocking AST.
*/
while (new_lock->l_readers > 0) {
- lu_ref_del(&new_lock->l_reference, "reader", new_lock);
- lu_ref_del(&new_lock->l_reference, "user", new_lock);
new_lock->l_readers--;
}
while (new_lock->l_writers > 0) {
- lu_ref_del(&new_lock->l_reference, "writer", new_lock);
- lu_ref_del(&new_lock->l_reference, "user", new_lock);
new_lock->l_writers--;
}
obdclass-all-objs += lustre_handles.o lustre_peer.o local_storage.o
obdclass-all-objs += statfs_pack.o obdo.o obd_config.o obd_mount.o obd_sysfs.o
obdclass-all-objs += lu_object.o dt_object.o
-obdclass-all-objs += cl_object.o cl_page.o cl_lock.o cl_io.o lu_ref.o
+obdclass-all-objs += cl_object.o cl_page.o cl_lock.o cl_io.o
obdclass-all-objs += linkea.o upcall_cache.o
obdclass-all-objs += kernelcomm.o jobid.o
obdclass-all-objs += integrity.o obd_cksum.o
LASSERT(list_empty(&page->cp_batch));
list_add_tail(&page->cp_batch, &plist->pl_pages);
++plist->pl_nr;
- lu_ref_add_at(&page->cp_reference, &page->cp_queue_ref, "queue", plist);
if (getref)
cl_page_get(page);
EXIT;
ENTRY;
list_del_init(&page->cp_batch);
--plist->pl_nr;
- lu_ref_del_at(&page->cp_reference, &page->cp_queue_ref, "queue", plist);
if (putref)
cl_page_put(env, page);
EXIT;
list_move_tail(&page->cp_batch, &dst->pl_pages);
--src->pl_nr;
++dst->pl_nr;
- lu_ref_set_at(&page->cp_reference, &page->cp_queue_ref, "queue",
- src, dst);
EXIT;
}
EXPORT_SYMBOL(cl_page_list_move);
list_move(&page->cp_batch, &dst->pl_pages);
--src->pl_nr;
++dst->pl_nr;
- lu_ref_set_at(&page->cp_reference, &page->cp_queue_ref, "queue",
- src, dst);
EXIT;
}
EXPORT_SYMBOL(cl_page_list_move_head);
*/
void cl_page_list_splice(struct cl_page_list *src, struct cl_page_list *dst)
{
-#ifdef CONFIG_LUSTRE_DEBUG_LU_REF
- struct cl_page *page;
- struct cl_page *tmp;
-
ENTRY;
- cl_page_list_for_each_safe(page, tmp, src)
- lu_ref_set_at(&page->cp_reference, &page->cp_queue_ref,
- "queue", src, dst);
-#else
- ENTRY;
-#endif
dst->pl_nr += src->pl_nr;
src->pl_nr = 0;
list_splice_tail_init(&src->pl_pages, &dst->pl_pages);
*/
if (page->cp_type == CPT_CACHEABLE)
__cl_page_disown(env, page);
- lu_ref_del_at(&page->cp_reference, &page->cp_queue_ref, "queue",
- plist);
cl_page_put(env, page);
}
EXIT;
rc = ldt->ldt_ops->ldto_device_init(env, d, typename, next);
if (rc == 0) {
lu_device_get(d);
- lu_ref_add(&d->ld_reference,
- "lu-stack", &lu_site_init);
} else {
ldt->ldt_ops->ldto_device_free(env, d);
CERROR("can't init device '%s', %d\n", typename, rc);
cs_page_dec(obj, CS_total);
if (cp->cp_type != CPT_TRANSIENT)
cs_pagestate_dec(obj, cp->cp_state);
- lu_object_ref_del_at(&obj->co_lu, &cp->cp_obj_ref, "cl_page", cp);
if (cp->cp_type != CPT_TRANSIENT)
cl_object_put(env, obj);
- lu_ref_fini(&cp->cp_reference);
__cl_page_free(cp, bufsize);
EXIT;
}
cl_page->cp_obj = o;
if (type != CPT_TRANSIENT)
cl_object_get(o);
- lu_object_ref_add_at(&o->co_lu, &cl_page->cp_obj_ref,
- "cl_page", cl_page);
cl_page->cp_vmpage = vmpage;
if (cl_page->cp_type != CPT_TRANSIENT)
cl_page->cp_state = CPS_CACHED;
else
cl_page->cp_inode = page2inode(vmpage);
INIT_LIST_HEAD(&cl_page->cp_batch);
- lu_ref_init(&cl_page->cp_reference);
head = o;
cl_page->cp_page_index = ind;
cl_object_for_each(o, head) {
obd, obd->obd_namespace, obd->obd_force);
LBUG();
}
- lu_ref_fini(&obd->obd_reference);
OBD_SLAB_FREE_PTR(obd, obd_device_cachep);
}
llog_group_init(&newdev->obd_olg);
/* Detach drops this */
kref_init(&newdev->obd_refcount);
- lu_ref_init(&newdev->obd_reference);
- lu_ref_add(&newdev->obd_reference, "newdev", newdev);
atomic_set(&newdev->obd_conn_inprogress, 0);
#include <lustre_disk.h>
#include <lustre_fid.h>
#include <lu_object.h>
-#include <lu_ref.h>
struct lu_site_bkt_data {
/**
s->ls_top_dev = top;
top->ld_site = s;
lu_device_get(top);
- lu_ref_add(&top->ld_reference, "site-top", s);
INIT_LIST_HEAD(&s->ls_ld_linkage);
spin_lock_init(&s->ls_ld_lock);
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;
}
memset(d, 0, sizeof(*d));
d->ld_type = t;
- lu_ref_init(&d->ld_reference);
INIT_LIST_HEAD(&d->ld_linkage);
return 0;
d->ld_obd = NULL;
}
- lu_ref_fini(&d->ld_reference);
LASSERTF(atomic_read(&d->ld_ref) == 0,
"Refcount is %u\n", atomic_read(&d->ld_ref));
LASSERT(atomic_read(&t->ldt_device_nr) > 0);
o->lo_header = h;
o->lo_dev = d;
lu_device_get(d);
- lu_ref_add_at(&d->ld_reference, &o->lo_dev_ref, "lu_object", o);
INIT_LIST_HEAD(&o->lo_linkage);
return 0;
LASSERT(list_empty(&o->lo_linkage));
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;
}
atomic_set(&h->loh_ref, 1);
INIT_LIST_HEAD(&h->loh_lru);
INIT_LIST_HEAD(&h->loh_layers);
- lu_ref_init(&h->loh_reference);
return 0;
}
EXPORT_SYMBOL(lu_object_header_init);
{
LASSERT(list_empty(&h->loh_layers));
LASSERT(list_empty(&h->loh_lru));
- lu_ref_fini(&h->loh_reference);
}
EXPORT_SYMBOL(lu_object_header_fini);
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);
}
result = -ENFILE;
atomic_set(&key->lct_used, 1);
- lu_ref_init(&key->lct_reference);
for (i = 0; i < ARRAY_SIZE(lu_keys); ++i) {
if (lu_keys[i])
continue;
break;
}
if (result) {
- lu_ref_fini(&key->lct_reference);
atomic_set(&key->lct_used, 0);
}
return result;
LASSERT(atomic_read(&key->lct_used) > 0);
key->lct_fini(ctx, key, ctx->lc_value[index]);
- lu_ref_del(&key->lct_reference, "ctx", ctx);
if (atomic_dec_and_test(&key->lct_used))
wake_up_var(&key->lct_used);
atomic_dec(&key->lct_used);
wait_var_event(&key->lct_used, atomic_read(&key->lct_used) == 0);
- if (!WARN_ON(lu_keys[key->lct_index] == NULL))
- lu_ref_fini(&key->lct_reference);
-
smp_store_release(&lu_keys[key->lct_index], NULL); /* release key */
}
EXPORT_SYMBOL(lu_context_key_degister);
break;
}
- lu_ref_add_atomic(&key->lct_reference, "ctx", ctx);
atomic_inc(&key->lct_used);
/*
* This is the only place in the code, where an
CDEBUG(D_INFO, "Lustre LU module (%p).\n", &lu_keys);
- result = lu_ref_global_init();
- if (result != 0)
- return result;
-
LU_CONTEXT_KEY_INIT(&lu_global_key);
result = lu_context_key_register(&lu_global_key);
if (result)
- goto out_lu_ref;
+ goto out;
/*
* At this level, we don't know what tags are needed, so allocate them
up_write(&lu_sites_guard);
if (result) {
lu_context_key_degister(&lu_global_key);
- goto out_lu_ref;
+ goto out;
}
/*
down_write(&lu_sites_guard);
lu_env_fini(&lu_shrink_env);
up_write(&lu_sites_guard);
-out_lu_ref:
- lu_ref_global_fini();
+out:
return result;
}
up_write(&lu_sites_guard);
rhashtable_destroy(&lu_env_rhash);
-
- lu_ref_global_fini();
}
static __u32 ls_stats_read(struct lprocfs_stats *stats, int idx)
+++ /dev/null
-// SPDX-License-Identifier: GPL-2.0
-/*
- * GPL HEADER START
- *
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 only,
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License version 2 for more details (a copy is included
- * in the LICENSE file that accompanied this code).
- *
- * You should have received a copy of the GNU General Public License
- * version 2 along with this program; If not, see
- * http://www.gnu.org/licenses/gpl-2.0.html
- *
- * GPL HEADER END
- */
-/*
- * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
- * Use is subject to license terms.
- *
- * Copyright (c) 2012, 2017, Intel Corporation.
- */
-/*
- * This file is part of Lustre, http://www.lustre.org/
- *
- * lustre/obdclass/lu_ref.c
- *
- * Lustre reference.
- *
- * Author: Nikita Danilov <nikita.danilov@sun.com>
- */
-
-#define DEBUG_SUBSYSTEM S_CLASS
-
-#include <obd.h>
-#include <obd_class.h>
-#include <obd_support.h>
-#include <lu_ref.h>
-
-#ifdef CONFIG_LUSTRE_DEBUG_LU_REF
-/**
- * Asserts a condition for a given lu_ref. Must be called with
- * lu_ref::lf_guard held.
- */
-#define REFASSERT(ref, expr) do { \
- struct lu_ref *__tmp = (ref); \
- \
- if (unlikely(!(expr))) { \
- lu_ref_print(__tmp); \
- spin_unlock(&__tmp->lf_guard); \
- lu_ref_print_all(); \
- LASSERT(0); \
- spin_lock(&__tmp->lf_guard); \
- } \
-} while (0)
-
-static struct kmem_cache *lu_ref_link_kmem;
-
-static struct lu_kmem_descr lu_ref_caches[] = {
- {
- .ckd_cache = &lu_ref_link_kmem,
- .ckd_name = "lu_ref_link_kmem",
- .ckd_size = sizeof(struct lu_ref_link)
- },
- {
- .ckd_cache = NULL
- }
-};
-
-/**
- * Global list of active (initialized, but not finalized) lu_ref's.
- *
- * Protected by lu_ref_refs_guard.
- */
-static LIST_HEAD(lu_ref_refs);
-static DEFINE_SPINLOCK(lu_ref_refs_guard);
-static struct lu_ref lu_ref_marker = {
- .lf_guard = __SPIN_LOCK_UNLOCKED(lu_ref_marker.lf_guard),
- .lf_list = LIST_HEAD_INIT(lu_ref_marker.lf_list),
- .lf_linkage = LIST_HEAD_INIT(lu_ref_marker.lf_linkage)
-};
-
-void lu_ref_print(const struct lu_ref *ref)
-{
- struct lu_ref_link *link;
-
- CERROR("lu_ref: %p %d %d %s:%d\n",
- ref, ref->lf_refs, ref->lf_failed, ref->lf_func, ref->lf_line);
- list_for_each_entry(link, &ref->lf_list, ll_linkage) {
- CERROR(" link: %s %p\n", link->ll_scope, link->ll_source);
- }
-}
-
-static int lu_ref_is_marker(const struct lu_ref *ref)
-{
- return ref == &lu_ref_marker;
-}
-
-void lu_ref_print_all(void)
-{
- struct lu_ref *ref;
-
- spin_lock(&lu_ref_refs_guard);
- list_for_each_entry(ref, &lu_ref_refs, lf_linkage) {
- if (lu_ref_is_marker(ref))
- continue;
-
- spin_lock(&ref->lf_guard);
- lu_ref_print(ref);
- spin_unlock(&ref->lf_guard);
- }
- spin_unlock(&lu_ref_refs_guard);
-}
-
-void lu_ref_init_loc(struct lu_ref *ref, const char *func, const int line)
-{
- ref->lf_refs = 0;
- ref->lf_func = func;
- ref->lf_line = line;
- spin_lock_init(&ref->lf_guard);
- INIT_LIST_HEAD(&ref->lf_list);
- spin_lock(&lu_ref_refs_guard);
- list_add(&ref->lf_linkage, &lu_ref_refs);
- spin_unlock(&lu_ref_refs_guard);
-}
-EXPORT_SYMBOL(lu_ref_init_loc);
-
-void lu_ref_fini(struct lu_ref *ref)
-{
- spin_lock(&ref->lf_guard);
- REFASSERT(ref, list_empty(&ref->lf_list));
- REFASSERT(ref, ref->lf_refs == 0);
- spin_unlock(&ref->lf_guard);
- spin_lock(&lu_ref_refs_guard);
- list_del_init(&ref->lf_linkage);
- spin_unlock(&lu_ref_refs_guard);
-}
-EXPORT_SYMBOL(lu_ref_fini);
-
-static struct lu_ref_link *lu_ref_add_context(struct lu_ref *ref,
- int flags,
- const char *scope,
- const void *source)
-{
- struct lu_ref_link *link;
-
- link = NULL;
- if (lu_ref_link_kmem) {
- OBD_SLAB_ALLOC_PTR_GFP(link, lu_ref_link_kmem, flags);
- if (link) {
- link->ll_ref = ref;
- link->ll_scope = scope;
- link->ll_source = source;
- spin_lock(&ref->lf_guard);
- list_add_tail(&link->ll_linkage, &ref->lf_list);
- ref->lf_refs++;
- spin_unlock(&ref->lf_guard);
- }
- }
-
- if (!link) {
- spin_lock(&ref->lf_guard);
- ref->lf_failed++;
- spin_unlock(&ref->lf_guard);
- link = ERR_PTR(-ENOMEM);
- }
-
- return link;
-}
-
-void lu_ref_add(struct lu_ref *ref, const char *scope, const void *source)
-{
- might_sleep();
- lu_ref_add_context(ref, GFP_NOFS, scope, source);
-}
-EXPORT_SYMBOL(lu_ref_add);
-
-void lu_ref_add_at(struct lu_ref *ref, struct lu_ref_link *link,
- const char *scope, const void *source)
-{
- link->ll_ref = ref;
- link->ll_scope = scope;
- link->ll_source = source;
- spin_lock(&ref->lf_guard);
- list_add_tail(&link->ll_linkage, &ref->lf_list);
- ref->lf_refs++;
- spin_unlock(&ref->lf_guard);
-}
-EXPORT_SYMBOL(lu_ref_add_at);
-
-/**
- * Version of lu_ref_add() to be used in non-blockable contexts.
- */
-void lu_ref_add_atomic(struct lu_ref *ref, const char *scope,
- const void *source)
-{
- lu_ref_add_context(ref, GFP_ATOMIC, scope, source);
-}
-EXPORT_SYMBOL(lu_ref_add_atomic);
-
-static inline int lu_ref_link_eq(const struct lu_ref_link *link,
- const char *scope,
- const void *source)
-{
- return link->ll_source == source && !strcmp(link->ll_scope, scope);
-}
-
-/**
- * Maximal chain length seen so far.
- */
-static unsigned int lu_ref_chain_max_length = 127;
-
-/**
- * Searches for a lu_ref_link with given [scope, source] within given lu_ref.
- */
-static struct lu_ref_link *lu_ref_find(struct lu_ref *ref, const char *scope,
- const void *source)
-{
- struct lu_ref_link *link;
- unsigned int iterations;
-
- iterations = 0;
- list_for_each_entry(link, &ref->lf_list, ll_linkage) {
- ++iterations;
- if (lu_ref_link_eq(link, scope, source)) {
- if (iterations > lu_ref_chain_max_length) {
- CWARN("Long lu_ref chain %d \"%s\":%p\n",
- iterations, scope, source);
- lu_ref_chain_max_length = iterations * 3 / 2;
- }
- return link;
- }
- }
- return NULL;
-}
-
-void lu_ref_del(struct lu_ref *ref, const char *scope, const void *source)
-{
- struct lu_ref_link *link;
-
- spin_lock(&ref->lf_guard);
- link = lu_ref_find(ref, scope, source);
- if (link) {
- list_del(&link->ll_linkage);
- ref->lf_refs--;
- spin_unlock(&ref->lf_guard);
- OBD_SLAB_FREE(link, lu_ref_link_kmem, sizeof(*link));
- } else {
- REFASSERT(ref, ref->lf_failed > 0);
- ref->lf_failed--;
- spin_unlock(&ref->lf_guard);
- }
-}
-EXPORT_SYMBOL(lu_ref_del);
-
-void lu_ref_set_at(struct lu_ref *ref, struct lu_ref_link *link,
- const char *scope,
- const void *source0, const void *source1)
-{
- spin_lock(&ref->lf_guard);
- REFASSERT(ref, !IS_ERR_OR_NULL(link));
- REFASSERT(ref, link->ll_ref == ref);
- REFASSERT(ref, lu_ref_link_eq(link, scope, source0));
- link->ll_source = source1;
- spin_unlock(&ref->lf_guard);
-}
-EXPORT_SYMBOL(lu_ref_set_at);
-
-void lu_ref_del_at(struct lu_ref *ref, struct lu_ref_link *link,
- const char *scope, const void *source)
-{
- spin_lock(&ref->lf_guard);
- REFASSERT(ref, !IS_ERR_OR_NULL(link));
- REFASSERT(ref, link->ll_ref == ref);
- REFASSERT(ref, lu_ref_link_eq(link, scope, source));
- list_del(&link->ll_linkage);
- ref->lf_refs--;
- spin_unlock(&ref->lf_guard);
-}
-EXPORT_SYMBOL(lu_ref_del_at);
-
-static void *lu_ref_seq_start(struct seq_file *seq, loff_t *pos)
-{
- struct lu_ref *ref = seq->private;
-
- spin_lock(&lu_ref_refs_guard);
- if (list_empty(&ref->lf_linkage))
- ref = NULL;
- spin_unlock(&lu_ref_refs_guard);
-
- return ref;
-}
-
-static void *lu_ref_seq_next(struct seq_file *seq, void *p, loff_t *pos)
-{
- struct lu_ref *ref = p;
- struct lu_ref *next;
-
- LASSERT(seq->private == p);
- LASSERT(!list_empty(&ref->lf_linkage));
-
- (*pos)++;
- spin_lock(&lu_ref_refs_guard);
- next = list_entry(ref->lf_linkage.next, struct lu_ref, lf_linkage);
- if (&next->lf_linkage == &lu_ref_refs)
- p = NULL;
- else
- list_move(&ref->lf_linkage, &next->lf_linkage);
- spin_unlock(&lu_ref_refs_guard);
-
- return p;
-}
-
-static void lu_ref_seq_stop(struct seq_file *seq, void *p)
-{
- /* Nothing to do */
-}
-
-
-static int lu_ref_seq_show(struct seq_file *seq, void *p)
-{
- struct lu_ref *ref = p;
- struct lu_ref *next;
-
- spin_lock(&lu_ref_refs_guard);
- next = list_entry(ref->lf_linkage.next, struct lu_ref, lf_linkage);
- if ((&next->lf_linkage == &lu_ref_refs) || lu_ref_is_marker(next)) {
- spin_unlock(&lu_ref_refs_guard);
- return 0;
- }
-
- /* print the entry */
- spin_lock(&next->lf_guard);
- seq_printf(seq, "lu_ref: %p %d %d %s:%d\n",
- next, next->lf_refs, next->lf_failed,
- next->lf_func, next->lf_line);
- if (next->lf_refs > 64) {
- seq_puts(seq, " too many references, skip\n");
- } else {
- struct lu_ref_link *link;
- int i = 0;
-
- list_for_each_entry(link, &next->lf_list, ll_linkage)
- seq_printf(seq, " #%d link: %s %p\n",
- i++, link->ll_scope, link->ll_source);
- }
- spin_unlock(&next->lf_guard);
- spin_unlock(&lu_ref_refs_guard);
-
- return 0;
-}
-
-static const struct seq_operations lu_ref_seq_ops = {
- .start = lu_ref_seq_start,
- .stop = lu_ref_seq_stop,
- .next = lu_ref_seq_next,
- .show = lu_ref_seq_show
-};
-
-static int lu_ref_seq_open(struct inode *inode, struct file *file)
-{
- struct lu_ref *marker = &lu_ref_marker;
- int result = 0;
-
- result = seq_open(file, &lu_ref_seq_ops);
- if (result == 0) {
- spin_lock(&lu_ref_refs_guard);
- if (!list_empty(&marker->lf_linkage))
- result = -EAGAIN;
- else
- list_add(&marker->lf_linkage, &lu_ref_refs);
- spin_unlock(&lu_ref_refs_guard);
-
- if (result == 0) {
- struct seq_file *f = file->private_data;
-
- f->private = marker;
- } else {
- seq_release(inode, file);
- }
- }
-
- return result;
-}
-
-static int lu_ref_seq_release(struct inode *inode, struct file *file)
-{
- struct seq_file *m = file->private_data;
- struct lu_ref *ref = m->private;
-
- spin_lock(&lu_ref_refs_guard);
- list_del_init(&ref->lf_linkage);
- spin_unlock(&lu_ref_refs_guard);
-
- return seq_release(inode, file);
-}
-
-static const struct file_operations lu_ref_dump_fops = {
- .owner = THIS_MODULE,
- .open = lu_ref_seq_open,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = lu_ref_seq_release
-};
-
-int lu_ref_global_init(void)
-{
- int result;
-
- CDEBUG(D_CONSOLE,
- "lu_ref tracking is enabled. Performance isn't.\n");
-
- result = lu_kmem_init(lu_ref_caches);
- if (result)
- return result;
-
- debugfs_create_file("lu_refs", 0444, debugfs_lustre_root,
- NULL, &lu_ref_dump_fops);
-
- return result;
-}
-
-void lu_ref_global_fini(void)
-{
- /* debugfs file gets cleaned up by debugfs_remove_recursive on
- * debugfs_lustre_root
- */
- lu_kmem_fini(lu_ref_caches);
-}
-
-#endif /* CONFIG_LUSTRE_DEBUG_LU_REF */
const char *scope,
const void *source)
{
- lu_ref_add_atomic(&obd->obd_reference, scope, source);
kref_get(&obd->obd_refcount);
CDEBUG(D_INFO, "incref %s (%p) now %d - %s\n", obd->obd_name, obd,
kref_read(&obd->obd_refcount), scope);
kref_read(&obd->obd_refcount), scope);
LASSERT(obd->obd_num_exports >= 0);
kref_put(&obd->obd_refcount, class_decref_free);
- lu_ref_del(&obd->obd_reference, scope, source);
}
EXPORT_SYMBOL(class_decref);
LASSERT(RB_EMPTY_NODE(&ext->oe_node));
if (ext->oe_dlmlock) {
- lu_ref_del(&ext->oe_dlmlock->l_reference,
- "osc_extent", ext);
LDLM_LOCK_RELEASE(ext->oe_dlmlock);
ext->oe_dlmlock = NULL;
}
if (olck->ols_dlmlock != NULL) {
LASSERT(olck->ols_hold);
cur->oe_dlmlock = LDLM_LOCK_GET(olck->ols_dlmlock);
- lu_ref_add(&olck->ols_dlmlock->l_reference, "osc_extent", cur);
}
/* grants has been allocated by caller */
list_del_init(&oap->oap_pending_item);
cl_page_get(page);
- lu_ref_add(&page->cp_reference, "truncate", current);
if (cl_page_own(env, io, page) == 0) {
cl_page_discard(env, io, page);
LASSERT(0);
}
- lu_ref_del(&page->cp_reference, "truncate", current);
cl_batch_put(env, page, fbatch);
--ext->oe_nr_pages;
* released in cl_page_completion() and nothing except for the
* reference counter protects page from concurrent reclaim.
*/
- lu_ref_del(&page->cp_reference, "transfer", page);
/* for transient pages, the last reference is destroyed by the
* cl_page_completion process, so do not referencce the page after this
while ((osc = osc_next_obj(cli)) != NULL) {
struct cl_object *obj = osc2cl(osc);
- struct lu_ref_link link;
OSC_IO_DEBUG(osc, "%lu in flight\n", rpcs_in_flight(cli));
cl_object_get(obj);
spin_unlock(&cli->cl_loi_list_lock);
- lu_object_ref_add_at(&obj->co_lu, &link, "check", current);
/* attempt some read/write balancing by alternating between
* reads and writes in an object. The makes_rpc checks here
osc_object_unlock(osc);
osc_list_maint(cli, osc);
- lu_object_ref_del_at(&obj->co_lu, &link, "check", current);
cl_object_put(env, obj);
spin_lock(&cli->cl_loi_list_lock);
oscl = oio->oi_write_osclock ? : oio->oi_read_osclock;
if (oscl && oscl->ols_dlmlock != NULL) {
ext->oe_dlmlock = LDLM_LOCK_GET(oscl->ols_dlmlock);
- lu_ref_add(&ext->oe_dlmlock->l_reference, "osc_extent", ext);
}
if (ext->oe_dio && !ext->oe_rw) { /* direct io write */
int grants;
continue;
cl_page_get(page);
- lu_ref_add_atomic(&page->cp_reference,
- "gang_lookup", current);
pvec[j++] = ops;
}
++idx;
for (i = 0; i < j; ++i) {
ops = pvec[i];
page = ops->ops_cl.cpl_page;
- lu_ref_del(&page->cp_reference, "gang_lookup", current);
cl_batch_put(env, page, fbatch);
}
folio_batch_release(fbatch);
/* lock reference taken by ldlm_handle2lock_long() is
* owned by osc_lock and released in osc_lock_detach()
*/
- lu_ref_add_atomic(&dlmlock->l_reference, "osc_lock", oscl);
oscl->ols_has_ref = 1;
LASSERT(oscl->ols_dlmlock == NULL);
/* release a reference taken in osc_lock_upcall(). */
LASSERT(olck->ols_has_ref);
- lu_ref_del(&dlmlock->l_reference, "osc_lock", olck);
LDLM_LOCK_RELEASE(dlmlock);
olck->ols_has_ref = 0;
LASSERT(!opg->ops_transfer_pinned);
cl_page_get(page);
- lu_ref_add_atomic(&page->cp_reference, label, page);
opg->ops_transfer_pinned = 1;
}
if (opg->ops_transfer_pinned) {
opg->ops_transfer_pinned = 0;
- lu_ref_del(&page->cp_reference, "transfer", page);
cl_page_put(env, page);
}
}
if (IS_ERR(res))
RETURN(0);
- LDLM_RESOURCE_ADDREF(res);
count = ldlm_cancel_resource_local(res, cancels, NULL, mode,
lock_flags, 0, NULL);
- LDLM_RESOURCE_DELREF(res);
ldlm_resource_putref(res);
RETURN(count);
}
dcb->dcb_func(NULL, th, dcb, error);
}
- lu_ref_del_at(&lud->ld_reference, &oh->ot_dev_link, "osd-tx", th);
if (atomic_dec_and_test(&osd->od_commit_cb_in_flight))
wake_up(&osd->od_commit_cb_done);
th->th_dev = NULL;
LASSERT(oti->oti_txns == 0);
atomic_inc(&dev->od_commit_cb_in_flight);
- lu_ref_add_at(&d->dd_lu_dev.ld_reference, &oh->ot_dev_link,
- "osd-tx", th);
oti->oti_txns++;
rc = 0;
} else {
struct ldiskfs_journal_cb_entry ot_jcb;
struct list_head ot_commit_dcb_list;
struct list_head ot_stop_dcb_list;
- /* Link to the device, for debugging. */
- struct lu_ref_link ot_dev_link;
unsigned int ot_credits;
unsigned int oh_declared_ext;
/* grab reference on master target that this pool belongs to */
lu_device_get(qmt2lu_dev(qmt));
- lu_ref_add(&qmt2lu_dev(qmt)->ld_reference, "pool", pool);
pool->qpi_qmt = qmt;
/* create pool proc directory */
if (pool->qpi_qmt != NULL) {
struct lu_device *ld = qmt2lu_dev(pool->qpi_qmt);
- lu_ref_del(&ld->ld_reference, "pool", pool);
lu_device_put(ld);
pool->qpi_qmt = NULL;
}
qqi_reint:1, /* in reintegration or not */
qqi_acct_failed:1; /* failed to setup acct */
- /* A list of references to this instance, for debugging */
- struct lu_ref qqi_reference;
-
/* default quota setting*/
__u64 qqi_default_hardlimit;
__u64 qqi_default_softlimit;
/* by now, all qqi users should have gone away */
LASSERT(atomic_read(&qqi->qqi_ref) == 1);
- lu_ref_fini(&qqi->qqi_reference);
/* release accounting object */
if (qqi->qqi_acct_obj != NULL && !IS_ERR(qqi->qqi_acct_obj)) {
/* set backpointer and other parameters */
qqi->qqi_qsd = qsd;
qqi->qqi_qtype = qtype;
- lu_ref_init(&qqi->qqi_reference);
qqi->qqi_glb_uptodate = false;
qqi->qqi_slv_uptodate = false;
qqi->qqi_reint = false;
/* release reference on dt_device */
if (qsd->qsd_dev != NULL) {
- lu_ref_del(&qsd->qsd_dev->dd_lu_dev.ld_reference, "qsd", qsd);
lu_device_put(&qsd->qsd_dev->dd_lu_dev);
qsd->qsd_dev = NULL;
}
/* grab reference on osd device */
lu_device_get(&dev->dd_lu_dev);
- lu_ref_add(&dev->dd_lu_dev.ld_reference, "qsd", qsd);
qsd->qsd_dev = dev;
/* get fsname from svname */
}
unlock_res_and_lock(lock);
- if (qqi)
- /* it is not safe to call lu_ref_add() under spinlock */
- lu_ref_add(&qqi->qqi_reference, "ast_data_get", lock);
-
if (reset && qqi) {
- /* release qqi reference hold for the lock */
- lu_ref_del(&qqi->qqi_reference, "glb_lock", lock);
qqi_putref(qqi);
}
RETURN(qqi);
if (!ldlm_is_local_only(lock))
qsd_start_reint_thread(qqi);
- lu_ref_del(&qqi->qqi_reference, "ast_data_get", lock);
qqi_putref(qqi);
break;
}
desc->gl_ver, true);
EXIT;
out_qqi:
- lu_ref_del(&qqi->qqi_reference, "ast_data_get", lock);
qqi_putref(qqi);
out:
req->rq_status = rc;
qsd->qsd_svname, PFID(&qqi->qqi_fid));
qqi_getref(qqi);
- lu_ref_add(&qqi->qqi_reference, "reint_thread", current);
qti = qsd_info(env);
complete(args->qra_started);
if (xchg(&qqi->qqi_reint_task, NULL) == NULL)
wait_var_event(qqi, kthread_should_stop());
- lu_ref_del(&qqi->qqi_reference, "reint_thread", current);
qqi_putref(qqi);
return rc;
switch(it_op) {
case IT_QUOTA_CONN:
/* grab reference on qqi for new lock */
-#ifdef CONFIG_LUSTRE_DEBUG_LU_REF
- {
- struct ldlm_lock *lock;
-
- lock = ldlm_handle2lock(&qti->qti_lockh);
- if (lock == NULL) {
- ptlrpc_req_put(req);
- GOTO(out, rc = -ENOLCK);
- }
- lu_ref_add(&qqi->qqi_reference, "glb_lock", lock);
- LDLM_LOCK_PUT(lock);
- }
-#endif
qqi_getref(qqi);
break;
case IT_QUOTA_DQACQ: