1 // SPDX-License-Identifier: GPL-2.0
3 * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
4 * Use is subject to license terms.
6 * Copyright (c) 2012, 2013, Intel Corporation.
8 * Author: Nikita Danilov <nikita.danilov@sun.com>
10 * This file is part of Lustre, http://www.lustre.org.
12 * Lustre is free software; you can redistribute it and/or
13 * modify it under the terms of version 2 of the GNU General Public
14 * License as published by the Free Software Foundation.
16 * Lustre is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
23 #ifndef __LUSTRE_LU_REF_H
24 #define __LUSTRE_LU_REF_H
26 #include <linux/list.h>
28 /** \defgroup lu_ref lu_ref
30 * An interface to track references between objects. Mostly for debugging.
32 * Suppose there is a reference counted data-structure struct foo. To track
33 * who acquired references to instance of struct foo, add lu_ref field to it:
37 * atomic_t foo_refcount;
38 * struct lu_ref foo_reference;
43 * foo::foo_reference has to be initialized by calling
44 * lu_ref_init(). Typically there will be functions or macros to increment and
45 * decrement foo::foo_refcount, let's say they are foo_get(struct foo *foo)
46 * and foo_put(struct foo *foo), respectively.
48 * Whenever foo_get() is called to acquire a reference on a foo, lu_ref_add()
49 * has to be called to insert into foo::foo_reference a record, describing
50 * acquired reference. Dually, lu_ref_del() removes matching record. Typical
56 * // bar owns a reference to foo.
57 * bar->bar_foo = foo_get(foo);
58 * lu_ref_add(&foo->foo_reference, "bar", bar);
62 * // reference from bar to foo is released.
63 * lu_ref_del(&foo->foo_reference, "bar", bar);
64 * foo_put(bar->bar_foo);
67 * // current thread acquired a temporary reference to foo.
69 * lu_ref_add(&foo->reference, __func__, current);
73 * // temporary reference is released.
74 * lu_ref_del(&foo->reference, __func__, current);
78 * \e Et \e cetera. Often it makes sense to include lu_ref_add() and
79 * lu_ref_del() calls into foo_get() and foo_put(). When an instance of struct
80 * foo is destroyed, lu_ref_fini() has to be called that checks that no
81 * pending references remain. lu_ref_print() can be used to dump a list of
82 * pending references, while hunting down a leak.
84 * For objects to which a large number of references can be acquired,
85 * lu_ref_del() can become cpu consuming, as it has to scan the list of
86 * references. To work around this, remember result of lu_ref_add() (usually
87 * in the same place where pointer to struct foo is stored), and use
91 * // There is a large number of bar's for a single foo.
92 * bar->bar_foo = foo_get(foo);
93 * bar->bar_foo_ref = lu_ref_add(&foo->foo_reference, "bar", bar);
97 * // reference from bar to foo is released.
98 * lu_ref_del_at(&foo->foo_reference, bar->bar_foo_ref, "bar", bar);
99 * foo_put(bar->bar_foo);
102 * lu_ref interface degrades gracefully in case of memory shortages.
107 #ifdef CONFIG_LUSTRE_DEBUG_LU_REF
110 * Data-structure to keep track of references to a given object. This is used
113 * lu_ref is embedded into an object which other entities (objects, threads,
118 * Spin-lock protecting lu_ref::lf_list.
122 * List of all outstanding references (each represented by struct
123 * lu_ref_link), pointing to this object.
125 struct list_head lf_list;
131 * Flag set when lu_ref_add() failed to allocate lu_ref_link. It is
132 * used to mask spurious failure of the following lu_ref_del().
136 * flags - attribute for the lu_ref, for pad and future use.
140 * Where was I initialized?
145 * Linkage into a global list of all lu_ref's (lu_ref_refs).
147 struct list_head lf_linkage;
151 struct lu_ref *ll_ref;
152 struct list_head ll_linkage;
153 const char *ll_scope;
154 const void *ll_source;
157 void lu_ref_init_loc(struct lu_ref *ref, const char *func, const int line);
158 void lu_ref_fini(struct lu_ref *ref);
159 #define lu_ref_init(ref) lu_ref_init_loc(ref, __func__, __LINE__)
161 void lu_ref_add(struct lu_ref *ref, const char *scope, const void *source);
163 void lu_ref_add_atomic(struct lu_ref *ref, const char *scope,
166 void lu_ref_add_at(struct lu_ref *ref, struct lu_ref_link *link,
167 const char *scope, const void *source);
169 void lu_ref_del(struct lu_ref *ref, const char *scope, const void *source);
171 void lu_ref_set_at(struct lu_ref *ref, struct lu_ref_link *link,
172 const char *scope, const void *source0, const void *source1);
174 void lu_ref_del_at(struct lu_ref *ref, struct lu_ref_link *link,
175 const char *scope, const void *source);
177 void lu_ref_print(const struct lu_ref *ref);
179 void lu_ref_print_all(void);
181 int lu_ref_global_init(void);
183 void lu_ref_global_fini(void);
185 #else /* !CONFIG_LUSTRE_DEBUG_LU_REF */
193 static inline void lu_ref_init(struct lu_ref *ref)
197 static inline void lu_ref_fini(struct lu_ref *ref)
201 static inline void lu_ref_add(struct lu_ref *ref,
207 static inline void lu_ref_add_atomic(struct lu_ref *ref,
213 static inline void lu_ref_add_at(struct lu_ref *ref,
214 struct lu_ref_link *link,
220 static inline void lu_ref_del(struct lu_ref *ref, const char *scope,
225 static inline void lu_ref_set_at(struct lu_ref *ref, struct lu_ref_link *link,
226 const char *scope, const void *source0,
231 static inline void lu_ref_del_at(struct lu_ref *ref, struct lu_ref_link *link,
232 const char *scope, const void *source)
236 static inline int lu_ref_global_init(void)
241 static inline void lu_ref_global_fini(void)
245 static inline void lu_ref_print(const struct lu_ref *ref)
249 static inline void lu_ref_print_all(void)
252 #endif /* CONFIG_LUSTRE_DEBUG_LU_REF */
256 #endif /* __LUSTRE_LU_REF_H */