1/* 2 * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. 3 * Use is subject to license terms. 4 * 5 * Copyright (c) 2012, Intel Corporation. 6 * 7 * Author: Nikita Danilov <nikita.danilov@sun.com> 8 * 9 * This file is part of Lustre, http://www.lustre.org. 10 * 11 * Lustre is free software; you can redistribute it and/or 12 * modify it under the terms of version 2 of the GNU General Public 13 * License as published by the Free Software Foundation. 14 * 15 * Lustre is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU General Public License for more details. 19 * 20 * You should have received a copy of the GNU General Public License 21 * along with Lustre; if not, write to the Free Software 22 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 23 * 24 */ 25 26#ifndef __LUSTRE_LU_REF_H 27#define __LUSTRE_LU_REF_H 28 29#include <linux/list.h> 30 31/** \defgroup lu_ref lu_ref 32 * 33 * An interface to track references between objects. Mostly for debugging. 34 * 35 * Suppose there is a reference counted data-structure struct foo. To track 36 * who acquired references to instance of struct foo, add lu_ref field to it: 37 * 38 * \code 39 * struct foo { 40 * atomic_t foo_refcount; 41 * struct lu_ref foo_reference; 42 * ... 43 * }; 44 * \endcode 45 * 46 * foo::foo_reference has to be initialized by calling 47 * lu_ref_init(). Typically there will be functions or macros to increment and 48 * decrement foo::foo_refcount, let's say they are foo_get(struct foo *foo) 49 * and foo_put(struct foo *foo), respectively. 50 * 51 * Whenever foo_get() is called to acquire a reference on a foo, lu_ref_add() 52 * has to be called to insert into foo::foo_reference a record, describing 53 * acquired reference. Dually, lu_ref_del() removes matching record. Typical 54 * usages are: 55 * 56 * \code 57 * struct bar *bar; 58 * 59 * // bar owns a reference to foo. 60 * bar->bar_foo = foo_get(foo); 61 * lu_ref_add(&foo->foo_reference, "bar", bar); 62 * 63 * ... 64 * 65 * // reference from bar to foo is released. 66 * lu_ref_del(&foo->foo_reference, "bar", bar); 67 * foo_put(bar->bar_foo); 68 * 69 * 70 * // current thread acquired a temporary reference to foo. 71 * foo_get(foo); 72 * lu_ref_add(&foo->reference, __FUNCTION__, current); 73 * 74 * ... 75 * 76 * // temporary reference is released. 77 * lu_ref_del(&foo->reference, __FUNCTION__, current); 78 * foo_put(foo); 79 * \endcode 80 * 81 * \e Et \e cetera. Often it makes sense to include lu_ref_add() and 82 * lu_ref_del() calls into foo_get() and foo_put(). When an instance of struct 83 * foo is destroyed, lu_ref_fini() has to be called that checks that no 84 * pending references remain. lu_ref_print() can be used to dump a list of 85 * pending references, while hunting down a leak. 86 * 87 * For objects to which a large number of references can be acquired, 88 * lu_ref_del() can become cpu consuming, as it has to scan the list of 89 * references. To work around this, remember result of lu_ref_add() (usually 90 * in the same place where pointer to struct foo is stored), and use 91 * lu_ref_del_at(): 92 * 93 * \code 94 * // There is a large number of bar's for a single foo. 95 * bar->bar_foo = foo_get(foo); 96 * bar->bar_foo_ref = lu_ref_add(&foo->foo_reference, "bar", bar); 97 * 98 * ... 99 * 100 * // reference from bar to foo is released. 101 * lu_ref_del_at(&foo->foo_reference, bar->bar_foo_ref, "bar", bar); 102 * foo_put(bar->bar_foo); 103 * \endcode 104 * 105 * lu_ref interface degrades gracefully in case of memory shortages. 106 * 107 * @{ 108 */ 109 110 111struct lu_ref {}; 112 113static inline void lu_ref_init(struct lu_ref *ref) 114{ 115} 116 117static inline void lu_ref_fini(struct lu_ref *ref) 118{ 119} 120 121static inline struct lu_ref_link *lu_ref_add(struct lu_ref *ref, 122 const char *scope, 123 const void *source) 124{ 125 return NULL; 126} 127 128static inline struct lu_ref_link *lu_ref_add_atomic(struct lu_ref *ref, 129 const char *scope, 130 const void *source) 131{ 132 return NULL; 133} 134 135static inline void lu_ref_del(struct lu_ref *ref, const char *scope, 136 const void *source) 137{ 138} 139 140static inline void lu_ref_set_at(struct lu_ref *ref, struct lu_ref_link *link, 141 const char *scope, const void *source0, 142 const void *source1) 143{ 144} 145 146static inline void lu_ref_del_at(struct lu_ref *ref, struct lu_ref_link *link, 147 const char *scope, const void *source) 148{ 149} 150 151static inline int lu_ref_global_init(void) 152{ 153 return 0; 154} 155 156static inline void lu_ref_global_fini(void) 157{ 158} 159 160static inline void lu_ref_print(const struct lu_ref *ref) 161{ 162} 163 164static inline void lu_ref_print_all(void) 165{ 166} 167 168/** @} lu */ 169 170#endif /* __LUSTRE_LU_REF_H */ 171