€•Œsphinx.addnodes”Œdocument”“”)�”}”(Œ rawsource”Œ”Œchildren”]”(Œ translations”Œ LanguagesNode”“”)�”}”(hhh]”(hŒ pending_xref”“”)�”}”(hhh]”Œdocutils.nodes”ŒText”“”ŒChinese (Simplified)”…”�”}”Œparent”hsbaŒ attributes”}”(Œids”]”Œclasses”]”Œnames”]”Œdupnames”]”Œbackrefs”]”Œ refdomain”Œstd”Œreftype”Œdoc”Œ reftarget”Œ!/translations/zh_CN/core-api/kref”Œmodname”NŒ classname”NŒ refexplicit”ˆuŒtagname”hhh ubh)�”}”(hhh]”hŒChinese (Traditional)”…”�”}”hh2sbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ!/translations/zh_TW/core-api/kref”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)�”}”(hhh]”hŒItalian”…”�”}”hhFsbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ!/translations/it_IT/core-api/kref”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)�”}”(hhh]”hŒJapanese”…”�”}”hhZsbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ!/translations/ja_JP/core-api/kref”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)�”}”(hhh]”hŒKorean”…”�”}”hhnsbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ!/translations/ko_KR/core-api/kref”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)�”}”(hhh]”hŒPortuguese (Brazilian)”…”�”}”hh‚sbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ!/translations/pt_BR/core-api/kref”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)�”}”(hhh]”hŒSpanish”…”�”}”hh–sbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ!/translations/sp_SP/core-api/kref”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubeh}”(h]”h ]”h"]”h$]”h&]”Œcurrent_language”ŒEnglish”uh1h hhŒ _document”hŒsource”NŒline”NubhŒsection”“”)�”}”(hhh]”(hŒtitle”“”)�”}”(hŒ3Adding reference counters (krefs) to kernel objects”h]”hŒ3Adding reference counters (krefs) to kernel objects”…”�”}”(hh¼h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hºhh·h²hh³Œ;/var/lib/git/docbuild/linux/Documentation/core-api/kref.rst”h´KubhŒ field_list”“”)�”}”(hhh]”(hŒfield”“”)�”}”(hhh]”(hŒ field_name”“”)�”}”(hŒAuthor”h]”hŒAuthor”…”�”}”(hh×h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÕhhÒh³hÊh´KubhŒ field_body”“”)�”}”(hŒCorey Minyard ”h]”hŒ paragraph”“”)�”}”(hhéh]”(hŒCorey Minyard <”…”�”}”(hhíh²hh³Nh´NubhŒ reference”“”)�”}”(hŒminyard@acm.org”h]”hŒminyard@acm.org”…”�”}”(hhöh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”Œrefuri”Œmailto:minyard@acm.org”uh1hôhhíubhŒ>”…”�”}”(hhíh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hëh³hÊh´Khhçubah}”(h]”h ]”h"]”h$]”h&]”uh1håhhÒubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÐh³hÊh´KhhÍh²hubhÑ)�”}”(hhh]”(hÖ)�”}”(hŒAuthor”h]”hŒAuthor”…”�”}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÕhjh³hÊh´Kubhæ)�”}”(hŒ5Thomas Hellström ”h]”hì)�”}”(hŒ4Thomas Hellström ”h]”(hŒThomas Hellström <”…”�”}”(hj1h²hh³Nh´Nubhõ)�”}”(hŒ thomas.hellstrom@linux.intel.com”h]”hŒ thomas.hellstrom@linux.intel.com”…”�”}”(hj9h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”Œrefuri”Œ'mailto:thomas.hellstrom@linux.intel.com”uh1hôhj1ubhŒ>”…”�”}”(hj1h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hëh³hÊh´Khj-ubah}”(h]”h ]”h"]”h$]”h&]”uh1håhjubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÐh³hÊh´KhhÍh²hubeh}”(h]”h ]”h"]”h$]”h&]”uh1hËhh·h²hh³hÊh´Kubhì)�”}”(hŒsA lot of this was lifted from Greg Kroah-Hartman's 2004 OLS paper and presentation on krefs, which can be found at:”h]”hŒuA lot of this was lifted from Greg Kroah-Hartman’s 2004 OLS paper and presentation on krefs, which can be found at:”…”�”}”(hjeh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hëh³hÊh´Khh·h²hubhŒ block_quote”“”)�”}”(hŒ�- http://www.kroah.com/linux/talks/ols_2004_kref_paper/Reprint-Kroah-Hartman-OLS2004.pdf - http://www.kroah.com/linux/talks/ols_2004_kref_talk/ ”h]”hŒ bullet_list”“”)�”}”(hhh]”(hŒ list_item”“”)�”}”(hŒVhttp://www.kroah.com/linux/talks/ols_2004_kref_paper/Reprint-Kroah-Hartman-OLS2004.pdf”h]”hì)�”}”(hj‚h]”hõ)�”}”(hj‚h]”hŒVhttp://www.kroah.com/linux/talks/ols_2004_kref_paper/Reprint-Kroah-Hartman-OLS2004.pdf”…”�”}”(hj‡h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”Œrefuri”j‚uh1hôhj„ubah}”(h]”h ]”h"]”h$]”h&]”uh1hëh³hÊh´K hj€ubah}”(h]”h ]”h"]”h$]”h&]”uh1j~hj{ubj)�”}”(hŒ5http://www.kroah.com/linux/talks/ols_2004_kref_talk/ ”h]”hì)�”}”(hŒ4http://www.kroah.com/linux/talks/ols_2004_kref_talk/”h]”hõ)�”}”(hj§h]”hŒ4http://www.kroah.com/linux/talks/ols_2004_kref_talk/”…”�”}”(hj©h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”Œrefuri”j§uh1hôhj¥ubah}”(h]”h ]”h"]”h$]”h&]”uh1hëh³hÊh´K hj¡ubah}”(h]”h ]”h"]”h$]”h&]”uh1j~hj{ubeh}”(h]”h ]”h"]”h$]”h&]”Œbullet”Œ-”uh1jyh³hÊh´K hjuubah}”(h]”h ]”h"]”h$]”h&]”uh1jsh³hÊh´K hh·h²hubh¶)�”}”(hhh]”(h»)�”}”(hŒ Introduction”h]”hŒ Introduction”…”�”}”(hjÔh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hºhjÑh²hh³hÊh´Kubhì)�”}”(hŒøkrefs allow you to add reference counters to your objects. If you have objects that are used in multiple places and passed around, and you don't have refcounts, your code is almost certainly broken. If you want refcounts, krefs are the way to go.”h]”hŒúkrefs allow you to add reference counters to your objects. If you have objects that are used in multiple places and passed around, and you don’t have refcounts, your code is almost certainly broken. If you want refcounts, krefs are the way to go.”…”�”}”(hjâh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hëh³hÊh´KhjÑh²hubhì)�”}”(hŒ5To use a kref, add one to your data structures like::”h]”hŒ4To use a kref, add one to your data structures like:”…”�”}”(hjðh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hëh³hÊh´KhjÑh²hubhŒ literal_block”“”)�”}”(hŒEstruct my_data { . . struct kref refcount; . . };”h]”hŒEstruct my_data { . . struct kref refcount; . . };”…”�”}”hjsbah}”(h]”h ]”h"]”h$]”h&]”Œ xml:space”Œpreserve”uh1jþh³hÊh´KhjÑh²hubhì)�”}”(hŒ6The kref can occur anywhere within the data structure.”h]”hŒ6The kref can occur anywhere within the data structure.”…”�”}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hëh³hÊh´K!hjÑh²hubeh}”(h]”Œ introduction”ah ]”h"]”Œ introduction”ah$]”h&]”uh1hµhh·h²hh³hÊh´Kubh¶)�”}”(hhh]”(h»)�”}”(hŒInitialization”h]”hŒInitialization”…”�”}”(hj)h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hºhj&h²hh³hÊh´K$ubhì)�”}”(hŒWYou must initialize the kref after you allocate it. To do this, call kref_init as so::”h]”hŒVYou must initialize the kref after you allocate it. To do this, call kref_init as so:”…”�”}”(hj7h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hëh³hÊh´K&hj&h²hubjÿ)�”}”(hŒostruct my_data *data; data = kmalloc_obj(*data); if (!data) return -ENOMEM; kref_init(&data->refcount);”h]”hŒostruct my_data *data; data = kmalloc_obj(*data); if (!data) return -ENOMEM; kref_init(&data->refcount);”…”�”}”hjEsbah}”(h]”h ]”h"]”h$]”h&]”jjuh1jþh³hÊh´K)hj&h²hubhì)�”}”(hŒ(This sets the refcount in the kref to 1.”h]”hŒ(This sets the refcount in the kref to 1.”…”�”}”(hjSh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hëh³hÊh´K0hj&h²hubeh}”(h]”Œinitialization”ah ]”h"]”Œinitialization”ah$]”h&]”uh1hµhh·h²hh³hÊh´K$ubh¶)�”}”(hhh]”(h»)�”}”(hŒ Kref rules”h]”hŒ Kref rules”…”�”}”(hjlh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hºhjih²hh³hÊh´K3ubhì)�”}”(hŒGOnce you have an initialized kref, you must follow the following rules:”h]”hŒGOnce you have an initialized kref, you must follow the following rules:”…”�”}”(hjzh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hëh³hÊh´K5hjih²hubhŒenumerated_list”“”)�”}”(hhh]”(j)�”}”(hXSIf you make a non-temporary copy of a pointer, especially if it can be passed to another thread of execution, you must increment the refcount with kref_get() before passing it off:: kref_get(&data->refcount); If you already have a valid pointer to a kref-ed structure (the refcount cannot go to zero) you may do this without a lock. ”h]”(hì)�”}”(hŒµIf you make a non-temporary copy of a pointer, especially if it can be passed to another thread of execution, you must increment the refcount with kref_get() before passing it off::”h]”hŒ´If you make a non-temporary copy of a pointer, especially if it can be passed to another thread of execution, you must increment the refcount with kref_get() before passing it off:”…”�”}”(hj‘h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hëh³hÊh´K8hj�ubjÿ)�”}”(hŒkref_get(&data->refcount);”h]”hŒkref_get(&data->refcount);”…”�”}”hjŸsbah}”(h]”h ]”h"]”h$]”h&]”jjuh1jþh³hÊh´Khj�ubeh}”(h]”h ]”h"]”h$]”h&]”uh1j~hjŠh²hh³hÊh´Nubj)�”}”(hXTWhen you are done with a pointer, you must call kref_put():: kref_put(&data->refcount, data_release); If this is the last reference to the pointer, the release routine will be called. If the code never tries to get a valid pointer to a kref-ed structure without already holding a valid pointer, it is safe to do this without a lock. ”h]”(hì)�”}”(hŒrefcount, data_release);”h]”hŒ(kref_put(&data->refcount, data_release);”…”�”}”hjÓsbah}”(h]”h ]”h"]”h$]”h&]”jjuh1jþh³hÊh´KChjÁubhì)�”}”(hŒçIf this is the last reference to the pointer, the release routine will be called. If the code never tries to get a valid pointer to a kref-ed structure without already holding a valid pointer, it is safe to do this without a lock.”h]”hŒçIf this is the last reference to the pointer, the release routine will be called. If the code never tries to get a valid pointer to a kref-ed structure without already holding a valid pointer, it is safe to do this without a lock.”…”�”}”(hjáh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hëh³hÊh´KEhjÁubeh}”(h]”h ]”h"]”h$]”h&]”uh1j~hjŠh²hh³hÊh´Nubj)�”}”(hŒôIf the code attempts to gain a reference to a kref-ed structure without already holding a valid pointer, it must serialize access where a kref_put() cannot occur during the kref_get(), and the structure must remain valid during the kref_get(). ”h]”hì)�”}”(hŒóIf the code attempts to gain a reference to a kref-ed structure without already holding a valid pointer, it must serialize access where a kref_put() cannot occur during the kref_get(), and the structure must remain valid during the kref_get().”h]”hŒóIf the code attempts to gain a reference to a kref-ed structure without already holding a valid pointer, it must serialize access where a kref_put() cannot occur during the kref_get(), and the structure must remain valid during the kref_get().”…”�”}”(hjùh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hëh³hÊh´KKhjõubah}”(h]”h ]”h"]”h$]”h&]”uh1j~hjŠh²hh³hÊh´Nubeh}”(h]”h ]”h"]”h$]”h&]”Œenumtype”Œarabic”Œprefix”hŒsuffix”Œ)”uh1jˆhjih²hh³hÊh´K8ubhì)�”}”(hŒVFor example, if you allocate some data and then pass it to another thread to process::”h]”hŒUFor example, if you allocate some data and then pass it to another thread to process:”…”�”}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hëh³hÊh´KPhjih²hubjÿ)�”}”(hX[void data_release(struct kref *ref) { struct my_data *data = container_of(ref, struct my_data, refcount); kfree(data); } void more_data_handling(void *cb_data) { struct my_data *data = cb_data; . . do stuff with data here . kref_put(&data->refcount, data_release); } int my_data_handler(void) { int rv = 0; struct my_data *data; struct task_struct *task; data = kmalloc_obj(*data); if (!data) return -ENOMEM; kref_init(&data->refcount); kref_get(&data->refcount); task = kthread_run(more_data_handling, data, "more_data_handling"); if (task == ERR_PTR(-ENOMEM)) { rv = -ENOMEM; kref_put(&data->refcount, data_release); goto out; } . . do stuff with data here . out: kref_put(&data->refcount, data_release); return rv; }”h]”hX[void data_release(struct kref *ref) { struct my_data *data = container_of(ref, struct my_data, refcount); kfree(data); } void more_data_handling(void *cb_data) { struct my_data *data = cb_data; . . do stuff with data here . kref_put(&data->refcount, data_release); } int my_data_handler(void) { int rv = 0; struct my_data *data; struct task_struct *task; data = kmalloc_obj(*data); if (!data) return -ENOMEM; kref_init(&data->refcount); kref_get(&data->refcount); task = kthread_run(more_data_handling, data, "more_data_handling"); if (task == ERR_PTR(-ENOMEM)) { rv = -ENOMEM; kref_put(&data->refcount, data_release); goto out; } . . do stuff with data here . out: kref_put(&data->refcount, data_release); return rv; }”…”�”}”hj&sbah}”(h]”h ]”h"]”h$]”h&]”jjuh1jþh³hÊh´KShjih²hubhì)�”}”(hXlThis way, it doesn't matter what order the two threads handle the data, the kref_put() handles knowing when the data is not referenced any more and releasing it. The kref_get() does not require a lock, since we already have a valid pointer that we own a refcount for. The put needs no lock because nothing tries to get the data without already holding a pointer.”h]”hXnThis way, it doesn’t matter what order the two threads handle the data, the kref_put() handles knowing when the data is not referenced any more and releasing it. The kref_get() does not require a lock, since we already have a valid pointer that we own a refcount for. The put needs no lock because nothing tries to get the data without already holding a pointer.”…”�”}”(hj4h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hëh³hÊh´K|hjih²hubhì)�”}”(hŒ½In the above example, kref_put() will be called 2 times in both success and error paths. This is necessary because the reference count got incremented 2 times by kref_init() and kref_get().”h]”hŒ½In the above example, kref_put() will be called 2 times in both success and error paths. This is necessary because the reference count got incremented 2 times by kref_init() and kref_get().”…”�”}”(hjBh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hëh³hÊh´Kƒhjih²hubhì)�”}”(hŒYNote that the "before" in rule 1 is very important. You should never do something like::”h]”hŒ\Note that the “beforeâ€� in rule 1 is very important. You should never do something like:”…”�”}”(hjPh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hëh³hÊh´K‡hjih²hubjÿ)�”}”(hŒêtask = kthread_run(more_data_handling, data, "more_data_handling"); if (task == ERR_PTR(-ENOMEM)) { rv = -ENOMEM; goto out; } else /* BAD BAD BAD - get is after the handoff */ kref_get(&data->refcount);”h]”hŒêtask = kthread_run(more_data_handling, data, "more_data_handling"); if (task == ERR_PTR(-ENOMEM)) { rv = -ENOMEM; goto out; } else /* BAD BAD BAD - get is after the handoff */ kref_get(&data->refcount);”…”�”}”hj^sbah}”(h]”h ]”h"]”h$]”h&]”jjuh1jþh³hÊh´KŠhjih²hubhì)�”}”(hXoDon't assume you know what you are doing and use the above construct. First of all, you may not know what you are doing. Second, you may know what you are doing (there are some situations where locking is involved where the above may be legal) but someone else who doesn't know what they are doing may change the code or copy the code. It's bad style. Don't do it.”h]”hXwDon’t assume you know what you are doing and use the above construct. First of all, you may not know what you are doing. Second, you may know what you are doing (there are some situations where locking is involved where the above may be legal) but someone else who doesn’t know what they are doing may change the code or copy the code. It’s bad style. Don’t do it.”…”�”}”(hjlh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hëh³hÊh´K’hjih²hubhì)�”}”(hŒåThere are some situations where you can optimize the gets and puts. For instance, if you are done with an object and enqueuing it for something else or passing it off to something else, there is no reason to do a get then a put::”h]”hŒäThere are some situations where you can optimize the gets and puts. For instance, if you are done with an object and enqueuing it for something else or passing it off to something else, there is no reason to do a get then a put:”…”�”}”(hjzh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hëh³hÊh´K™hjih²hubjÿ)�”}”(hŒb/* Silly extra get and put */ kref_get(&obj->ref); enqueue(obj); kref_put(&obj->ref, obj_cleanup);”h]”hŒb/* Silly extra get and put */ kref_get(&obj->ref); enqueue(obj); kref_put(&obj->ref, obj_cleanup);”…”�”}”hjˆsbah}”(h]”h ]”h"]”h$]”h&]”jjuh1jþh³hÊh´Kžhjih²hubhì)�”}”(hŒ>Just do the enqueue. A comment about this is always welcome::”h]”hŒ=Just do the enqueue. A comment about this is always welcome:”…”�”}”(hj–h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hëh³hÊh´K£hjih²hubjÿ)�”}”(hŒsenqueue(obj); /* We are done with obj, so we pass our refcount off to the queue. DON'T TOUCH obj AFTER HERE! */”h]”hŒsenqueue(obj); /* We are done with obj, so we pass our refcount off to the queue. DON'T TOUCH obj AFTER HERE! */”…”�”}”hj¤sbah}”(h]”h ]”h"]”h$]”h&]”jjuh1jþh³hÊh´K¥hjih²hubhì)�”}”(hXfThe last rule (rule 3) is the nastiest one to handle. Say, for instance, you have a list of items that are each kref-ed, and you wish to get the first one. You can't just pull the first item off the list and kref_get() it. That violates rule 3 because you are not already holding a valid pointer. You must add a mutex (or some other lock). For instance::”h]”hXgThe last rule (rule 3) is the nastiest one to handle. Say, for instance, you have a list of items that are each kref-ed, and you wish to get the first one. You can’t just pull the first item off the list and kref_get() it. That violates rule 3 because you are not already holding a valid pointer. You must add a mutex (or some other lock). For instance:”…”�”}”(hj²h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hëh³hÊh´K©hjih²hubjÿ)�”}”(hXstatic DEFINE_MUTEX(mutex); static LIST_HEAD(q); struct my_data { struct kref refcount; struct list_head link; }; static struct my_data *get_entry() { struct my_data *entry = NULL; mutex_lock(&mutex); if (!list_empty(&q)) { entry = container_of(q.next, struct my_data, link); kref_get(&entry->refcount); } mutex_unlock(&mutex); return entry; } static void release_entry(struct kref *ref) { struct my_data *entry = container_of(ref, struct my_data, refcount); list_del(&entry->link); kfree(entry); } static void put_entry(struct my_data *entry) { mutex_lock(&mutex); kref_put(&entry->refcount, release_entry); mutex_unlock(&mutex); }”h]”hXstatic DEFINE_MUTEX(mutex); static LIST_HEAD(q); struct my_data { struct kref refcount; struct list_head link; }; static struct my_data *get_entry() { struct my_data *entry = NULL; mutex_lock(&mutex); if (!list_empty(&q)) { entry = container_of(q.next, struct my_data, link); kref_get(&entry->refcount); } mutex_unlock(&mutex); return entry; } static void release_entry(struct kref *ref) { struct my_data *entry = container_of(ref, struct my_data, refcount); list_del(&entry->link); kfree(entry); } static void put_entry(struct my_data *entry) { mutex_lock(&mutex); kref_put(&entry->refcount, release_entry); mutex_unlock(&mutex); }”…”�”}”hjÀsbah}”(h]”h ]”h"]”h$]”h&]”jjuh1jþh³hÊh´K°hjih²hubhì)�”}”(hX The kref_put() return value is useful if you do not want to hold the lock during the whole release operation. Say you didn't want to call kfree() with the lock held in the example above (since it is kind of pointless to do so). You could use kref_put() as follows::”h]”hX The kref_put() return value is useful if you do not want to hold the lock during the whole release operation. Say you didn’t want to call kfree() with the lock held in the example above (since it is kind of pointless to do so). You could use kref_put() as follows:”…”�”}”(hjÎh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hëh³hÊh´KÓhjih²hubjÿ)�”}”(hX˜static void release_entry(struct kref *ref) { /* All work is done after the return from kref_put(). */ } static void put_entry(struct my_data *entry) { mutex_lock(&mutex); if (kref_put(&entry->refcount, release_entry)) { list_del(&entry->link); mutex_unlock(&mutex); kfree(entry); } else mutex_unlock(&mutex); }”h]”hX˜static void release_entry(struct kref *ref) { /* All work is done after the return from kref_put(). */ } static void put_entry(struct my_data *entry) { mutex_lock(&mutex); if (kref_put(&entry->refcount, release_entry)) { list_del(&entry->link); mutex_unlock(&mutex); kfree(entry); } else mutex_unlock(&mutex); }”…”�”}”hjÜsbah}”(h]”h ]”h"]”h$]”h&]”jjuh1jþh³hÊh´KØhjih²hubhì)�”}”(hŒöThis is really more useful if you have to call other routines as part of the free operations that could take a long time or might claim the same lock. Note that doing everything in the release routine is still preferred as it is a little neater.”h]”hŒöThis is really more useful if you have to call other routines as part of the free operations that could take a long time or might claim the same lock. Note that doing everything in the release routine is still preferred as it is a little neater.”…”�”}”(hjêh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hëh³hÊh´Kèhjih²hubhì)�”}”(hŒ]The above example could also be optimized using kref_get_unless_zero() in the following way::”h]”hŒ\The above example could also be optimized using kref_get_unless_zero() in the following way:”…”�”}”(hjøh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hëh³hÊh´Kíhjih²hubjÿ)�”}”(hXÀstatic struct my_data *get_entry() { struct my_data *entry = NULL; mutex_lock(&mutex); if (!list_empty(&q)) { entry = container_of(q.next, struct my_data, link); if (!kref_get_unless_zero(&entry->refcount)) entry = NULL; } mutex_unlock(&mutex); return entry; } static void release_entry(struct kref *ref) { struct my_data *entry = container_of(ref, struct my_data, refcount); mutex_lock(&mutex); list_del(&entry->link); mutex_unlock(&mutex); kfree(entry); } static void put_entry(struct my_data *entry) { kref_put(&entry->refcount, release_entry); }”h]”hXÀstatic struct my_data *get_entry() { struct my_data *entry = NULL; mutex_lock(&mutex); if (!list_empty(&q)) { entry = container_of(q.next, struct my_data, link); if (!kref_get_unless_zero(&entry->refcount)) entry = NULL; } mutex_unlock(&mutex); return entry; } static void release_entry(struct kref *ref) { struct my_data *entry = container_of(ref, struct my_data, refcount); mutex_lock(&mutex); list_del(&entry->link); mutex_unlock(&mutex); kfree(entry); } static void put_entry(struct my_data *entry) { kref_put(&entry->refcount, release_entry); }”…”�”}”hjsbah}”(h]”h ]”h"]”h$]”h&]”jjuh1jþh³hÊh´Kðhjih²hubhì)�”}”(hXãWhich is useful to remove the mutex lock around kref_put() in put_entry(), but it's important that kref_get_unless_zero is enclosed in the same critical section that finds the entry in the lookup table, otherwise kref_get_unless_zero may reference already freed memory. Note that it is illegal to use kref_get_unless_zero without checking its return value. If you are sure (by already having a valid pointer) that kref_get_unless_zero() will return true, then use kref_get() instead.”h]”hXåWhich is useful to remove the mutex lock around kref_put() in put_entry(), but it’s important that kref_get_unless_zero is enclosed in the same critical section that finds the entry in the lookup table, otherwise kref_get_unless_zero may reference already freed memory. Note that it is illegal to use kref_get_unless_zero without checking its return value. If you are sure (by already having a valid pointer) that kref_get_unless_zero() will return true, then use kref_get() instead.”…”�”}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hëh³hÊh´M hjih²hubeh}”(h]”Œ kref-rules”ah ]”h"]”Œ kref rules”ah$]”h&]”uh1hµhh·h²hh³hÊh´K3ubh¶)�”}”(hhh]”(h»)�”}”(hŒ Krefs and RCU”h]”hŒ Krefs and RCU”…”�”}”(hj-h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hºhj*h²hh³hÊh´Mubhì)�”}”(hŒnThe function kref_get_unless_zero also makes it possible to use rcu locking for lookups in the above example::”h]”hŒmThe function kref_get_unless_zero also makes it possible to use rcu locking for lookups in the above example:”…”�”}”(hj;h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hëh³hÊh´Mhj*h²hubjÿ)�”}”(hXEstruct my_data { struct rcu_head rhead; . struct kref refcount; . . }; static struct my_data *get_entry_rcu() { struct my_data *entry = NULL; rcu_read_lock(); if (!list_empty(&q)) { entry = container_of(q.next, struct my_data, link); if (!kref_get_unless_zero(&entry->refcount)) entry = NULL; } rcu_read_unlock(); return entry; } static void release_entry_rcu(struct kref *ref) { struct my_data *entry = container_of(ref, struct my_data, refcount); mutex_lock(&mutex); list_del_rcu(&entry->link); mutex_unlock(&mutex); kfree_rcu(entry, rhead); } static void put_entry(struct my_data *entry) { kref_put(&entry->refcount, release_entry_rcu); }”h]”hXEstruct my_data { struct rcu_head rhead; . struct kref refcount; . . }; static struct my_data *get_entry_rcu() { struct my_data *entry = NULL; rcu_read_lock(); if (!list_empty(&q)) { entry = container_of(q.next, struct my_data, link); if (!kref_get_unless_zero(&entry->refcount)) entry = NULL; } rcu_read_unlock(); return entry; } static void release_entry_rcu(struct kref *ref) { struct my_data *entry = container_of(ref, struct my_data, refcount); mutex_lock(&mutex); list_del_rcu(&entry->link); mutex_unlock(&mutex); kfree_rcu(entry, rhead); } static void put_entry(struct my_data *entry) { kref_put(&entry->refcount, release_entry_rcu); }”…”�”}”hjIsbah}”(h]”h ]”h"]”h$]”h&]”jjuh1jþh³hÊh´Mhj*h²hubhì)�”}”(hXHBut note that the struct kref member needs to remain in valid memory for a rcu grace period after release_entry_rcu was called. That can be accomplished by using kfree_rcu(entry, rhead) as done above, or by calling synchronize_rcu() before using kfree, but note that synchronize_rcu() may sleep for a substantial amount of time.”h]”hXHBut note that the struct kref member needs to remain in valid memory for a rcu grace period after release_entry_rcu was called. That can be accomplished by using kfree_rcu(entry, rhead) as done above, or by calling synchronize_rcu() before using kfree, but note that synchronize_rcu() may sleep for a substantial amount of time.”…”�”}”(hjWh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hëh³hÊh´M?hj*h²hubeh}”(h]”Œ krefs-and-rcu”ah ]”h"]”Œ krefs and rcu”ah$]”h&]”uh1hµhh·h²hh³hÊh´Mubh¶)�”}”(hhh]”(h»)�”}”(hŒFunctions and structures”h]”hŒFunctions and structures”…”�”}”(hjph²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hºhjmh²hh³hÊh´MFubhŒindex”“”)�”}”(hhh]”h}”(h]”h ]”h"]”h$]”h&]”Œentries”]”(Œsingle”Œkref_init (C function)”Œ c.kref_init”hNt”auh1j~hjmh²hh³Nh´NubhŒdesc”“”)�”}”(hhh]”(hŒdesc_signature”“”)�”}”(hŒ"void kref_init (struct kref *kref)”h]”hŒdesc_signature_line”“”)�”}”(hŒ!void kref_init(struct kref *kref)”h]”(hŒdesc_sig_keyword_type”“”)�”}”(hŒvoid”h]”hŒvoid”…”�”}”(hj¢h²hh³Nh´Nubah}”(h]”h ]”Œkt”ah"]”h$]”h&]”uh1j hjœh²hh³ŒS/var/lib/git/docbuild/linux/Documentation/core-api/kref:328: ./include/linux/kref.h”h´KubhŒdesc_sig_space”“”)�”}”(hŒ ”h]”hŒ ”…”�”}”(hj´h²hh³Nh´Nubah}”(h]”h ]”Œw”ah"]”h$]”h&]”uh1j²hjœh²hh³j±h´KubhŒ desc_name”“”)�”}”(hŒ kref_init”h]”hŒ desc_sig_name”“”)�”}”(hŒ kref_init”h]”hŒ kref_init”…”�”}”(hjËh²hh³Nh´Nubah}”(h]”h ]”Œn”ah"]”h$]”h&]”uh1jÉhjÅubah}”(h]”h ]”(Œsig-name”Œdescname”eh"]”h$]”h&]”jjuh1jÃhjœh²hh³j±h´KubhŒdesc_parameterlist”“”)�”}”(hŒ(struct kref *kref)”h]”hŒdesc_parameter”“”)�”}”(hŒstruct kref *kref”h]”(hŒdesc_sig_keyword”“”)�”}”(hŒstruct”h]”hŒstruct”…”�”}”(hjðh²hh³Nh´Nubah}”(h]”h ]”Œk”ah"]”h$]”h&]”uh1jîhjêubj³)�”}”(hŒ ”h]”hŒ ”…”�”}”(hjÿh²hh³Nh´Nubah}”(h]”h ]”j¿ah"]”h$]”h&]”uh1j²hjêubh)�”}”(hhh]”jÊ)�”}”(hŒkref”h]”hŒkref”…”�”}”(hjh²hh³Nh´Nubah}”(h]”h ]”jÖah"]”h$]”h&]”uh1jÉhj ubah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”Œc”Œreftype”Œ identifier”Œ reftarget”jŒmodname”NŒ classname”NŒ c:parent_key”Œsphinx.domains.c”Œ LookupKey”“”)�”}”Œdata”]”j,Œ ASTIdentifier”“”)�”}”j'jÍsbŒ c.kref_init”†”asbuh1hhjêubj³)�”}”(hŒ ”h]”hŒ ”…”�”}”(hj9h²hh³Nh´Nubah}”(h]”h ]”j¿ah"]”h$]”h&]”uh1j²hjêubhŒdesc_sig_punctuation”“”)�”}”(hŒ*”h]”hŒ*”…”�”}”(hjIh²hh³Nh´Nubah}”(h]”h ]”Œp”ah"]”h$]”h&]”uh1jGhjêubjÊ)�”}”(hŒkref”h]”hŒkref”…”�”}”(hjXh²hh³Nh´Nubah}”(h]”h ]”jÖah"]”h$]”h&]”uh1jÉhjêubeh}”(h]”h ]”h"]”h$]”h&]”Œnoemph”ˆjjuh1jèhjäubah}”(h]”h ]”h"]”h$]”h&]”jjuh1jâhjœh²hh³j±h´Kubeh}”(h]”h ]”h"]”h$]”h&]”jjŒ add_permalink”ˆuh1jšŒsphinx_line_type”Œ declarator”hj–h²hh³j±h´Kubah}”(h]”j�ah ]”(Œsig”Œ sig-object”eh"]”h$]”h&]”Œ is_multiline”ˆŒ _toc_parts”)Œ _toc_name”huh1j”h³j±h´Khj‘h²hubhŒ desc_content”“”)�”}”(hhh]”hì)�”}”(hŒinitialize object.”h]”hŒinitialize object.”…”�”}”(hjŒh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hëh³ŒS/var/lib/git/docbuild/linux/Documentation/core-api/kref:328: ./include/linux/kref.h”h´Khj‰h²hubah}”(h]”h ]”h"]”h$]”h&]”uh1j‡hj‘h²hh³j±h´Kubeh}”(h]”h ]”(j%Œfunction”eh"]”h$]”h&]”Œdomain”j%Œobjtype”j¤Œdesctype”j¤Œnoindex”‰Œ noindexentry”‰Œnocontentsentry”‰uh1j�h²hhjmh³Nh´NubhŒ container”“”)�”}”(hŒ;**Parameters** ``struct kref *kref`` object in question.”h]”(hì)�”}”(hŒ**Parameters**”h]”hŒstrong”“”)�”}”(hj¶h]”hŒ Parameters”…”�”}”(hjºh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j¸hj´ubah}”(h]”h ]”h"]”h$]”h&]”uh1hëh³ŒS/var/lib/git/docbuild/linux/Documentation/core-api/kref:328: ./include/linux/kref.h”h´Khj°ubhŒdefinition_list”“”)�”}”(hhh]”hŒdefinition_list_item”“”)�”}”(hŒ)``struct kref *kref`` object in question.”h]”(hŒterm”“”)�”}”(hŒ``struct kref *kref``”h]”hŒliteral”“”)�”}”(hjÝh]”hŒstruct kref *kref”…”�”}”(hjáh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jßhjÛubah}”(h]”h ]”h"]”h$]”h&]”uh1jÙh³ŒS/var/lib/git/docbuild/linux/Documentation/core-api/kref:328: ./include/linux/kref.h”h´K hjÕubhŒ definition”“”)�”}”(hhh]”hì)�”}”(hŒobject in question.”h]”hŒobject in question.”…”�”}”(hjúh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hëh³ŒS/var/lib/git/docbuild/linux/Documentation/core-api/kref:328: ./include/linux/kref.h”h´Khj÷ubah}”(h]”h ]”h"]”h$]”h&]”uh1jõhjÕubeh}”(h]”h ]”h"]”h$]”h&]”uh1jÓh³jôh´K hjÐubah}”(h]”h ]”h"]”h$]”h&]”uh1jÎhj°ubeh}”(h]”h ]”Œ kernelindent”ah"]”h$]”h&]”uh1j®hjmh²hh³Nh´Nubj)�”}”(hhh]”h}”(h]”h ]”h"]”h$]”h&]”Œentries”]”(j‹Œkref_get (C function)”Œ c.kref_get”hNt”auh1j~hjmh²hh³Nh´Nubj�)�”}”(hhh]”(j•)�”}”(hŒ!void kref_get (struct kref *kref)”h]”j›)�”}”(hŒ void kref_get(struct kref *kref)”h]”(j¡)�”}”(hŒvoid”h]”hŒvoid”…”�”}”(hj;h²hh³Nh´Nubah}”(h]”h ]”j­ah"]”h$]”h&]”uh1j hj7h²hh³ŒS/var/lib/git/docbuild/linux/Documentation/core-api/kref:328: ./include/linux/kref.h”h´K(ubj³)�”}”(hŒ ”h]”hŒ ”…”�”}”(hjJh²hh³Nh´Nubah}”(h]”h ]”j¿ah"]”h$]”h&]”uh1j²hj7h²hh³jIh´K(ubjÄ)�”}”(hŒkref_get”h]”jÊ)�”}”(hŒkref_get”h]”hŒkref_get”…”�”}”(hj\h²hh³Nh´Nubah}”(h]”h ]”jÖah"]”h$]”h&]”uh1jÉhjXubah}”(h]”h ]”(jÝjÞeh"]”h$]”h&]”jjuh1jÃhj7h²hh³jIh´K(ubjã)�”}”(hŒ(struct kref *kref)”h]”jé)�”}”(hŒstruct kref *kref”h]”(jï)�”}”(hjòh]”hŒstruct”…”�”}”(hjxh²hh³Nh´Nubah}”(h]”h ]”jûah"]”h$]”h&]”uh1jîhjtubj³)�”}”(hŒ ”h]”hŒ ”…”�”}”(hj…h²hh³Nh´Nubah}”(h]”h ]”j¿ah"]”h$]”h&]”uh1j²hjtubh)�”}”(hhh]”jÊ)�”}”(hŒkref”h]”hŒkref”…”�”}”(hj–h²hh³Nh´Nubah}”(h]”h ]”jÖah"]”h$]”h&]”uh1jÉhj“ubah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”j%Œreftype”j'Œ reftarget”j˜Œmodname”NŒ classname”Nj+j.)�”}”j1]”j4)�”}”j'j^sbŒ c.kref_get”†”asbuh1hhjtubj³)�”}”(hŒ ”h]”hŒ ”…”�”}”(hj¶h²hh³Nh´Nubah}”(h]”h ]”j¿ah"]”h$]”h&]”uh1j²hjtubjH)�”}”(hjKh]”hŒ*”…”�”}”(hjÄh²hh³Nh´Nubah}”(h]”h ]”jTah"]”h$]”h&]”uh1jGhjtubjÊ)�”}”(hŒkref”h]”hŒkref”…”�”}”(hjÑh²hh³Nh´Nubah}”(h]”h ]”jÖah"]”h$]”h&]”uh1jÉhjtubeh}”(h]”h ]”h"]”h$]”h&]”Œnoemph”ˆjjuh1jèhjpubah}”(h]”h ]”h"]”h$]”h&]”jjuh1jâhj7h²hh³jIh´K(ubeh}”(h]”h ]”h"]”h$]”h&]”jjjyˆuh1jšjzj{hj3h²hh³jIh´K(ubah}”(h]”j.ah ]”(jj€eh"]”h$]”h&]”j„ˆj…)j†huh1j”h³jIh´K(hj0h²hubjˆ)�”}”(hhh]”hì)�”}”(hŒincrement refcount for object.”h]”hŒincrement refcount for object.”…”�”}”(hjûh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hëh³ŒS/var/lib/git/docbuild/linux/Documentation/core-api/kref:328: ./include/linux/kref.h”h´K(hjøh²hubah}”(h]”h ]”h"]”h$]”h&]”uh1j‡hj0h²hh³jIh´K(ubeh}”(h]”h ]”(j%Œfunction”eh"]”h$]”h&]”j¨j%j©jjªjj«‰j¬‰j­‰uh1j�h²hhjmh³Nh´Nubj¯)�”}”(hŒ/**Parameters** ``struct kref *kref`` object.”h]”(hì)�”}”(hŒ**Parameters**”h]”j¹)�”}”(hjh]”hŒ Parameters”…”�”}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j¸hjubah}”(h]”h ]”h"]”h$]”h&]”uh1hëh³ŒS/var/lib/git/docbuild/linux/Documentation/core-api/kref:328: ./include/linux/kref.h”h´K,hjubjÏ)�”}”(hhh]”jÔ)�”}”(hŒ``struct kref *kref`` object.”h]”(jÚ)�”}”(hŒ``struct kref *kref``”h]”jà)�”}”(hj<h]”hŒstruct kref *kref”…”�”}”(hj>h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jßhj:ubah}”(h]”h ]”h"]”h$]”h&]”uh1jÙh³ŒS/var/lib/git/docbuild/linux/Documentation/core-api/kref:328: ./include/linux/kref.h”h´K.hj6ubjö)�”}”(hhh]”hì)�”}”(hŒobject.”h]”hŒobject.”…”�”}”(hjUh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hëh³ŒS/var/lib/git/docbuild/linux/Documentation/core-api/kref:328: ./include/linux/kref.h”h´K)hjRubah}”(h]”h ]”h"]”h$]”h&]”uh1jõhj6ubeh}”(h]”h ]”h"]”h$]”h&]”uh1jÓh³jQh´K.hj3ubah}”(h]”h ]”h"]”h$]”h&]”uh1jÎhjubeh}”(h]”h ]”Œ kernelindent”ah"]”h$]”h&]”uh1j®hjmh²hh³Nh´Nubj)�”}”(hhh]”h}”(h]”h ]”h"]”h$]”h&]”Œentries”]”(j‹Œkref_put (C function)”Œ c.kref_put”hNt”auh1j~hjmh²hh³Nh´Nubj�)�”}”(hhh]”(j•)�”}”(hŒDint kref_put (struct kref *kref, void (*release)(struct kref *kref))”h]”j›)�”}”(hŒCint kref_put(struct kref *kref, void (*release)(struct kref *kref))”h]”(j¡)�”}”(hŒint”h]”hŒint”…”�”}”(hj–h²hh³Nh´Nubah}”(h]”h ]”j­ah"]”h$]”h&]”uh1j hj’h²hh³ŒS/var/lib/git/docbuild/linux/Documentation/core-api/kref:328: ./include/linux/kref.h”h´K1ubj³)�”}”(hŒ ”h]”hŒ ”…”�”}”(hj¥h²hh³Nh´Nubah}”(h]”h ]”j¿ah"]”h$]”h&]”uh1j²hj’h²hh³j¤h´K1ubjÄ)�”}”(hŒkref_put”h]”jÊ)�”}”(hŒkref_put”h]”hŒkref_put”…”�”}”(hj·h²hh³Nh´Nubah}”(h]”h ]”jÖah"]”h$]”h&]”uh1jÉhj³ubah}”(h]”h ]”(jÝjÞeh"]”h$]”h&]”jjuh1jÃhj’h²hh³j¤h´K1ubjã)�”}”(hŒ7(struct kref *kref, void (*release)(struct kref *kref))”h]”(jé)�”}”(hŒstruct kref *kref”h]”(jï)�”}”(hjòh]”hŒstruct”…”�”}”(hjÓh²hh³Nh´Nubah}”(h]”h ]”jûah"]”h$]”h&]”uh1jîhjÏubj³)�”}”(hŒ ”h]”hŒ ”…”�”}”(hjàh²hh³Nh´Nubah}”(h]”h ]”j¿ah"]”h$]”h&]”uh1j²hjÏubh)�”}”(hhh]”jÊ)�”}”(hŒkref”h]”hŒkref”…”�”}”(hjñh²hh³Nh´Nubah}”(h]”h ]”jÖah"]”h$]”h&]”uh1jÉhjîubah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”j%Œreftype”j'Œ reftarget”jóŒmodname”NŒ classname”Nj+j.)�”}”j1]”j4)�”}”j'j¹sbŒ c.kref_put”†”asbuh1hhjÏubj³)�”}”(hŒ ”h]”hŒ ”…”�”}”(hjh²hh³Nh´Nubah}”(h]”h ]”j¿ah"]”h$]”h&]”uh1j²hjÏubjH)�”}”(hjKh]”hŒ*”…”�”}”(hjh²hh³Nh´Nubah}”(h]”h ]”jTah"]”h$]”h&]”uh1jGhjÏubjÊ)�”}”(hŒkref”h]”hŒkref”…”�”}”(hj,h²hh³Nh´Nubah}”(h]”h ]”jÖah"]”h$]”h&]”uh1jÉhjÏubeh}”(h]”h ]”h"]”h$]”h&]”Œnoemph”ˆjjuh1jèhjËubjé)�”}”(hŒ"void (*release)(struct kref *kref)”h]”(j¡)�”}”(hŒvoid”h]”hŒvoid”…”�”}”(hjEh²hh³Nh´Nubah}”(h]”h ]”j­ah"]”h$]”h&]”uh1j hjAubj³)�”}”(hŒ ”h]”hŒ ”…”�”}”(hjSh²hh³Nh´Nubah}”(h]”h ]”j¿ah"]”h$]”h&]”uh1j²hjAubjH)�”}”(hŒ(”h]”hŒ(”…”�”}”(hjah²hh³Nh´Nubah}”(h]”h ]”jTah"]”h$]”h&]”uh1jGhjAubjH)�”}”(hjKh]”hŒ*”…”�”}”(hjoh²hh³Nh´Nubah}”(h]”h ]”jTah"]”h$]”h&]”uh1jGhjAubjÊ)�”}”(hŒrelease”h]”hŒrelease”…”�”}”(hj|h²hh³Nh´Nubah}”(h]”h ]”jÖah"]”h$]”h&]”uh1jÉhjAubjH)�”}”(hjh]”hŒ)”…”�”}”(hjŠh²hh³Nh´Nubah}”(h]”h ]”jTah"]”h$]”h&]”uh1jGhjAubjH)�”}”(hjch]”hŒ(”…”�”}”(hj—h²hh³Nh´Nubah}”(h]”h ]”jTah"]”h$]”h&]”uh1jGhjAubjï)�”}”(hjòh]”hŒstruct”…”�”}”(hj¤h²hh³Nh´Nubah}”(h]”h ]”jûah"]”h$]”h&]”uh1jîhjAubj³)�”}”(hŒ ”h]”hŒ ”…”�”}”(hj±h²hh³Nh´Nubah}”(h]”h ]”j¿ah"]”h$]”h&]”uh1j²hjAubh)�”}”(hhh]”jÊ)�”}”(hŒkref”h]”hŒkref”…”�”}”(hjÂh²hh³Nh´Nubah}”(h]”h ]”jÖah"]”h$]”h&]”uh1jÉhj¿ubah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”j%Œreftype”j'Œ reftarget”jÄŒmodname”NŒ classname”Nj+j.)�”}”j1]”j Œ c.kref_put”†”asbuh1hhjAubj³)�”}”(hŒ ”h]”hŒ ”…”�”}”(hjàh²hh³Nh´Nubah}”(h]”h ]”j¿ah"]”h$]”h&]”uh1j²hjAubjH)�”}”(hjKh]”hŒ*”…”�”}”(hjîh²hh³Nh´Nubah}”(h]”h ]”jTah"]”h$]”h&]”uh1jGhjAubjÊ)�”}”(hŒkref”h]”hŒkref”…”�”}”(hjûh²hh³Nh´Nubah}”(h]”h ]”jÖah"]”h$]”h&]”uh1jÉhjAubjH)�”}”(hjh]”hŒ)”…”�”}”(hj h²hh³Nh´Nubah}”(h]”h ]”jTah"]”h$]”h&]”uh1jGhjAubeh}”(h]”h ]”h"]”h$]”h&]”Œnoemph”ˆjjuh1jèhjËubeh}”(h]”h ]”h"]”h$]”h&]”jjuh1jâhj’h²hh³j¤h´K1ubeh}”(h]”h ]”h"]”h$]”h&]”jjjyˆuh1jšjzj{hjŽh²hh³j¤h´K1ubah}”(h]”j‰ah ]”(jj€eh"]”h$]”h&]”j„ˆj…)j†huh1j”h³j¤h´K1hj‹h²hubjˆ)�”}”(hhh]”hì)�”}”(hŒDecrement refcount for object”h]”hŒDecrement refcount for object”…”�”}”(hj2 h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hëh³ŒS/var/lib/git/docbuild/linux/Documentation/core-api/kref:328: ./include/linux/kref.h”h´K1hj/ h²hubah}”(h]”h ]”h"]”h$]”h&]”uh1j‡hj‹h²hh³j¤h´K1ubeh}”(h]”h ]”(j%Œfunction”eh"]”h$]”h&]”j¨j%j©jJ jªjJ j«‰j¬‰j­‰uh1j�h²hhjmh³Nh´Nubj¯)�”}”(hX]**Parameters** ``struct kref *kref`` Object ``void (*release)(struct kref *kref)`` Pointer to the function that will clean up the object when the last reference to the object is released. **Description** Decrement the refcount, and if 0, call **release**. The caller may not pass NULL or kfree() as the release function. **Return** 1 if this call removed the object, otherwise return 0. Beware, if this function returns 0, another caller may have removed the object by the time this function returns. The return value is only certain if you want to see if the object is definitely released.”h]”(hì)�”}”(hŒ**Parameters**”h]”j¹)�”}”(hjT h]”hŒ Parameters”…”�”}”(hjV h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j¸hjR ubah}”(h]”h ]”h"]”h$]”h&]”uh1hëh³ŒS/var/lib/git/docbuild/linux/Documentation/core-api/kref:328: ./include/linux/kref.h”h´K5hjN ubjÏ)�”}”(hhh]”(jÔ)�”}”(hŒ``struct kref *kref`` Object ”h]”(jÚ)�”}”(hŒ``struct kref *kref``”h]”jà)�”}”(hjs h]”hŒstruct kref *kref”…”�”}”(hju h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jßhjq ubah}”(h]”h ]”h"]”h$]”h&]”uh1jÙh³ŒS/var/lib/git/docbuild/linux/Documentation/core-api/kref:328: ./include/linux/kref.h”h´K2hjm ubjö)�”}”(hhh]”hì)�”}”(hŒObject”h]”hŒObject”…”�”}”(hjŒ h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hëh³jˆ h´K2hj‰ ubah}”(h]”h ]”h"]”h$]”h&]”uh1jõhjm ubeh}”(h]”h ]”h"]”h$]”h&]”uh1jÓh³jˆ h´K2hjj ubjÔ)�”}”(hŒ�``void (*release)(struct kref *kref)`` Pointer to the function that will clean up the object when the last reference to the object is released. ”h]”(jÚ)�”}”(hŒ&``void (*release)(struct kref *kref)``”h]”jà)�”}”(hj¬ h]”hŒ"void (*release)(struct kref *kref)”…”�”}”(hj® h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jßhjª ubah}”(h]”h ]”h"]”h$]”h&]”uh1jÙh³ŒS/var/lib/git/docbuild/linux/Documentation/core-api/kref:328: ./include/linux/kref.h”h´K4hj¦ ubjö)�”}”(hhh]”hì)�”}”(hŒhPointer to the function that will clean up the object when the last reference to the object is released.”h]”hŒhPointer to the function that will clean up the object when the last reference to the object is released.”…”�”}”(hjÅ h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hëh³ŒS/var/lib/git/docbuild/linux/Documentation/core-api/kref:328: ./include/linux/kref.h”h´K3hj ubah}”(h]”h ]”h"]”h$]”h&]”uh1jõhj¦ ubeh}”(h]”h ]”h"]”h$]”h&]”uh1jÓh³jÁ h´K4hjj ubeh}”(h]”h ]”h"]”h$]”h&]”uh1jÎhjN ubhì)�”}”(hŒ**Description**”h]”j¹)�”}”(hjè h]”hŒ Description”…”�”}”(hjê h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j¸hjæ ubah}”(h]”h ]”h"]”h$]”h&]”uh1hëh³ŒS/var/lib/git/docbuild/linux/Documentation/core-api/kref:328: ./include/linux/kref.h”h´K6hjN ubhì)�”}”(hŒuDecrement the refcount, and if 0, call **release**. The caller may not pass NULL or kfree() as the release function.”h]”(hŒ'Decrement the refcount, and if 0, call ”…”�”}”(hjþ h²hh³Nh´Nubj¹)�”}”(hŒ **release**”h]”hŒrelease”…”�”}”(hj h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j¸hjþ ubhŒC. The caller may not pass NULL or kfree() as the release function.”…”�”}”(hjþ h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hëh³ŒS/var/lib/git/docbuild/linux/Documentation/core-api/kref:328: ./include/linux/kref.h”h´K5hjN ubhì)�”}”(hŒ **Return**”h]”j¹)�”}”(hj! h]”hŒReturn”…”�”}”(hj# h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j¸hj ubah}”(h]”h ]”h"]”h$]”h&]”uh1hëh³ŒS/var/lib/git/docbuild/linux/Documentation/core-api/kref:328: ./include/linux/kref.h”h´K8hjN ubhì)�”}”(hX1 if this call removed the object, otherwise return 0. Beware, if this function returns 0, another caller may have removed the object by the time this function returns. The return value is only certain if you want to see if the object is definitely released.”h]”hX1 if this call removed the object, otherwise return 0. Beware, if this function returns 0, another caller may have removed the object by the time this function returns. The return value is only certain if you want to see if the object is definitely released.”…”�”}”(hj7 h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hëh³ŒS/var/lib/git/docbuild/linux/Documentation/core-api/kref:328: ./include/linux/kref.h”h´K9hjN ubeh}”(h]”h ]”Œ kernelindent”ah"]”h$]”h&]”uh1j®hjmh²hh³Nh´Nubj)�”}”(hhh]”h}”(h]”h ]”h"]”h$]”h&]”Œentries”]”(j‹Œkref_put_mutex (C function)”Œc.kref_put_mutex”hNt”auh1j~hjmh²hh³Nh´Nubj�)�”}”(hhh]”(j•)�”}”(hŒ_int kref_put_mutex (struct kref *kref, void (*release)(struct kref *kref), struct mutex *mutex)”h]”j›)�”}”(hŒ^int kref_put_mutex(struct kref *kref, void (*release)(struct kref *kref), struct mutex *mutex)”h]”(j¡)�”}”(hŒint”h]”hŒint”…”�”}”(hjf h²hh³Nh´Nubah}”(h]”h ]”j­ah"]”h$]”h&]”uh1j hjb h²hh³ŒS/var/lib/git/docbuild/linux/Documentation/core-api/kref:328: ./include/linux/kref.h”h´KHubj³)�”}”(hŒ ”h]”hŒ ”…”�”}”(hju h²hh³Nh´Nubah}”(h]”h ]”j¿ah"]”h$]”h&]”uh1j²hjb h²hh³jt h´KHubjÄ)�”}”(hŒkref_put_mutex”h]”jÊ)�”}”(hŒkref_put_mutex”h]”hŒkref_put_mutex”…”�”}”(hj‡ h²hh³Nh´Nubah}”(h]”h ]”jÖah"]”h$]”h&]”uh1jÉhjƒ ubah}”(h]”h ]”(jÝjÞeh"]”h$]”h&]”jjuh1jÃhjb h²hh³jt h´KHubjã)�”}”(hŒL(struct kref *kref, void (*release)(struct kref *kref), struct mutex *mutex)”h]”(jé)�”}”(hŒstruct kref *kref”h]”(jï)�”}”(hjòh]”hŒstruct”…”�”}”(hj£ h²hh³Nh´Nubah}”(h]”h ]”jûah"]”h$]”h&]”uh1jîhjŸ ubj³)�”}”(hŒ ”h]”hŒ ”…”�”}”(hj° h²hh³Nh´Nubah}”(h]”h ]”j¿ah"]”h$]”h&]”uh1j²hjŸ ubh)�”}”(hhh]”jÊ)�”}”(hŒkref”h]”hŒkref”…”�”}”(hjÁ h²hh³Nh´Nubah}”(h]”h ]”jÖah"]”h$]”h&]”uh1jÉhj¾ ubah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”j%Œreftype”j'Œ reftarget”jà Œmodname”NŒ classname”Nj+j.)�”}”j1]”j4)�”}”j'j‰ sbŒc.kref_put_mutex”†”asbuh1hhjŸ ubj³)�”}”(hŒ ”h]”hŒ ”…”�”}”(hjá h²hh³Nh´Nubah}”(h]”h ]”j¿ah"]”h$]”h&]”uh1j²hjŸ ubjH)�”}”(hjKh]”hŒ*”…”�”}”(hjï h²hh³Nh´Nubah}”(h]”h ]”jTah"]”h$]”h&]”uh1jGhjŸ ubjÊ)�”}”(hŒkref”h]”hŒkref”…”�”}”(hjü h²hh³Nh´Nubah}”(h]”h ]”jÖah"]”h$]”h&]”uh1jÉhjŸ ubeh}”(h]”h ]”h"]”h$]”h&]”Œnoemph”ˆjjuh1jèhj› ubjé)�”}”(hŒ"void (*release)(struct kref *kref)”h]”(j¡)�”}”(hŒvoid”h]”hŒvoid”…”�”}”(hj h²hh³Nh´Nubah}”(h]”h ]”j­ah"]”h$]”h&]”uh1j hj ubj³)�”}”(hŒ ”h]”hŒ ”…”�”}”(hj# h²hh³Nh´Nubah}”(h]”h ]”j¿ah"]”h$]”h&]”uh1j²hj ubjH)�”}”(hjch]”hŒ(”…”�”}”(hj1 h²hh³Nh´Nubah}”(h]”h ]”jTah"]”h$]”h&]”uh1jGhj ubjH)�”}”(hjKh]”hŒ*”…”�”}”(hj> h²hh³Nh´Nubah}”(h]”h ]”jTah"]”h$]”h&]”uh1jGhj ubjÊ)�”}”(hŒrelease”h]”hŒrelease”…”�”}”(hjK h²hh³Nh´Nubah}”(h]”h ]”jÖah"]”h$]”h&]”uh1jÉhj ubjH)�”}”(hjh]”hŒ)”…”�”}”(hjY h²hh³Nh´Nubah}”(h]”h ]”jTah"]”h$]”h&]”uh1jGhj ubjH)�”}”(hjch]”hŒ(”…”�”}”(hjf h²hh³Nh´Nubah}”(h]”h ]”jTah"]”h$]”h&]”uh1jGhj ubjï)�”}”(hjòh]”hŒstruct”…”�”}”(hjs h²hh³Nh´Nubah}”(h]”h ]”jûah"]”h$]”h&]”uh1jîhj ubj³)�”}”(hŒ ”h]”hŒ ”…”�”}”(hj€ h²hh³Nh´Nubah}”(h]”h ]”j¿ah"]”h$]”h&]”uh1j²hj ubh)�”}”(hhh]”jÊ)�”}”(hŒkref”h]”hŒkref”…”�”}”(hj‘ h²hh³Nh´Nubah}”(h]”h ]”jÖah"]”h$]”h&]”uh1jÉhjŽ ubah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”j%Œreftype”j'Œ reftarget”j“ Œmodname”NŒ classname”Nj+j.)�”}”j1]”jÝ Œc.kref_put_mutex”†”asbuh1hhj ubj³)�”}”(hŒ ”h]”hŒ ”…”�”}”(hj¯ h²hh³Nh´Nubah}”(h]”h ]”j¿ah"]”h$]”h&]”uh1j²hj ubjH)�”}”(hjKh]”hŒ*”…”�”}”(hj½ h²hh³Nh´Nubah}”(h]”h ]”jTah"]”h$]”h&]”uh1jGhj ubjÊ)�”}”(hŒkref”h]”hŒkref”…”�”}”(hjÊ h²hh³Nh´Nubah}”(h]”h ]”jÖah"]”h$]”h&]”uh1jÉhj ubjH)�”}”(hjh]”hŒ)”…”�”}”(hjØ h²hh³Nh´Nubah}”(h]”h ]”jTah"]”h$]”h&]”uh1jGhj ubeh}”(h]”h ]”h"]”h$]”h&]”Œnoemph”ˆjjuh1jèhj› ubjé)�”}”(hŒstruct mutex *mutex”h]”(jï)�”}”(hjòh]”hŒstruct”…”�”}”(hjð h²hh³Nh´Nubah}”(h]”h ]”jûah"]”h$]”h&]”uh1jîhjì ubj³)�”}”(hŒ ”h]”hŒ ”…”�”}”(hjý h²hh³Nh´Nubah}”(h]”h ]”j¿ah"]”h$]”h&]”uh1j²hjì ubh)�”}”(hhh]”jÊ)�”}”(hŒmutex”h]”hŒmutex”…”�”}”(hj h²hh³Nh´Nubah}”(h]”h ]”jÖah"]”h$]”h&]”uh1jÉhj ubah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”j%Œreftype”j'Œ reftarget”j Œmodname”NŒ classname”Nj+j.)�”}”j1]”jÝ Œc.kref_put_mutex”†”asbuh1hhjì ubj³)�”}”(hŒ ”h]”hŒ ”…”�”}”(hj, h²hh³Nh´Nubah}”(h]”h ]”j¿ah"]”h$]”h&]”uh1j²hjì ubjH)�”}”(hjKh]”hŒ*”…”�”}”(hj: h²hh³Nh´Nubah}”(h]”h ]”jTah"]”h$]”h&]”uh1jGhjì ubjÊ)�”}”(hŒmutex”h]”hŒmutex”…”�”}”(hjG h²hh³Nh´Nubah}”(h]”h ]”jÖah"]”h$]”h&]”uh1jÉhjì ubeh}”(h]”h ]”h"]”h$]”h&]”Œnoemph”ˆjjuh1jèhj› ubeh}”(h]”h ]”h"]”h$]”h&]”jjuh1jâhjb h²hh³jt h´KHubeh}”(h]”h ]”h"]”h$]”h&]”jjjyˆuh1jšjzj{hj^ h²hh³jt h´KHubah}”(h]”jY ah ]”(jj€eh"]”h$]”h&]”j„ˆj…)j†huh1j”h³jt h´KHhj[ h²hubjˆ)�”}”(hhh]”hì)�”}”(hŒDecrement refcount for object”h]”hŒDecrement refcount for object”…”�”}”(hjq h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hëh³ŒS/var/lib/git/docbuild/linux/Documentation/core-api/kref:328: ./include/linux/kref.h”h´KHhjn h²hubah}”(h]”h ]”h"]”h$]”h&]”uh1j‡hj[ h²hh³jt h´KHubeh}”(h]”h ]”(j%Œfunction”eh"]”h$]”h&]”j¨j%j©j‰ jªj‰ j«‰j¬‰j­‰uh1j�h²hhjmh³Nh´Nubj¯)�”}”(hX¡**Parameters** ``struct kref *kref`` Object ``void (*release)(struct kref *kref)`` Pointer to the function that will clean up the object when the last reference to the object is released. ``struct mutex *mutex`` Mutex which protects the release function. **Description** This variant of kref_lock() calls the **release** function with the **mutex** held. The **release** function will release the mutex.”h]”(hì)�”}”(hŒ**Parameters**”h]”j¹)�”}”(hj“ h]”hŒ Parameters”…”�”}”(hj• h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j¸hj‘ ubah}”(h]”h ]”h"]”h$]”h&]”uh1hëh³ŒS/var/lib/git/docbuild/linux/Documentation/core-api/kref:328: ./include/linux/kref.h”h´KLhj� ubjÏ)�”}”(hhh]”(jÔ)�”}”(hŒ``struct kref *kref`` Object ”h]”(jÚ)�”}”(hŒ``struct kref *kref``”h]”jà)�”}”(hj² h]”hŒstruct kref *kref”…”�”}”(hj´ h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jßhj° ubah}”(h]”h ]”h"]”h$]”h&]”uh1jÙh³ŒS/var/lib/git/docbuild/linux/Documentation/core-api/kref:328: ./include/linux/kref.h”h´KIhj¬ ubjö)�”}”(hhh]”hì)�”}”(hŒObject”h]”hŒObject”…”�”}”(hjË h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hëh³jÇ h´KIhjÈ ubah}”(h]”h ]”h"]”h$]”h&]”uh1jõhj¬ ubeh}”(h]”h ]”h"]”h$]”h&]”uh1jÓh³jÇ h´KIhj© ubjÔ)�”}”(hŒ�``void (*release)(struct kref *kref)`` Pointer to the function that will clean up the object when the last reference to the object is released. ”h]”(jÚ)�”}”(hŒ&``void (*release)(struct kref *kref)``”h]”jà)�”}”(hjë h]”hŒ"void (*release)(struct kref *kref)”…”�”}”(hjí h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jßhjé ubah}”(h]”h ]”h"]”h$]”h&]”uh1jÙh³ŒS/var/lib/git/docbuild/linux/Documentation/core-api/kref:328: ./include/linux/kref.h”h´KKhjå ubjö)�”}”(hhh]”hì)�”}”(hŒhPointer to the function that will clean up the object when the last reference to the object is released.”h]”hŒhPointer to the function that will clean up the object when the last reference to the object is released.”…”�”}”(hj h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hëh³ŒS/var/lib/git/docbuild/linux/Documentation/core-api/kref:328: ./include/linux/kref.h”h´KJhj ubah}”(h]”h ]”h"]”h$]”h&]”uh1jõhjå ubeh}”(h]”h ]”h"]”h$]”h&]”uh1jÓh³j h´KKhj© ubjÔ)�”}”(hŒC``struct mutex *mutex`` Mutex which protects the release function. ”h]”(jÚ)�”}”(hŒ``struct mutex *mutex``”h]”jà)�”}”(hj% h]”hŒstruct mutex *mutex”…”�”}”(hj' h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jßhj# ubah}”(h]”h ]”h"]”h$]”h&]”uh1jÙh³ŒS/var/lib/git/docbuild/linux/Documentation/core-api/kref:328: ./include/linux/kref.h”h´KLhj ubjö)�”}”(hhh]”hì)�”}”(hŒ*Mutex which protects the release function.”h]”hŒ*Mutex which protects the release function.”…”�”}”(hj> h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hëh³j: h´KLhj; ubah}”(h]”h ]”h"]”h$]”h&]”uh1jõhj ubeh}”(h]”h ]”h"]”h$]”h&]”uh1jÓh³j: h´KLhj© ubeh}”(h]”h ]”h"]”h$]”h&]”uh1jÎhj� ubhì)�”}”(hŒ**Description**”h]”j¹)�”}”(hj` h]”hŒ Description”…”�”}”(hjb h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j¸hj^ ubah}”(h]”h ]”h"]”h$]”h&]”uh1hëh³ŒS/var/lib/git/docbuild/linux/Documentation/core-api/kref:328: ./include/linux/kref.h”h´KNhj� ubhì)�”}”(hŒ…This variant of kref_lock() calls the **release** function with the **mutex** held. The **release** function will release the mutex.”h]”(hŒ&This variant of kref_lock() calls the ”…”�”}”(hjv h²hh³Nh´Nubj¹)�”}”(hŒ **release**”h]”hŒrelease”…”�”}”(hj~ h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j¸hjv ubhŒ function with the ”…”�”}”(hjv h²hh³Nh´Nubj¹)�”}”(hŒ **mutex**”h]”hŒmutex”…”�”}”(hj� h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j¸hjv ubhŒ held. The ”…”�”}”(hjv h²hh³Nh´Nubj¹)�”}”(hŒ **release**”h]”hŒrelease”…”�”}”(hj¢ h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j¸hjv ubhŒ! function will release the mutex.”…”�”}”(hjv h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hëh³ŒS/var/lib/git/docbuild/linux/Documentation/core-api/kref:328: ./include/linux/kref.h”h´KMhj� ubeh}”(h]”h ]”Œ kernelindent”ah"]”h$]”h&]”uh1j®hjmh²hh³Nh´Nubj)�”}”(hhh]”h}”(h]”h ]”h"]”h$]”h&]”Œentries”]”(j‹Œkref_put_lock (C function)”Œc.kref_put_lock”hNt”auh1j~hjmh²hh³Nh´Nubj�)�”}”(hhh]”(j•)�”}”(hŒ[int kref_put_lock (struct kref *kref, void (*release)(struct kref *kref), spinlock_t *lock)”h]”j›)�”}”(hŒZint kref_put_lock(struct kref *kref, void (*release)(struct kref *kref), spinlock_t *lock)”h]”(j¡)�”}”(hŒint”h]”hŒint”…”�”}”(hjÛ h²hh³Nh´Nubah}”(h]”h ]”j­ah"]”h$]”h&]”uh1j hj× h²hh³ŒS/var/lib/git/docbuild/linux/Documentation/core-api/kref:328: ./include/linux/kref.h”h´K^ubj³)�”}”(hŒ ”h]”hŒ ”…”�”}”(hjê h²hh³Nh´Nubah}”(h]”h ]”j¿ah"]”h$]”h&]”uh1j²hj× h²hh³jé h´K^ubjÄ)�”}”(hŒ kref_put_lock”h]”jÊ)�”}”(hŒ kref_put_lock”h]”hŒ kref_put_lock”…”�”}”(hjü h²hh³Nh´Nubah}”(h]”h ]”jÖah"]”h$]”h&]”uh1jÉhjø ubah}”(h]”h ]”(jÝjÞeh"]”h$]”h&]”jjuh1jÃhj× h²hh³jé h´K^ubjã)�”}”(hŒI(struct kref *kref, void (*release)(struct kref *kref), spinlock_t *lock)”h]”(jé)�”}”(hŒstruct kref *kref”h]”(jï)�”}”(hjòh]”hŒstruct”…”�”}”(hjh²hh³Nh´Nubah}”(h]”h ]”jûah"]”h$]”h&]”uh1jîhjubj³)�”}”(hŒ ”h]”hŒ ”…”�”}”(hj%h²hh³Nh´Nubah}”(h]”h ]”j¿ah"]”h$]”h&]”uh1j²hjubh)�”}”(hhh]”jÊ)�”}”(hŒkref”h]”hŒkref”…”�”}”(hj6h²hh³Nh´Nubah}”(h]”h ]”jÖah"]”h$]”h&]”uh1jÉhj3ubah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”j%Œreftype”j'Œ reftarget”j8Œmodname”NŒ classname”Nj+j.)�”}”j1]”j4)�”}”j'jþ sbŒc.kref_put_lock”†”asbuh1hhjubj³)�”}”(hŒ ”h]”hŒ ”…”�”}”(hjVh²hh³Nh´Nubah}”(h]”h ]”j¿ah"]”h$]”h&]”uh1j²hjubjH)�”}”(hjKh]”hŒ*”…”�”}”(hjdh²hh³Nh´Nubah}”(h]”h ]”jTah"]”h$]”h&]”uh1jGhjubjÊ)�”}”(hŒkref”h]”hŒkref”…”�”}”(hjqh²hh³Nh´Nubah}”(h]”h ]”jÖah"]”h$]”h&]”uh1jÉhjubeh}”(h]”h ]”h"]”h$]”h&]”Œnoemph”ˆjjuh1jèhjubjé)�”}”(hŒ"void (*release)(struct kref *kref)”h]”(j¡)�”}”(hŒvoid”h]”hŒvoid”…”�”}”(hjŠh²hh³Nh´Nubah}”(h]”h ]”j­ah"]”h$]”h&]”uh1j hj†ubj³)�”}”(hŒ ”h]”hŒ ”…”�”}”(hj˜h²hh³Nh´Nubah}”(h]”h ]”j¿ah"]”h$]”h&]”uh1j²hj†ubjH)�”}”(hjch]”hŒ(”…”�”}”(hj¦h²hh³Nh´Nubah}”(h]”h ]”jTah"]”h$]”h&]”uh1jGhj†ubjH)�”}”(hjKh]”hŒ*”…”�”}”(hj³h²hh³Nh´Nubah}”(h]”h ]”jTah"]”h$]”h&]”uh1jGhj†ubjÊ)�”}”(hŒrelease”h]”hŒrelease”…”�”}”(hjÀh²hh³Nh´Nubah}”(h]”h ]”jÖah"]”h$]”h&]”uh1jÉhj†ubjH)�”}”(hjh]”hŒ)”…”�”}”(hjÎh²hh³Nh´Nubah}”(h]”h ]”jTah"]”h$]”h&]”uh1jGhj†ubjH)�”}”(hjch]”hŒ(”…”�”}”(hjÛh²hh³Nh´Nubah}”(h]”h ]”jTah"]”h$]”h&]”uh1jGhj†ubjï)�”}”(hjòh]”hŒstruct”…”�”}”(hjèh²hh³Nh´Nubah}”(h]”h ]”jûah"]”h$]”h&]”uh1jîhj†ubj³)�”}”(hŒ ”h]”hŒ ”…”�”}”(hjõh²hh³Nh´Nubah}”(h]”h ]”j¿ah"]”h$]”h&]”uh1j²hj†ubh)�”}”(hhh]”jÊ)�”}”(hŒkref”h]”hŒkref”…”�”}”(hjh²hh³Nh´Nubah}”(h]”h ]”jÖah"]”h$]”h&]”uh1jÉhjubah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”j%Œreftype”j'Œ reftarget”jŒmodname”NŒ classname”Nj+j.)�”}”j1]”jRŒc.kref_put_lock”†”asbuh1hhj†ubj³)�”}”(hŒ ”h]”hŒ ”…”�”}”(hj$h²hh³Nh´Nubah}”(h]”h ]”j¿ah"]”h$]”h&]”uh1j²hj†ubjH)�”}”(hjKh]”hŒ*”…”�”}”(hj2h²hh³Nh´Nubah}”(h]”h ]”jTah"]”h$]”h&]”uh1jGhj†ubjÊ)�”}”(hŒkref”h]”hŒkref”…”�”}”(hj?h²hh³Nh´Nubah}”(h]”h ]”jÖah"]”h$]”h&]”uh1jÉhj†ubjH)�”}”(hjh]”hŒ)”…”�”}”(hjMh²hh³Nh´Nubah}”(h]”h ]”jTah"]”h$]”h&]”uh1jGhj†ubeh}”(h]”h ]”h"]”h$]”h&]”Œnoemph”ˆjjuh1jèhjubjé)�”}”(hŒspinlock_t *lock”h]”(h)�”}”(hhh]”jÊ)�”}”(hŒ spinlock_t”h]”hŒ spinlock_t”…”�”}”(hjhh²hh³Nh´Nubah}”(h]”h ]”jÖah"]”h$]”h&]”uh1jÉhjeubah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”j%Œreftype”j'Œ reftarget”jjŒmodname”NŒ classname”Nj+j.)�”}”j1]”jRŒc.kref_put_lock”†”asbuh1hhjaubj³)�”}”(hŒ ”h]”hŒ ”…”�”}”(hj†h²hh³Nh´Nubah}”(h]”h ]”j¿ah"]”h$]”h&]”uh1j²hjaubjH)�”}”(hjKh]”hŒ*”…”�”}”(hj”h²hh³Nh´Nubah}”(h]”h ]”jTah"]”h$]”h&]”uh1jGhjaubjÊ)�”}”(hŒlock”h]”hŒlock”…”�”}”(hj¡h²hh³Nh´Nubah}”(h]”h ]”jÖah"]”h$]”h&]”uh1jÉhjaubeh}”(h]”h ]”h"]”h$]”h&]”Œnoemph”ˆjjuh1jèhjubeh}”(h]”h ]”h"]”h$]”h&]”jjuh1jâhj× h²hh³jé h´K^ubeh}”(h]”h ]”h"]”h$]”h&]”jjjyˆuh1jšjzj{hjÓ h²hh³jé h´K^ubah}”(h]”jÎ ah ]”(jj€eh"]”h$]”h&]”j„ˆj…)j†huh1j”h³jé h´K^hjÐ h²hubjˆ)�”}”(hhh]”hì)�”}”(hŒDecrement refcount for object”h]”hŒDecrement refcount for object”…”�”}”(hjËh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hëh³ŒS/var/lib/git/docbuild/linux/Documentation/core-api/kref:328: ./include/linux/kref.h”h´K^hjÈh²hubah}”(h]”h ]”h"]”h$]”h&]”uh1j‡hjÐ h²hh³jé h´K^ubeh}”(h]”h ]”(j%Œfunction”eh"]”h$]”h&]”j¨j%j©jãjªjãj«‰j¬‰j­‰uh1j�h²hhjmh³Nh´Nubj¯)�”}”(hXŸ**Parameters** ``struct kref *kref`` Object ``void (*release)(struct kref *kref)`` Pointer to the function that will clean up the object when the last reference to the object is released. ``spinlock_t *lock`` Spinlock which protects the release function. **Description** This variant of kref_lock() calls the **release** function with the **lock** held. The **release** function will release the lock.”h]”(hì)�”}”(hŒ**Parameters**”h]”j¹)�”}”(hjíh]”hŒ Parameters”…”�”}”(hjïh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j¸hjëubah}”(h]”h ]”h"]”h$]”h&]”uh1hëh³ŒS/var/lib/git/docbuild/linux/Documentation/core-api/kref:328: ./include/linux/kref.h”h´KbhjçubjÏ)�”}”(hhh]”(jÔ)�”}”(hŒ``struct kref *kref`` Object ”h]”(jÚ)�”}”(hŒ``struct kref *kref``”h]”jà)�”}”(hj h]”hŒstruct kref *kref”…”�”}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jßhj ubah}”(h]”h ]”h"]”h$]”h&]”uh1jÙh³ŒS/var/lib/git/docbuild/linux/Documentation/core-api/kref:328: ./include/linux/kref.h”h´K_hjubjö)�”}”(hhh]”hì)�”}”(hŒObject”h]”hŒObject”…”�”}”(hj%h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hëh³j!h´K_hj"ubah}”(h]”h ]”h"]”h$]”h&]”uh1jõhjubeh}”(h]”h ]”h"]”h$]”h&]”uh1jÓh³j!h´K_hjubjÔ)�”}”(hŒ�``void (*release)(struct kref *kref)`` Pointer to the function that will clean up the object when the last reference to the object is released. ”h]”(jÚ)�”}”(hŒ&``void (*release)(struct kref *kref)``”h]”jà)�”}”(hjEh]”hŒ"void (*release)(struct kref *kref)”…”�”}”(hjGh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jßhjCubah}”(h]”h ]”h"]”h$]”h&]”uh1jÙh³ŒS/var/lib/git/docbuild/linux/Documentation/core-api/kref:328: ./include/linux/kref.h”h´Kahj?ubjö)�”}”(hhh]”hì)�”}”(hŒhPointer to the function that will clean up the object when the last reference to the object is released.”h]”hŒhPointer to the function that will clean up the object when the last reference to the object is released.”…”�”}”(hj^h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hëh³ŒS/var/lib/git/docbuild/linux/Documentation/core-api/kref:328: ./include/linux/kref.h”h´K`hj[ubah}”(h]”h ]”h"]”h$]”h&]”uh1jõhj?ubeh}”(h]”h ]”h"]”h$]”h&]”uh1jÓh³jZh´KahjubjÔ)�”}”(hŒC``spinlock_t *lock`` Spinlock which protects the release function. ”h]”(jÚ)�”}”(hŒ``spinlock_t *lock``”h]”jà)�”}”(hjh]”hŒspinlock_t *lock”…”�”}”(hj�h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jßhj}ubah}”(h]”h ]”h"]”h$]”h&]”uh1jÙh³ŒS/var/lib/git/docbuild/linux/Documentation/core-api/kref:328: ./include/linux/kref.h”h´Kbhjyubjö)�”}”(hhh]”hì)�”}”(hŒ-Spinlock which protects the release function.”h]”hŒ-Spinlock which protects the release function.”…”�”}”(hj˜h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hëh³j”h´Kbhj•ubah}”(h]”h ]”h"]”h$]”h&]”uh1jõhjyubeh}”(h]”h ]”h"]”h$]”h&]”uh1jÓh³j”h´Kbhjubeh}”(h]”h ]”h"]”h$]”h&]”uh1jÎhjçubhì)�”}”(hŒ**Description**”h]”j¹)�”}”(hjºh]”hŒ Description”…”�”}”(hj¼h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j¸hj¸ubah}”(h]”h ]”h"]”h$]”h&]”uh1hëh³ŒS/var/lib/git/docbuild/linux/Documentation/core-api/kref:328: ./include/linux/kref.h”h´Kdhjçubhì)�”}”(hŒƒThis variant of kref_lock() calls the **release** function with the **lock** held. The **release** function will release the lock.”h]”(hŒ&This variant of kref_lock() calls the ”…”�”}”(hjÐh²hh³Nh´Nubj¹)�”}”(hŒ **release**”h]”hŒrelease”…”�”}”(hjØh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j¸hjÐubhŒ function with the ”…”�”}”(hjÐh²hh³Nh´Nubj¹)�”}”(hŒ**lock**”h]”hŒlock”…”�”}”(hjêh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j¸hjÐubhŒ held. The ”…”�”}”(hjÐh²hh³Nh´Nubj¹)�”}”(hŒ **release**”h]”hŒrelease”…”�”}”(hjüh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j¸hjÐubhŒ function will release the lock.”…”�”}”(hjÐh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hëh³ŒS/var/lib/git/docbuild/linux/Documentation/core-api/kref:328: ./include/linux/kref.h”h´Kchjçubeh}”(h]”h ]”Œ kernelindent”ah"]”h$]”h&]”uh1j®hjmh²hh³Nh´Nubj)�”}”(hhh]”h}”(h]”h ]”h"]”h$]”h&]”Œentries”]”(j‹Œ!kref_get_unless_zero (C function)”Œc.kref_get_unless_zero”hNt”auh1j~hjmh²hh³Nh´Nubj�)�”}”(hhh]”(j•)�”}”(hŒ,int kref_get_unless_zero (struct kref *kref)”h]”j›)�”}”(hŒ+int kref_get_unless_zero(struct kref *kref)”h]”(j¡)�”}”(hŒint”h]”hŒint”…”�”}”(hj5h²hh³Nh´Nubah}”(h]”h ]”j­ah"]”h$]”h&]”uh1j hj1h²hh³ŒS/var/lib/git/docbuild/linux/Documentation/core-api/kref:328: ./include/linux/kref.h”h´Ktubj³)�”}”(hŒ ”h]”hŒ ”…”�”}”(hjDh²hh³Nh´Nubah}”(h]”h ]”j¿ah"]”h$]”h&]”uh1j²hj1h²hh³jCh´KtubjÄ)�”}”(hŒkref_get_unless_zero”h]”jÊ)�”}”(hŒkref_get_unless_zero”h]”hŒkref_get_unless_zero”…”�”}”(hjVh²hh³Nh´Nubah}”(h]”h ]”jÖah"]”h$]”h&]”uh1jÉhjRubah}”(h]”h ]”(jÝjÞeh"]”h$]”h&]”jjuh1jÃhj1h²hh³jCh´Ktubjã)�”}”(hŒ(struct kref *kref)”h]”jé)�”}”(hŒstruct kref *kref”h]”(jï)�”}”(hjòh]”hŒstruct”…”�”}”(hjrh²hh³Nh´Nubah}”(h]”h ]”jûah"]”h$]”h&]”uh1jîhjnubj³)�”}”(hŒ ”h]”hŒ ”…”�”}”(hjh²hh³Nh´Nubah}”(h]”h ]”j¿ah"]”h$]”h&]”uh1j²hjnubh)�”}”(hhh]”jÊ)�”}”(hŒkref”h]”hŒkref”…”�”}”(hj�h²hh³Nh´Nubah}”(h]”h ]”jÖah"]”h$]”h&]”uh1jÉhj�ubah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”j%Œreftype”j'Œ reftarget”j’Œmodname”NŒ classname”Nj+j.)�”}”j1]”j4)�”}”j'jXsb•ýŒc.kref_get_unless_zero”†”asbuh1hhjnubj³)�”}”(hŒ ”h]”hŒ ”…”�”}”(hj°h²hh³Nh´Nubah}”(h]”h ]”j¿ah"]”h$]”h&]”uh1j²hjnubjH)�”}”(hjKh]”hŒ*”…”�”}”(hj¾h²hh³Nh´Nubah}”(h]”h ]”jTah"]”h$]”h&]”uh1jGhjnubjÊ)�”}”(hŒkref”h]”hŒkref”…”�”}”(hjËh²hh³Nh´Nubah}”(h]”h ]”jÖah"]”h$]”h&]”uh1jÉhjnubeh}”(h]”h ]”h"]”h$]”h&]”Œnoemph”ˆjjuh1jèhjjubah}”(h]”h ]”h"]”h$]”h&]”jjuh1jâhj1h²hh³jCh´Ktubeh}”(h]”h ]”h"]”h$]”h&]”jjjyˆuh1jšjzj{hj-h²hh³jCh´Ktubah}”(h]”j(ah ]”(jj€eh"]”h$]”h&]”j„ˆj…)j†huh1j”h³jCh´Kthj*h²hubjˆ)�”}”(hhh]”hì)�”}”(hŒ0Increment refcount for object unless it is zero.”h]”hŒ0Increment refcount for object unless it is zero.”…”�”}”(hjõh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hëh³ŒS/var/lib/git/docbuild/linux/Documentation/core-api/kref:328: ./include/linux/kref.h”h´Kthjòh²hubah}”(h]”h ]”h"]”h$]”h&]”uh1j‡hj*h²hh³jCh´Ktubeh}”(h]”h ]”(j%Œfunction”eh"]”h$]”h&]”j¨j%j©j jªj j«‰j¬‰j­‰uh1j�h²hhjmh³Nh´Nubj¯)�”}”(hXã**Parameters** ``struct kref *kref`` object. **Description** 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. **Return** non-zero if the increment succeeded. Otherwise return 0.”h]”(hì)�”}”(hŒ**Parameters**”h]”j¹)�”}”(hjh]”hŒ Parameters”…”�”}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j¸hjubah}”(h]”h ]”h"]”h$]”h&]”uh1hëh³ŒS/var/lib/git/docbuild/linux/Documentation/core-api/kref:328: ./include/linux/kref.h”h´KxhjubjÏ)�”}”(hhh]”jÔ)�”}”(hŒ``struct kref *kref`` object. ”h]”(jÚ)�”}”(hŒ``struct kref *kref``”h]”jà)�”}”(hj6h]”hŒstruct kref *kref”…”�”}”(hj8h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jßhj4ubah}”(h]”h ]”h"]”h$]”h&]”uh1jÙh³ŒS/var/lib/git/docbuild/linux/Documentation/core-api/kref:328: ./include/linux/kref.h”h´Kuhj0ubjö)�”}”(hhh]”hì)�”}”(hŒobject.”h]”hŒobject.”…”�”}”(hjOh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hëh³jKh´KuhjLubah}”(h]”h ]”h"]”h$]”h&]”uh1jõhj0ubeh}”(h]”h ]”h"]”h$]”h&]”uh1jÓh³jKh´Kuhj-ubah}”(h]”h ]”h"]”h$]”h&]”uh1jÎhjubhì)�”}”(hŒ**Description**”h]”j¹)�”}”(hjqh]”hŒ Description”…”�”}”(hjsh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j¸hjoubah}”(h]”h ]”h"]”h$]”h&]”uh1hëh³ŒS/var/lib/git/docbuild/linux/Documentation/core-api/kref:328: ./include/linux/kref.h”h´Kwhjubhì)�”}”(hX[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.”h]”(hXÅ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 ”…”�”}”(hj‡h²hh³Nh´NubhŒemphasis”“”)�”}”(hŒ*with return value check*”h]”hŒwith return value check”…”�”}”(hj‘h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j�hj‡ubhŒ} locking in the kref_put path can be deferred to the actual removal from the lookup structure and RCU lookups become trivial.”…”�”}”(hj‡h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hëh³ŒS/var/lib/git/docbuild/linux/Documentation/core-api/kref:328: ./include/linux/kref.h”h´Kvhjubhì)�”}”(hŒ **Return**”h]”j¹)�”}”(hj¬h]”hŒReturn”…”�”}”(hj®h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j¸hjªubah}”(h]”h ]”h"]”h$]”h&]”uh1hëh³ŒS/var/lib/git/docbuild/linux/Documentation/core-api/kref:328: ./include/linux/kref.h”h´K€hjubhì)�”}”(hŒ8non-zero if the increment succeeded. Otherwise return 0.”h]”hŒ8non-zero if the increment succeeded. Otherwise return 0.”…”�”}”(hjÂh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hëh³ŒS/var/lib/git/docbuild/linux/Documentation/core-api/kref:328: ./include/linux/kref.h”h´K�hjubeh}”(h]”h ]”Œ kernelindent”ah"]”h$]”h&]”uh1j®hjmh²hh³Nh´Nubeh}”(h]”Œfunctions-and-structures”ah ]”h"]”Œfunctions and structures”ah$]”h&]”uh1hµhh·h²hh³hÊh´MFubeh}”(h]”Œ1adding-reference-counters-krefs-to-kernel-objects”ah ]”h"]”Œ3adding reference counters (krefs) to kernel objects”ah$]”h&]”uh1hµhhh²hh³hÊh´Kubeh}”(h]”h ]”h"]”h$]”h&]”Œsource”hÊuh1hŒcurrent_source”NŒ current_line”NŒsettings”Œdocutils.frontend”ŒValues”“”)�”}”(hºNŒ generator”NŒ datestamp”NŒ source_link”NŒ source_url”NŒ toc_backlinks”Œentry”Œfootnote_backlinks”KŒ sectnum_xform”KŒstrip_comments”NŒstrip_elements_with_classes”NŒ strip_classes”NŒ report_level”KŒ halt_level”KŒexit_status_level”KŒdebug”NŒwarning_stream”NŒ traceback”ˆŒinput_encoding”Œ utf-8-sig”Œinput_encoding_error_handler”Œstrict”Œoutput_encoding”Œutf-8”Œoutput_encoding_error_handler”j Œerror_encoding”Œutf-8”Œerror_encoding_error_handler”Œbackslashreplace”Œ language_code”Œen”Œrecord_dependencies”NŒconfig”NŒ id_prefix”hŒauto_id_prefix”Œid”Œ dump_settings”NŒdump_internals”NŒdump_transforms”NŒdump_pseudo_xml”NŒexpose_internals”NŒstrict_visitor”NŒ_disable_config”NŒ_source”hÊŒ _destination”NŒ _config_files”]”Œ7/var/lib/git/docbuild/linux/Documentation/docutils.conf”aŒfile_insertion_enabled”ˆŒ raw_enabled”KŒline_length_limit”M'Œpep_references”NŒ pep_base_url”Œhttps://peps.python.org/”Œpep_file_url_template”Œpep-%04d”Œrfc_references”NŒ rfc_base_url”Œ&https://datatracker.ietf.org/doc/html/”Œ tab_width”KŒtrim_footnote_reference_space”‰Œsyntax_highlight”Œlong”Œ smart_quotes”ˆŒsmartquotes_locales”]”Œcharacter_level_inline_markup”‰Œdoctitle_xform”‰Œ docinfo_xform”KŒsectsubtitle_xform”‰Œ image_loading”Œlink”Œembed_stylesheet”‰Œcloak_email_addresses”ˆŒsection_self_link”‰Œenv”NubŒreporter”NŒindirect_targets”]”Œsubstitution_defs”}”Œsubstitution_names”}”Œrefnames”}”Œrefids”}”Œnameids”}”(jåjâj#j jfjcj'j$jjjgjÝjÚuŒ nametypes”}”(jå‰j#‰jf‰j'‰jj‰j݉uh}”(jâh·j jÑjcj&j$jijgj*jÚjmj�j–j.j3j‰jŽjY j^ jÎ jÓ j(j-uŒ footnote_refs”}”Œ citation_refs”}”Œ autofootnotes”]”Œautofootnote_refs”]”Œsymbol_footnotes”]”Œsymbol_footnote_refs”]”Œ footnotes”]”Œ citations”]”Œautofootnote_start”KŒsymbol_footnote_start”KŒ id_counter”Œ collections”ŒCounter”“”}”…”R”Œparse_messages”]”Œtransform_messages”]”Œ transformer”NŒ include_log”]”Œ decoration”Nh²hub.