diff options
author | Mauro Carvalho Chehab <mchehab@s-opensource.com> | 2017-05-14 16:13:21 -0400 |
---|---|---|
committer | Jonathan Corbet <corbet@lwn.net> | 2017-07-14 15:51:45 -0400 |
commit | d6ac1c7e2fa3bfe20ac078cdc49104babf015ca2 (patch) | |
tree | 3b6a7d3cf727d962424ae7ed3231cf1488a49bc9 /Documentation/kref.txt | |
parent | a1dac767622c001c72373534e557bd3dcb61434b (diff) |
kref.txt: standardize document format
Each text file under Documentation follows a different
format. Some doesn't even have titles!
Change its representation to follow the adopted standard,
using ReST markups for it to be parseable by Sphinx:
- add a title for the document and section titles;
- move authorship information to the beginning and use
:Author:
- mark literal blocks as such and ident them if needed.
Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
Signed-off-by: Jonathan Corbet <corbet@lwn.net>
Diffstat (limited to 'Documentation/kref.txt')
-rw-r--r-- | Documentation/kref.txt | 295 |
1 files changed, 155 insertions, 140 deletions
diff --git a/Documentation/kref.txt b/Documentation/kref.txt index d26a27ca964d..3af384156d7e 100644 --- a/Documentation/kref.txt +++ b/Documentation/kref.txt | |||
@@ -1,24 +1,42 @@ | |||
1 | =================================================== | ||
2 | Adding reference counters (krefs) to kernel objects | ||
3 | =================================================== | ||
4 | |||
5 | :Author: Corey Minyard <minyard@acm.org> | ||
6 | :Author: Thomas Hellstrom <thellstrom@vmware.com> | ||
7 | |||
8 | A lot of this was lifted from Greg Kroah-Hartman's 2004 OLS paper and | ||
9 | presentation on krefs, which can be found at: | ||
10 | |||
11 | - http://www.kroah.com/linux/talks/ols_2004_kref_paper/Reprint-Kroah-Hartman-OLS2004.pdf | ||
12 | - http://www.kroah.com/linux/talks/ols_2004_kref_talk/ | ||
13 | |||
14 | Introduction | ||
15 | ============ | ||
1 | 16 | ||
2 | krefs allow you to add reference counters to your objects. If you | 17 | krefs allow you to add reference counters to your objects. If you |
3 | have objects that are used in multiple places and passed around, and | 18 | have objects that are used in multiple places and passed around, and |
4 | you don't have refcounts, your code is almost certainly broken. If | 19 | you don't have refcounts, your code is almost certainly broken. If |
5 | you want refcounts, krefs are the way to go. | 20 | you want refcounts, krefs are the way to go. |
6 | 21 | ||
7 | To use a kref, add one to your data structures like: | 22 | To use a kref, add one to your data structures like:: |
8 | 23 | ||
9 | struct my_data | 24 | struct my_data |
10 | { | 25 | { |
11 | . | 26 | . |
12 | . | 27 | . |
13 | struct kref refcount; | 28 | struct kref refcount; |
14 | . | 29 | . |
15 | . | 30 | . |
16 | }; | 31 | }; |
17 | 32 | ||
18 | The kref can occur anywhere within the data structure. | 33 | The kref can occur anywhere within the data structure. |
19 | 34 | ||
35 | Initialization | ||
36 | ============== | ||
37 | |||
20 | You must initialize the kref after you allocate it. To do this, call | 38 | You must initialize the kref after you allocate it. To do this, call |
21 | kref_init as so: | 39 | kref_init as so:: |
22 | 40 | ||
23 | struct my_data *data; | 41 | struct my_data *data; |
24 | 42 | ||
@@ -29,18 +47,25 @@ kref_init as so: | |||
29 | 47 | ||
30 | This sets the refcount in the kref to 1. | 48 | This sets the refcount in the kref to 1. |
31 | 49 | ||
50 | Kref rules | ||
51 | ========== | ||
52 | |||
32 | Once you have an initialized kref, you must follow the following | 53 | Once you have an initialized kref, you must follow the following |
33 | rules: | 54 | rules: |
34 | 55 | ||
35 | 1) If you make a non-temporary copy of a pointer, especially if | 56 | 1) If you make a non-temporary copy of a pointer, especially if |
36 | it can be passed to another thread of execution, you must | 57 | it can be passed to another thread of execution, you must |
37 | increment the refcount with kref_get() before passing it off: | 58 | increment the refcount with kref_get() before passing it off:: |
59 | |||
38 | kref_get(&data->refcount); | 60 | kref_get(&data->refcount); |
61 | |||
39 | If you already have a valid pointer to a kref-ed structure (the | 62 | If you already have a valid pointer to a kref-ed structure (the |
40 | refcount cannot go to zero) you may do this without a lock. | 63 | refcount cannot go to zero) you may do this without a lock. |
41 | 64 | ||
42 | 2) When you are done with a pointer, you must call kref_put(): | 65 | 2) When you are done with a pointer, you must call kref_put():: |
66 | |||
43 | kref_put(&data->refcount, data_release); | 67 | kref_put(&data->refcount, data_release); |
68 | |||
44 | If this is the last reference to the pointer, the release | 69 | If this is the last reference to the pointer, the release |
45 | routine will be called. If the code never tries to get | 70 | routine will be called. If the code never tries to get |
46 | a valid pointer to a kref-ed structure without already | 71 | a valid pointer to a kref-ed structure without already |
@@ -53,25 +78,25 @@ rules: | |||
53 | structure must remain valid during the kref_get(). | 78 | structure must remain valid during the kref_get(). |
54 | 79 | ||
55 | For example, if you allocate some data and then pass it to another | 80 | For example, if you allocate some data and then pass it to another |
56 | thread to process: | 81 | thread to process:: |
57 | 82 | ||
58 | void data_release(struct kref *ref) | 83 | void data_release(struct kref *ref) |
59 | { | 84 | { |
60 | struct my_data *data = container_of(ref, struct my_data, refcount); | 85 | struct my_data *data = container_of(ref, struct my_data, refcount); |
61 | kfree(data); | 86 | kfree(data); |
62 | } | 87 | } |
63 | 88 | ||
64 | void more_data_handling(void *cb_data) | 89 | void more_data_handling(void *cb_data) |
65 | { | 90 | { |
66 | struct my_data *data = cb_data; | 91 | struct my_data *data = cb_data; |
67 | . | 92 | . |
68 | . do stuff with data here | 93 | . do stuff with data here |
69 | . | 94 | . |
70 | kref_put(&data->refcount, data_release); | 95 | kref_put(&data->refcount, data_release); |
71 | } | 96 | } |
72 | 97 | ||
73 | int my_data_handler(void) | 98 | int my_data_handler(void) |
74 | { | 99 | { |
75 | int rv = 0; | 100 | int rv = 0; |
76 | struct my_data *data; | 101 | struct my_data *data; |
77 | struct task_struct *task; | 102 | struct task_struct *task; |
@@ -91,10 +116,10 @@ int my_data_handler(void) | |||
91 | . | 116 | . |
92 | . do stuff with data here | 117 | . do stuff with data here |
93 | . | 118 | . |
94 | out: | 119 | out: |
95 | kref_put(&data->refcount, data_release); | 120 | kref_put(&data->refcount, data_release); |
96 | return rv; | 121 | return rv; |
97 | } | 122 | } |
98 | 123 | ||
99 | This way, it doesn't matter what order the two threads handle the | 124 | This way, it doesn't matter what order the two threads handle the |
100 | data, the kref_put() handles knowing when the data is not referenced | 125 | data, the kref_put() handles knowing when the data is not referenced |
@@ -104,7 +129,7 @@ put needs no lock because nothing tries to get the data without | |||
104 | already holding a pointer. | 129 | already holding a pointer. |
105 | 130 | ||
106 | Note that the "before" in rule 1 is very important. You should never | 131 | Note that the "before" in rule 1 is very important. You should never |
107 | do something like: | 132 | do something like:: |
108 | 133 | ||
109 | task = kthread_run(more_data_handling, data, "more_data_handling"); | 134 | task = kthread_run(more_data_handling, data, "more_data_handling"); |
110 | if (task == ERR_PTR(-ENOMEM)) { | 135 | if (task == ERR_PTR(-ENOMEM)) { |
@@ -124,14 +149,14 @@ bad style. Don't do it. | |||
124 | There are some situations where you can optimize the gets and puts. | 149 | There are some situations where you can optimize the gets and puts. |
125 | For instance, if you are done with an object and enqueuing it for | 150 | For instance, if you are done with an object and enqueuing it for |
126 | something else or passing it off to something else, there is no reason | 151 | something else or passing it off to something else, there is no reason |
127 | to do a get then a put: | 152 | to do a get then a put:: |
128 | 153 | ||
129 | /* Silly extra get and put */ | 154 | /* Silly extra get and put */ |
130 | kref_get(&obj->ref); | 155 | kref_get(&obj->ref); |
131 | enqueue(obj); | 156 | enqueue(obj); |
132 | kref_put(&obj->ref, obj_cleanup); | 157 | kref_put(&obj->ref, obj_cleanup); |
133 | 158 | ||
134 | Just do the enqueue. A comment about this is always welcome: | 159 | Just do the enqueue. A comment about this is always welcome:: |
135 | 160 | ||
136 | enqueue(obj); | 161 | enqueue(obj); |
137 | /* We are done with obj, so we pass our refcount off | 162 | /* We are done with obj, so we pass our refcount off |
@@ -142,109 +167,99 @@ instance, you have a list of items that are each kref-ed, and you wish | |||
142 | to get the first one. You can't just pull the first item off the list | 167 | to get the first one. You can't just pull the first item off the list |
143 | and kref_get() it. That violates rule 3 because you are not already | 168 | and kref_get() it. That violates rule 3 because you are not already |
144 | holding a valid pointer. You must add a mutex (or some other lock). | 169 | holding a valid pointer. You must add a mutex (or some other lock). |
145 | For instance: | 170 | For instance:: |
146 | 171 | ||
147 | static DEFINE_MUTEX(mutex); | 172 | static DEFINE_MUTEX(mutex); |
148 | static LIST_HEAD(q); | 173 | static LIST_HEAD(q); |
149 | struct my_data | 174 | struct my_data |
150 | { | 175 | { |
151 | struct kref refcount; | 176 | struct kref refcount; |
152 | struct list_head link; | 177 | struct list_head link; |
153 | }; | 178 | }; |
154 | 179 | ||
155 | static struct my_data *get_entry() | 180 | static struct my_data *get_entry() |
156 | { | 181 | { |
157 | struct my_data *entry = NULL; | 182 | struct my_data *entry = NULL; |
158 | mutex_lock(&mutex); | 183 | mutex_lock(&mutex); |
159 | if (!list_empty(&q)) { | 184 | if (!list_empty(&q)) { |
160 | entry = container_of(q.next, struct my_data, link); | 185 | entry = container_of(q.next, struct my_data, link); |
161 | kref_get(&entry->refcount); | 186 | kref_get(&entry->refcount); |
187 | } | ||
188 | mutex_unlock(&mutex); | ||
189 | return entry; | ||
162 | } | 190 | } |
163 | mutex_unlock(&mutex); | ||
164 | return entry; | ||
165 | } | ||
166 | 191 | ||
167 | static void release_entry(struct kref *ref) | 192 | static void release_entry(struct kref *ref) |
168 | { | 193 | { |
169 | struct my_data *entry = container_of(ref, struct my_data, refcount); | 194 | struct my_data *entry = container_of(ref, struct my_data, refcount); |
170 | 195 | ||
171 | list_del(&entry->link); | 196 | list_del(&entry->link); |
172 | kfree(entry); | 197 | kfree(entry); |
173 | } | 198 | } |
174 | 199 | ||
175 | static void put_entry(struct my_data *entry) | 200 | static void put_entry(struct my_data *entry) |
176 | { | 201 | { |
177 | mutex_lock(&mutex); | 202 | mutex_lock(&mutex); |
178 | kref_put(&entry->refcount, release_entry); | 203 | kref_put(&entry->refcount, release_entry); |
179 | mutex_unlock(&mutex); | 204 | mutex_unlock(&mutex); |
180 | } | 205 | } |
181 | 206 | ||
182 | The kref_put() return value is useful if you do not want to hold the | 207 | The kref_put() return value is useful if you do not want to hold the |
183 | lock during the whole release operation. Say you didn't want to call | 208 | lock during the whole release operation. Say you didn't want to call |
184 | kfree() with the lock held in the example above (since it is kind of | 209 | kfree() with the lock held in the example above (since it is kind of |
185 | pointless to do so). You could use kref_put() as follows: | 210 | pointless to do so). You could use kref_put() as follows:: |
186 | 211 | ||
187 | static void release_entry(struct kref *ref) | 212 | static void release_entry(struct kref *ref) |
188 | { | 213 | { |
189 | /* All work is done after the return from kref_put(). */ | 214 | /* All work is done after the return from kref_put(). */ |
190 | } | 215 | } |
191 | 216 | ||
192 | static void put_entry(struct my_data *entry) | 217 | static void put_entry(struct my_data *entry) |
193 | { | 218 | { |
194 | mutex_lock(&mutex); | 219 | mutex_lock(&mutex); |
195 | if (kref_put(&entry->refcount, release_entry)) { | 220 | if (kref_put(&entry->refcount, release_entry)) { |
196 | list_del(&entry->link); | 221 | list_del(&entry->link); |
197 | mutex_unlock(&mutex); | 222 | mutex_unlock(&mutex); |
198 | kfree(entry); | 223 | kfree(entry); |
199 | } else | 224 | } else |
200 | mutex_unlock(&mutex); | 225 | mutex_unlock(&mutex); |
201 | } | 226 | } |
202 | 227 | ||
203 | This is really more useful if you have to call other routines as part | 228 | This is really more useful if you have to call other routines as part |
204 | of the free operations that could take a long time or might claim the | 229 | of the free operations that could take a long time or might claim the |
205 | same lock. Note that doing everything in the release routine is still | 230 | same lock. Note that doing everything in the release routine is still |
206 | preferred as it is a little neater. | 231 | preferred as it is a little neater. |
207 | 232 | ||
208 | |||
209 | Corey Minyard <minyard@acm.org> | ||
210 | |||
211 | A lot of this was lifted from Greg Kroah-Hartman's 2004 OLS paper and | ||
212 | presentation on krefs, which can be found at: | ||
213 | http://www.kroah.com/linux/talks/ols_2004_kref_paper/Reprint-Kroah-Hartman-OLS2004.pdf | ||
214 | and: | ||
215 | http://www.kroah.com/linux/talks/ols_2004_kref_talk/ | ||
216 | |||
217 | |||
218 | The above example could also be optimized using kref_get_unless_zero() in | 233 | The above example could also be optimized using kref_get_unless_zero() in |
219 | the following way: | 234 | the following way:: |
220 | 235 | ||
221 | static struct my_data *get_entry() | 236 | static struct my_data *get_entry() |
222 | { | 237 | { |
223 | struct my_data *entry = NULL; | 238 | struct my_data *entry = NULL; |
224 | mutex_lock(&mutex); | 239 | mutex_lock(&mutex); |
225 | if (!list_empty(&q)) { | 240 | if (!list_empty(&q)) { |
226 | entry = container_of(q.next, struct my_data, link); | 241 | entry = container_of(q.next, struct my_data, link); |
227 | if (!kref_get_unless_zero(&entry->refcount)) | 242 | if (!kref_get_unless_zero(&entry->refcount)) |
228 | entry = NULL; | 243 | entry = NULL; |
244 | } | ||
245 | mutex_unlock(&mutex); | ||
246 | return entry; | ||
229 | } | 247 | } |
230 | mutex_unlock(&mutex); | ||
231 | return entry; | ||
232 | } | ||
233 | 248 | ||
234 | static void release_entry(struct kref *ref) | 249 | static void release_entry(struct kref *ref) |
235 | { | 250 | { |
236 | struct my_data *entry = container_of(ref, struct my_data, refcount); | 251 | struct my_data *entry = container_of(ref, struct my_data, refcount); |
237 | 252 | ||
238 | mutex_lock(&mutex); | 253 | mutex_lock(&mutex); |
239 | list_del(&entry->link); | 254 | list_del(&entry->link); |
240 | mutex_unlock(&mutex); | 255 | mutex_unlock(&mutex); |
241 | kfree(entry); | 256 | kfree(entry); |
242 | } | 257 | } |
243 | 258 | ||
244 | static void put_entry(struct my_data *entry) | 259 | static void put_entry(struct my_data *entry) |
245 | { | 260 | { |
246 | kref_put(&entry->refcount, release_entry); | 261 | kref_put(&entry->refcount, release_entry); |
247 | } | 262 | } |
248 | 263 | ||
249 | Which is useful to remove the mutex lock around kref_put() in put_entry(), but | 264 | Which is useful to remove the mutex lock around kref_put() in put_entry(), but |
250 | it's important that kref_get_unless_zero is enclosed in the same critical | 265 | it's important that kref_get_unless_zero is enclosed in the same critical |
@@ -254,51 +269,51 @@ Note that it is illegal to use kref_get_unless_zero without checking its | |||
254 | return value. If you are sure (by already having a valid pointer) that | 269 | return value. If you are sure (by already having a valid pointer) that |
255 | kref_get_unless_zero() will return true, then use kref_get() instead. | 270 | kref_get_unless_zero() will return true, then use kref_get() instead. |
256 | 271 | ||
257 | The function kref_get_unless_zero also makes it possible to use rcu | 272 | Krefs and RCU |
258 | locking for lookups in the above example: | 273 | ============= |
259 | 274 | ||
260 | struct my_data | 275 | The function kref_get_unless_zero also makes it possible to use rcu |
261 | { | 276 | locking for lookups in the above example:: |
262 | struct rcu_head rhead; | 277 | |
263 | . | 278 | struct my_data |
264 | struct kref refcount; | 279 | { |
265 | . | 280 | struct rcu_head rhead; |
266 | . | 281 | . |
267 | }; | 282 | struct kref refcount; |
268 | 283 | . | |
269 | static struct my_data *get_entry_rcu() | 284 | . |
270 | { | 285 | }; |
271 | struct my_data *entry = NULL; | 286 | |
272 | rcu_read_lock(); | 287 | static struct my_data *get_entry_rcu() |
273 | if (!list_empty(&q)) { | 288 | { |
274 | entry = container_of(q.next, struct my_data, link); | 289 | struct my_data *entry = NULL; |
275 | if (!kref_get_unless_zero(&entry->refcount)) | 290 | rcu_read_lock(); |
276 | entry = NULL; | 291 | if (!list_empty(&q)) { |
292 | entry = container_of(q.next, struct my_data, link); | ||
293 | if (!kref_get_unless_zero(&entry->refcount)) | ||
294 | entry = NULL; | ||
295 | } | ||
296 | rcu_read_unlock(); | ||
297 | return entry; | ||
277 | } | 298 | } |
278 | rcu_read_unlock(); | ||
279 | return entry; | ||
280 | } | ||
281 | 299 | ||
282 | static void release_entry_rcu(struct kref *ref) | 300 | static void release_entry_rcu(struct kref *ref) |
283 | { | 301 | { |
284 | struct my_data *entry = container_of(ref, struct my_data, refcount); | 302 | struct my_data *entry = container_of(ref, struct my_data, refcount); |
285 | 303 | ||
286 | mutex_lock(&mutex); | 304 | mutex_lock(&mutex); |
287 | list_del_rcu(&entry->link); | 305 | list_del_rcu(&entry->link); |
288 | mutex_unlock(&mutex); | 306 | mutex_unlock(&mutex); |
289 | kfree_rcu(entry, rhead); | 307 | kfree_rcu(entry, rhead); |
290 | } | 308 | } |
291 | 309 | ||
292 | static void put_entry(struct my_data *entry) | 310 | static void put_entry(struct my_data *entry) |
293 | { | 311 | { |
294 | kref_put(&entry->refcount, release_entry_rcu); | 312 | kref_put(&entry->refcount, release_entry_rcu); |
295 | } | 313 | } |
296 | 314 | ||
297 | But note that the struct kref member needs to remain in valid memory for a | 315 | But note that the struct kref member needs to remain in valid memory for a |
298 | rcu grace period after release_entry_rcu was called. That can be accomplished | 316 | rcu grace period after release_entry_rcu was called. That can be accomplished |
299 | by using kfree_rcu(entry, rhead) as done above, or by calling synchronize_rcu() | 317 | by using kfree_rcu(entry, rhead) as done above, or by calling synchronize_rcu() |
300 | before using kfree, but note that synchronize_rcu() may sleep for a | 318 | before using kfree, but note that synchronize_rcu() may sleep for a |
301 | substantial amount of time. | 319 | substantial amount of time. |
302 | |||
303 | |||
304 | Thomas Hellstrom <thellstrom@vmware.com> | ||