Commit 4b20db3de8dab005b07c74161cb041db8c5ff3a7
Committed by
Dave Airlie
1 parent
d714455619
Exists in
smarc-l5.0.0_1.0.0-ga
and in
5 other branches
kref: Implement kref_get_unless_zero v3
This function is intended to simplify locking around refcounting for objects that can be looked up from a lookup structure, and which are removed from that lookup structure in the object destructor. Operations on such objects require at least a read lock around lookup + kref_get, and a write lock around kref_put + remove from lookup structure. Furthermore, RCU implementations become extremely tricky. With a lookup followed by a kref_get_unless_zero *with return value check* locking in the kref_put path can be deferred to the actual removal from the lookup structure and RCU lookups become trivial. v2: Formatting fixes. v3: Invert the return value. Signed-off-by: Thomas Hellstrom <thellstrom@vmware.com> Signed-off-by: Dave Airlie <airlied@redhat.com>
Showing 1 changed file with 21 additions and 0 deletions Side-by-side Diff
include/linux/kref.h
... | ... | @@ -111,5 +111,26 @@ |
111 | 111 | } |
112 | 112 | return 0; |
113 | 113 | } |
114 | + | |
115 | +/** | |
116 | + * kref_get_unless_zero - Increment refcount for object unless it is zero. | |
117 | + * @kref: object. | |
118 | + * | |
119 | + * Return non-zero if the increment succeeded. Otherwise return 0. | |
120 | + * | |
121 | + * This function is intended to simplify locking around refcounting for | |
122 | + * objects that can be looked up from a lookup structure, and which are | |
123 | + * removed from that lookup structure in the object destructor. | |
124 | + * Operations on such objects require at least a read lock around | |
125 | + * lookup + kref_get, and a write lock around kref_put + remove from lookup | |
126 | + * structure. Furthermore, RCU implementations become extremely tricky. | |
127 | + * With a lookup followed by a kref_get_unless_zero *with return value check* | |
128 | + * locking in the kref_put path can be deferred to the actual removal from | |
129 | + * the lookup structure and RCU lookups become trivial. | |
130 | + */ | |
131 | +static inline int __must_check kref_get_unless_zero(struct kref *kref) | |
132 | +{ | |
133 | + return atomic_add_unless(&kref->refcount, 1, 0); | |
134 | +} | |
114 | 135 | #endif /* _KREF_H_ */ |