€•+Œ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/kernel-hacking/locking”Œ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/kernel-hacking/locking”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)�”}”(hhh]”hŒItalian”…”�”}”hhFsbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ*/translations/it_IT/kernel-hacking/locking”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)�”}”(hhh]”hŒJapanese”…”�”}”hhZsbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ*/translations/ja_JP/kernel-hacking/locking”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)�”}”(hhh]”hŒKorean”…”�”}”hhnsbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ*/translations/ko_KR/kernel-hacking/locking”Œ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/kernel-hacking/locking”Œ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/kernel-hacking/locking”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubeh}”(h]”h ]”h"]”h$]”h&]”Œcurrent_language”ŒEnglish”uh1h hhŒ _document”hŒsource”NŒline”NubhŒtarget”“”)�”}”(hŒ.. _kernel_hacking_lock:”h]”h}”(h]”h ]”h"]”h$]”h&]”Œrefid”Œkernel-hacking-lock”uh1hµh´Khhh²hh³ŒD/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking.rst”ubhŒsection”“”)�”}”(hhh]”(hŒtitle”“”)�”}”(hŒUnreliable Guide To Locking”h]”hŒUnreliable Guide To Locking”…”�”}”(hhËh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÉhhÆh²hh³hÃ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ŒRusty Russell ”h]”hŒ paragraph”“”)�”}”(hŒ Rusty Russell”h]”hŒ Rusty Russell”…”�”}”(hhûh²hh³Nh´Nubah}”(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²hubah}”(h]”h ]”h"]”h$]”h&]”uh1hÙhhÆh²hh³hÃh´KubhÅ)�”}”(hhh]”(hÊ)�”}”(hŒ Introduction”h]”hŒ Introduction”…”�”}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÉhjh²hh³hÃh´K ubhú)�”}”(hŒ‘Welcome, to Rusty's Remarkably Unreliable Guide to Kernel Locking issues. This document describes the locking systems in the Linux Kernel in 2.6.”h]”hŒ“Welcome, to Rusty’s Remarkably Unreliable Guide to Kernel Locking issues. This document describes the locking systems in the Linux Kernel in 2.6.”…”�”}”(hj,h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´K hjh²hubhú)�”}”(hŒ³With the wide availability of HyperThreading, and preemption in the Linux Kernel, everyone hacking on the kernel needs to know the fundamentals of concurrency and locking for SMP.”h]”hŒ³With the wide availability of HyperThreading, and preemption in the Linux Kernel, everyone hacking on the kernel needs to know the fundamentals of concurrency and locking for SMP.”…”�”}”(hj:h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´Khjh²hubeh}”(h]”Œ introduction”ah ]”h"]”Œ introduction”ah$]”h&]”uh1hÄhhÆh²hh³hÃh´K ubhÅ)�”}”(hhh]”(hÊ)�”}”(hŒThe Problem With Concurrency”h]”hŒThe Problem With Concurrency”…”�”}”(hjSh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÉhjPh²hh³hÃh´Kubhú)�”}”(hŒ1(Skip this if you know what a Race Condition is).”h]”hŒ1(Skip this if you know what a Race Condition is).”…”�”}”(hjah²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´KhjPh²hubhú)�”}”(hŒ9In a normal program, you can increment a counter like so:”h]”hŒ9In a normal program, you can increment a counter like so:”…”�”}”(hjoh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´KhjPh²hubhŒ literal_block”“”)�”}”(hŒvery_important_count++;”h]”hŒvery_important_count++;”…”�”}”hjsbah}”(h]”h ]”h"]”h$]”h&]”Œ xml:space”Œpreserve”uh1j}h³hÃh´KhjPh²hubhú)�”}”(hŒ)This is what they would expect to happen:”h]”hŒ)This is what they would expect to happen:”…”�”}”(hj�h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´K hjPh²hubhŒtable”“”)�”}”(hhh]”(hÊ)�”}”(hŒExpected Results”h]”hŒExpected Results”…”�”}”(hj¢h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÉh³hÃh´K#hjŸubhŒtgroup”“”)�”}”(hhh]”(hŒcolspec”“”)�”}”(hhh]”h}”(h]”h ]”h"]”h$]”h&]”Œcolwidth”K$uh1jµhj²ubj¶)�”}”(hhh]”h}”(h]”h ]”h"]”h$]”h&]”Œcolwidth”K$uh1jµhj²ubhŒthead”“”)�”}”(hhh]”hŒrow”“”)�”}”(hhh]”(hŒentry”“”)�”}”(hhh]”hú)�”}”(hŒ Instance 1”h]”hŒ Instance 1”…”�”}”(hjÚh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´K&hj×ubah}”(h]”h ]”h"]”h$]”h&]”uh1jÕhjÒubjÖ)�”}”(hhh]”hú)�”}”(hŒ Instance 2”h]”hŒ Instance 2”…”�”}”(hjñh²hh³Nh´Nubah}”(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&]”uh1jÐhjÍubah}”(h]”h ]”h"]”h$]”h&]”uh1jËhj²ubhŒtbody”“”)�”}”(hhh]”(jÑ)�”}”(hhh]”(jÖ)�”}”(hhh]”hú)�”}”(hŒread very_important_count (5)”h]”hŒread very_important_count (5)”…”�”}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´K(hjubah}”(h]”h ]”h"]”h$]”h&]”uh1jÕhjubjÖ)�”}”(hhh]”h}”(h]”h ]”h"]”h$]”h&]”uh1jÕhjubeh}”(h]”h ]”h"]”h$]”h&]”uh1jÐhjubjÑ)�”}”(hhh]”(jÖ)�”}”(hhh]”hú)�”}”(hŒ add 1 (6)”h]”hŒ add 1 (6)”…”�”}”(hjEh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´K*hjBubah}”(h]”h ]”h"]”h$]”h&]”uh1jÕhj?ubjÖ)�”}”(hhh]”h}”(h]”h ]”h"]”h$]”h&]”uh1jÕhj?ubeh}”(h]”h ]”h"]”h$]”h&]”uh1jÐhjubjÑ)�”}”(hhh]”(jÖ)�”}”(hhh]”hú)�”}”(hŒwrite very_important_count (6)”h]”hŒwrite very_important_count (6)”…”�”}”(hjnh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´K,hjkubah}”(h]”h ]”h"]”h$]”h&]”uh1jÕhjhubjÖ)�”}”(hhh]”h}”(h]”h ]”h"]”h$]”h&]”uh1jÕhjhubeh}”(h]”h ]”h"]”h$]”h&]”uh1jÐhjubjÑ)�”}”(hhh]”(jÖ)�”}”(hhh]”h}”(h]”h ]”h"]”h$]”h&]”uh1jÕhj‘ubjÖ)�”}”(hhh]”hú)�”}”(hŒread very_important_count (6)”h]”hŒread very_important_count (6)”…”�”}”(hj h²hh³Nh´Nubah}”(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&]”uh1jÐhjubjÑ)�”}”(hhh]”(jÖ)�”}”(hhh]”h}”(h]”h ]”h"]”h$]”h&]”uh1jÕhjºubjÖ)�”}”(hhh]”hú)�”}”(hŒ add 1 (7)”h]”hŒ add 1 (7)”…”�”}”(hjÉh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´K0hjÆubah}”(h]”h ]”h"]”h$]”h&]”uh1jÕhjºubeh}”(h]”h ]”h"]”h$]”h&]”uh1jÐhjubjÑ)�”}”(hhh]”(jÖ)�”}”(hhh]”h}”(h]”h ]”h"]”h$]”h&]”uh1jÕhjãubjÖ)�”}”(hhh]”hú)�”}”(hŒwrite very_important_count (7)”h]”hŒwrite very_important_count (7)”…”�”}”(hjòh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´K2hjïubah}”(h]”h ]”h"]”h$]”h&]”uh1jÕhjãubeh}”(h]”h ]”h"]”h$]”h&]”uh1jÐhjubeh}”(h]”h ]”h"]”h$]”h&]”uh1jhj²ubeh}”(h]”h ]”h"]”h$]”h&]”Œcols”Kuh1j°hjŸubeh}”(h]”Œid1”ah ]”h"]”h$]”h&]”uh1j�hjPh²hh³hÃh´Nubhú)�”}”(hŒThis is what might happen:”h]”hŒThis is what might happen:”…”�”}”(hj h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´K5hjPh²hubjž)�”}”(hhh]”(hÊ)�”}”(hŒPossible Results”h]”hŒPossible Results”…”�”}”(hj1h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÉh³hÃh´K7hj.ubj±)�”}”(hhh]”(j¶)�”}”(hhh]”h}”(h]”h ]”h"]”h$]”h&]”Œcolwidth”K$uh1jµhj?ubj¶)�”}”(hhh]”h}”(h]”h ]”h"]”h$]”h&]”Œcolwidth”K$uh1jµhj?ubjÌ)�”}”(hhh]”jÑ)�”}”(hhh]”(jÖ)�”}”(hhh]”hú)�”}”(hŒ Instance 1”h]”hŒ Instance 1”…”�”}”(hj_h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´K:hj\ubah}”(h]”h ]”h"]”h$]”h&]”uh1jÕhjYubjÖ)�”}”(hhh]”hú)�”}”(hŒ Instance 2”h]”hŒ Instance 2”…”�”}”(hjvh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´K:hjsubah}”(h]”h ]”h"]”h$]”h&]”uh1jÕhjYubeh}”(h]”h ]”h"]”h$]”h&]”uh1jÐhjVubah}”(h]”h ]”h"]”h$]”h&]”uh1jËhj?ubj)�”}”(hhh]”(jÑ)�”}”(hhh]”(jÖ)�”}”(hhh]”hú)�”}”(hŒread very_important_count (5)”h]”hŒread very_important_count (5)”…”�”}”(hjŸh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´KhjÎubah}”(h]”h ]”h"]”h$]”h&]”uh1jÕhjÂubeh}”(h]”h ]”h"]”h$]”h&]”uh1jÐhj–ubjÑ)�”}”(hhh]”(jÖ)�”}”(hhh]”hú)�”}”(hŒ add 1 (6)”h]”hŒ add 1 (6)”…”�”}”(hjñh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´K@hjîubah}”(h]”h ]”h"]”h$]”h&]”uh1jÕhjëubjÖ)�”}”(hhh]”h}”(h]”h ]”h"]”h$]”h&]”uh1jÕhjëubeh}”(h]”h ]”h"]”h$]”h&]”uh1jÐhj–ubjÑ)�”}”(hhh]”(jÖ)�”}”(hhh]”h}”(h]”h ]”h"]”h$]”h&]”uh1jÕhjubjÖ)�”}”(hhh]”hú)�”}”(hŒ add 1 (6)”h]”hŒ add 1 (6)”…”�”}”(hj#h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´KBhj ubah}”(h]”h ]”h"]”h$]”h&]”uh1jÕhjubeh}”(h]”h ]”h"]”h$]”h&]”uh1jÐhj–ubjÑ)�”}”(hhh]”(jÖ)�”}”(hhh]”hú)�”}”(hŒwrite very_important_count (6)”h]”hŒwrite very_important_count (6)”…”�”}”(hjCh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´KDhj@ubah}”(h]”h ]”h"]”h$]”h&]”uh1jÕhj=ubjÖ)�”}”(hhh]”h}”(h]”h ]”h"]”h$]”h&]”uh1jÕhj=ubeh}”(h]”h ]”h"]”h$]”h&]”uh1jÐhj–ubjÑ)�”}”(hhh]”(jÖ)�”}”(hhh]”h}”(h]”h ]”h"]”h$]”h&]”uh1jÕhjfubjÖ)�”}”(hhh]”hú)�”}”(hŒwrite very_important_count (6)”h]”hŒwrite very_important_count (6)”…”�”}”(hjuh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´KFhjrubah}”(h]”h ]”h"]”h$]”h&]”uh1jÕhjfubeh}”(h]”h ]”h"]”h$]”h&]”uh1jÐhj–ubeh}”(h]”h ]”h"]”h$]”h&]”uh1jhj?ubeh}”(h]”h ]”h"]”h$]”h&]”Œcols”Kuh1j°hj.ubeh}”(h]”Œid2”ah ]”h"]”h$]”h&]”uh1j�hjPh²hh³hÃh´NubhÅ)�”}”(hhh]”(hÊ)�”}”(hŒ$Race Conditions and Critical Regions”h]”hŒ$Race Conditions and Critical Regions”…”�”}”(hj¦h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÉhj£h²hh³hÃh´KKubhú)�”}”(hXBThis overlap, where the result depends on the relative timing of multiple tasks, is called a race condition. The piece of code containing the concurrency issue is called a critical region. And especially since Linux starting running on SMP machines, they became one of the major issues in kernel design and implementation.”h]”hXBThis overlap, where the result depends on the relative timing of multiple tasks, is called a race condition. The piece of code containing the concurrency issue is called a critical region. And especially since Linux starting running on SMP machines, they became one of the major issues in kernel design and implementation.”…”�”}”(hj´h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´KMhj£h²hubhú)�”}”(hŒìPreemption can have the same effect, even if there is only one CPU: by preempting one task during the critical region, we have exactly the same race condition. In this case the thread which preempts might run the critical region itself.”h]”hŒìPreemption can have the same effect, even if there is only one CPU: by preempting one task during the critical region, we have exactly the same race condition. In this case the thread which preempts might run the critical region itself.”…”�”}”(hjÂh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´KShj£h²hubhú)�”}”(hX>The solution is to recognize when these simultaneous accesses occur, and use locks to make sure that only one instance can enter the critical region at any time. There are many friendly primitives in the Linux kernel to help you do this. And then there are the unfriendly primitives, but I'll pretend they don't exist.”h]”hXBThe solution is to recognize when these simultaneous accesses occur, and use locks to make sure that only one instance can enter the critical region at any time. There are many friendly primitives in the Linux kernel to help you do this. And then there are the unfriendly primitives, but I’ll pretend they don’t exist.”…”�”}”(hjÐh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´KXhj£h²hubeh}”(h]”Œ$race-conditions-and-critical-regions”ah ]”h"]”Œ$race conditions and critical regions”ah$]”h&]”uh1hÄhjPh²hh³hÃh´KKubeh}”(h]”Œthe-problem-with-concurrency”ah ]”h"]”Œthe problem with concurrency”ah$]”h&]”uh1hÄhhÆh²hh³hÃh´KubhÅ)�”}”(hhh]”(hÊ)�”}”(hŒLocking in the Linux Kernel”h]”hŒLocking in the Linux Kernel”…”�”}”(hjñh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÉhjîh²hh³hÃh´K_ubhú)�”}”(hŒGIf I could give you one piece of advice on locking: **keep it simple**.”h]”(hŒ4If I could give you one piece of advice on locking: ”…”�”}”(hjÿh²hh³Nh´NubhŒstrong”“”)�”}”(hŒ**keep it simple**”h]”hŒkeep it simple”…”�”}”(hj h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhjÿubhŒ.”…”�”}”(hjÿh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´Kahjîh²hubhú)�”}”(hŒ$Be reluctant to introduce new locks.”h]”hŒ$Be reluctant to introduce new locks.”…”�”}”(hj!h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´Kchjîh²hubhÅ)�”}”(hhh]”(hÊ)�”}”(hŒ5Two Main Types of Kernel Locks: Spinlocks and Mutexes”h]”hŒ5Two Main Types of Kernel Locks: Spinlocks and Mutexes”…”�”}”(hj2h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÉhj/h²hh³hÃh´Kfubhú)�”}”(hXThere are two main types of kernel locks. The fundamental type is the spinlock (``include/asm/spinlock.h``), which is a very simple single-holder lock: if you can't get the spinlock, you keep trying (spinning) until you can. Spinlocks are very small and fast, and can be used anywhere.”h]”(hŒPThere are two main types of kernel locks. The fundamental type is the spinlock (”…”�”}”(hj@h²hh³Nh´NubhŒliteral”“”)�”}”(hŒ``include/asm/spinlock.h``”h]”hŒinclude/asm/spinlock.h”…”�”}”(hjJh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jHhj@ubhŒµ), which is a very simple single-holder lock: if you can’t get the spinlock, you keep trying (spinning) until you can. Spinlocks are very small and fast, and can be used anywhere.”…”�”}”(hj@h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´Khhj/h²hubhú)�”}”(hXªThe second type is a mutex (``include/linux/mutex.h``): it is like a spinlock, but you may block holding a mutex. If you can't lock a mutex, your task will suspend itself, and be woken up when the mutex is released. This means the CPU can do something else while you are waiting. There are many cases when you simply can't sleep (see `What Functions Are Safe To Call From Interrupts?`_), and so have to use a spinlock instead.”h]”(hŒThe second type is a mutex (”…”�”}”(hjbh²hh³Nh´NubjI)�”}”(hŒ``include/linux/mutex.h``”h]”hŒinclude/linux/mutex.h”…”�”}”(hjjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jHhjbubhX): it is like a spinlock, but you may block holding a mutex. If you can’t lock a mutex, your task will suspend itself, and be woken up when the mutex is released. This means the CPU can do something else while you are waiting. There are many cases when you simply can’t sleep (see ”…”�”}”(hjbh²hh³Nh´NubhŒ reference”“”)�”}”(hŒ3`What Functions Are Safe To Call From Interrupts?`_”h]”hŒ0What Functions Are Safe To Call From Interrupts?”…”�”}”(hj~h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”Œname”Œ0What Functions Are Safe To Call From Interrupts?”hÁŒ/what-functions-are-safe-to-call-from-interrupts”uh1j|hjbŒresolved”KubhŒ)), and so have to use a spinlock instead.”…”�”}”(hjbh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´Knhj/h²hubhú)�”}”(hŒHNeither type of lock is recursive: see `Deadlock: Simple and Advanced`_.”h]”(hŒ'Neither type of lock is recursive: see ”…”�”}”(hjšh²hh³Nh´Nubj})�”}”(hŒ `Deadlock: Simple and Advanced`_”h]”hŒDeadlock: Simple and Advanced”…”�”}”(hj¢h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”Œname”ŒDeadlock: Simple and Advanced”hÁŒdeadlock-simple-and-advanced”uh1j|hjšj�KubhŒ.”…”�”}”(hjšh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´Kvhj/h²hubeh}”(h]”Œ4two-main-types-of-kernel-locks-spinlocks-and-mutexes”ah ]”h"]”Œ5two main types of kernel locks: spinlocks and mutexes”ah$]”h&]”uh1hÄhjîh²hh³hÃh´KfubhÅ)�”}”(hhh]”(hÊ)�”}”(hŒLocks and Uniprocessor Kernels”h]”hŒLocks and Uniprocessor Kernels”…”�”}”(hjÈh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÉhjÅh²hh³hÃh´Kzubhú)�”}”(hŒÞFor kernels compiled without ``CONFIG_SMP``, and without ``CONFIG_PREEMPT`` spinlocks do not exist at all. This is an excellent design decision: when no-one else can run at the same time, there is no reason to have a lock.”h]”(hŒFor kernels compiled without ”…”�”}”(hjÖh²hh³Nh´NubjI)�”}”(hŒ``CONFIG_SMP``”h]”hŒ CONFIG_SMP”…”�”}”(hjÞh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jHhjÖubhŒ, and without ”…”�”}”(hjÖh²hh³Nh´NubjI)�”}”(hŒ``CONFIG_PREEMPT``”h]”hŒCONFIG_PREEMPT”…”�”}”(hjðh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jHhjÖubhŒ“ spinlocks do not exist at all. This is an excellent design decision: when no-one else can run at the same time, there is no reason to have a lock.”…”�”}”(hjÖh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´K|hjÅh²hubhú)�”}”(hX If the kernel is compiled without ``CONFIG_SMP``, but ``CONFIG_PREEMPT`` is set, then spinlocks simply disable preemption, which is sufficient to prevent any races. For most purposes, we can think of preemption as equivalent to SMP, and not worry about it separately.”h]”(hŒ"If the kernel is compiled without ”…”�”}”(hjh²hh³Nh´NubjI)�”}”(hŒ``CONFIG_SMP``”h]”hŒ CONFIG_SMP”…”�”}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jHhjubhŒ, but ”…”�”}”(hjh²hh³Nh´NubjI)�”}”(hŒ``CONFIG_PREEMPT``”h]”hŒCONFIG_PREEMPT”…”�”}”(hj"h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jHhjubhŒÃ is set, then spinlocks simply disable preemption, which is sufficient to prevent any races. For most purposes, we can think of preemption as equivalent to SMP, and not worry about it separately.”…”�”}”(hjh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´K�hjÅh²hubhú)�”}”(hŒ¼You should always test your locking code with ``CONFIG_SMP`` and ``CONFIG_PREEMPT`` enabled, even if you don't have an SMP test box, because it will still catch some kinds of locking bugs.”h]”(hŒ.You should always test your locking code with ”…”�”}”(hj:h²hh³Nh´NubjI)�”}”(hŒ``CONFIG_SMP``”h]”hŒ CONFIG_SMP”…”�”}”(hjBh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jHhj:ubhŒ and ”…”�”}”(hj:h²hh³Nh´NubjI)�”}”(hŒ``CONFIG_PREEMPT``”h]”hŒCONFIG_PREEMPT”…”�”}”(hjTh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jHhj:ubhŒk enabled, even if you don’t have an SMP test box, because it will still catch some kinds of locking bugs.”…”�”}”(hj:h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´K†hjÅh²hubhú)�”}”(hŒoMutexes still exist, because they are required for synchronization between user contexts, as we will see below.”h]”hŒoMutexes still exist, because they are required for synchronization between user contexts, as we will see below.”…”�”}”(hjlh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´KŠhjÅh²hubeh}”(h]”Œlocks-and-uniprocessor-kernels”ah ]”h"]”Œlocks and uniprocessor kernels”ah$]”h&]”uh1hÄhjîh²hh³hÃh´KzubhÅ)�”}”(hhh]”(hÊ)�”}”(hŒLocking Only In User Context”h]”hŒLocking Only In User Context”…”�”}”(hj…h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÉhj‚h²hh³hÃh´KŽubhú)�”}”(hXœIf you have a data structure which is only ever accessed from user context, then you can use a simple mutex (``include/linux/mutex.h``) to protect it. This is the most trivial case: you initialize the mutex. Then you can call mutex_lock_interruptible() to grab the mutex, and mutex_unlock() to release it. There is also a mutex_lock(), which should be avoided, because it will not return if a signal is received.”h]”(hŒmIf you have a data structure which is only ever accessed from user context, then you can use a simple mutex (”…”�”}”(hj“h²hh³Nh´NubjI)�”}”(hŒ``include/linux/mutex.h``”h]”hŒinclude/linux/mutex.h”…”�”}”(hj›h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jHhj“ubhX) to protect it. This is the most trivial case: you initialize the mutex. Then you can call mutex_lock_interruptible() to grab the mutex, and mutex_unlock() to release it. There is also a mutex_lock(), which should be avoided, because it will not return if a signal is received.”…”�”}”(hj“h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´K�hj‚h²hubhú)�”}”(hXßExample: ``net/netfilter/nf_sockopt.c`` allows registration of new setsockopt() and getsockopt() calls, with nf_register_sockopt(). Registration and de-registration are only done on module load and unload (and boot time, where there is no concurrency), and the list of registrations is only consulted for an unknown setsockopt() or getsockopt() system call. The ``nf_sockopt_mutex`` is perfect to protect this, especially since the setsockopt and getsockopt calls may well sleep.”h]”(hŒ Example: ”…”�”}”(hj³h²hh³Nh´NubjI)�”}”(hŒ``net/netfilter/nf_sockopt.c``”h]”hŒnet/netfilter/nf_sockopt.c”…”�”}”(hj»h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jHhj³ubhXC allows registration of new setsockopt() and getsockopt() calls, with nf_register_sockopt(). Registration and de-registration are only done on module load and unload (and boot time, where there is no concurrency), and the list of registrations is only consulted for an unknown setsockopt() or getsockopt() system call. The ”…”�”}”(hj³h²hh³Nh´NubjI)�”}”(hŒ``nf_sockopt_mutex``”h]”hŒnf_sockopt_mutex”…”�”}”(hjÍh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jHhj³ubhŒa is perfect to protect this, especially since the setsockopt and getsockopt calls may well sleep.”…”�”}”(hj³h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´K˜hj‚h²hubeh}”(h]”Œlocking-only-in-user-context”ah ]”h"]”Œlocking only in user context”ah$]”h&]”uh1hÄhjîh²hh³hÃh´KŽubhÅ)�”}”(hhh]”(hÊ)�”}”(hŒ)Locking Between User Context and Softirqs”h]”hŒ)Locking Between User Context and Softirqs”…”�”}”(hjðh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÉhjíh²hh³hÃh´K¢ubhú)�”}”(hXIf a softirq shares data with user context, you have two problems. Firstly, the current user context can be interrupted by a softirq, and secondly, the critical region could be entered from another CPU. This is where spin_lock_bh() (``include/linux/spinlock.h``) is used. It disables softirqs on that CPU, then grabs the lock. spin_unlock_bh() does the reverse. (The '_bh' suffix is a historical reference to "Bottom Halves", the old name for software interrupts. It should really be called spin_lock_softirq()' in a perfect world).”h]”(hŒéIf a softirq shares data with user context, you have two problems. Firstly, the current user context can be interrupted by a softirq, and secondly, the critical region could be entered from another CPU. This is where spin_lock_bh() (”…”�”}”(hjþh²hh³Nh´NubjI)�”}”(hŒ``include/linux/spinlock.h``”h]”hŒinclude/linux/spinlock.h”…”�”}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jHhjþubhX) is used. It disables softirqs on that CPU, then grabs the lock. spin_unlock_bh() does the reverse. (The ‘_bh’ suffix is a historical reference to “Bottom Halvesâ€�, the old name for software interrupts. It should really be called spin_lock_softirq()’ in a perfect world).”…”�”}”(hjþh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´K¤hjíh²hubhú)�”}”(hŒˆNote that you can also use spin_lock_irq() or spin_lock_irqsave() here, which stop hardware interrupts as well: see `Hard IRQ Context`_.”h]”(hŒtNote that you can also use spin_lock_irq() or spin_lock_irqsave() here, which stop hardware interrupts as well: see ”…”�”}”(hjh²hh³Nh´Nubj})�”}”(hŒ`Hard IRQ Context`_”h]”hŒHard IRQ Context”…”�”}”(hj&h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”Œname”ŒHard IRQ Context”hÁŒhard-irq-context”uh1j|hjj�KubhŒ.”…”�”}”(hjh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´K®hjíh²hubhú)�”}”(hŒ½This works perfectly for UP as well: the spin lock vanishes, and this macro simply becomes local_bh_disable() (``include/linux/interrupt.h``), which protects you from the softirq being run.”h]”(hŒoThis works perfectly for UP as well: the spin lock vanishes, and this macro simply becomes local_bh_disable() (”…”�”}”(hjAh²hh³Nh´NubjI)�”}”(hŒ``include/linux/interrupt.h``”h]”hŒinclude/linux/interrupt.h”…”�”}”(hjIh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jHhjAubhŒ1), which protects you from the softirq being run.”…”�”}”(hjAh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´K²hjíh²hubeh}”(h]”Œ)locking-between-user-context-and-softirqs”ah ]”h"]”Œ)locking between user context and softirqs”ah$]”h&]”uh1hÄhjîh²hh³hÃh´K¢ubhÅ)�”}”(hhh]”(hÊ)�”}”(hŒ)Locking Between User Context and Tasklets”h]”hŒ)Locking Between User Context and Tasklets”…”�”}”(hjlh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÉhjih²hh³hÃh´K¸ubhú)�”}”(hŒTThis is exactly the same as above, because tasklets are actually run from a softirq.”h]”hŒTThis is exactly the same as above, because tasklets are actually run from a softirq.”…”�”}”(hjzh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´Kºhjih²hubeh}”(h]”Œ)locking-between-user-context-and-tasklets”ah ]”h"]”Œ)locking between user context and tasklets”ah$]”h&]”uh1hÄhjîh²hh³hÃh´K¸ubhÅ)�”}”(hhh]”(hÊ)�”}”(hŒ'Locking Between User Context and Timers”h]”hŒ'Locking Between User Context and Timers”…”�”}”(hj“h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÉhj�h²hh³hÃh´K¾ubhú)�”}”(hŒ™This, too, is exactly the same as above, because timers are actually run from a softirq. From a locking point of view, tasklets and timers are identical.”h]”hŒ™This, too, is exactly the same as above, because timers are actually run from a softirq. From a locking point of view, tasklets and timers are identical.”…”�”}”(hj¡h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´KÀhj�h²hubeh}”(h]”Œ'locking-between-user-context-and-timers”ah ]”h"]”Œ'locking between user context and timers”ah$]”h&]”uh1hÄhjîh²hh³hÃh´K¾ubhÅ)�”}”(hhh]”(hÊ)�”}”(hŒLocking Between Tasklets/Timers”h]”hŒLocking Between Tasklets/Timers”…”�”}”(hjºh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÉhj·h²hh³hÃh´KÅubhú)�”}”(hŒTSometimes a tasklet or timer might want to share data with another tasklet or timer.”h]”hŒTSometimes a tasklet or timer might want to share data with another tasklet or timer.”…”�”}”(hjÈh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´KÇhj·h²hubhÅ)�”}”(hhh]”(hÊ)�”}”(hŒThe Same Tasklet/Timer”h]”hŒThe Same Tasklet/Timer”…”�”}”(hjÙh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÉhjÖh²hh³hÃh´KËubhú)�”}”(hŒ’Since a tasklet is never run on two CPUs at once, you don't need to worry about your tasklet being reentrant (running twice at once), even on SMP.”h]”hŒ”Since a tasklet is never run on two CPUs at once, you don’t need to worry about your tasklet being reentrant (running twice at once), even on SMP.”…”�”}”(hjçh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´KÍhjÖh²hubeh}”(h]”Œthe-same-tasklet-timer”ah ]”h"]”Œthe same tasklet/timer”ah$]”h&]”uh1hÄhj·h²hh³hÃh´KËubhÅ)�”}”(hhh]”(hÊ)�”}”(hŒDifferent Tasklets/Timers”h]”hŒDifferent Tasklets/Timers”…”�”}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÉhjýh²hh³hÃh´KÒubhú)�”}”(hŒóIf another tasklet/timer wants to share data with your tasklet or timer , you will both need to use spin_lock() and spin_unlock() calls. spin_lock_bh() is unnecessary here, as you are already in a tasklet, and none will be run on the same CPU.”h]”hŒóIf another tasklet/timer wants to share data with your tasklet or timer , you will both need to use spin_lock() and spin_unlock() calls. spin_lock_bh() is unnecessary here, as you are already in a tasklet, and none will be run on the same CPU.”…”�”}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´KÔhjýh²hubeh}”(h]”Œdifferent-tasklets-timers”ah ]”h"]”Œdifferent tasklets/timers”ah$]”h&]”uh1hÄhj·h²hh³hÃh´KÒubeh}”(h]”Œlocking-between-tasklets-timers”ah ]”h"]”Œlocking between tasklets/timers”ah$]”h&]”uh1hÄhjîh²hh³hÃh´KÅubhÅ)�”}”(hhh]”(hÊ)�”}”(hŒLocking Between Softirqs”h]”hŒLocking Between Softirqs”…”�”}”(hj/h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÉhj,h²hh³hÃh´KÛubhú)�”}”(hŒHOften a softirq might want to share data with itself or a tasklet/timer.”h]”hŒHOften a softirq might want to share data with itself or a tasklet/timer.”…”�”}”(hj=h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´KÝhj,h²hubhÅ)�”}”(hhh]”(hÊ)�”}”(hŒThe Same Softirq”h]”hŒThe Same Softirq”…”�”}”(hjNh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÉhjKh²hh³hÃh´Kàubhú)�”}”(hŒöThe same softirq can run on the other CPUs: you can use a per-CPU array (see `Per-CPU Data`_) for better performance. If you're going so far as to use a softirq, you probably care about scalable performance enough to justify the extra complexity.”h]”(hŒMThe same softirq can run on the other CPUs: you can use a per-CPU array (see ”…”�”}”(hj\h²hh³Nh´Nubj})�”}”(hŒ`Per-CPU Data`_”h]”hŒ Per-CPU Data”…”�”}”(hjdh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”Œname”Œ Per-CPU Data”hÁŒ per-cpu-data”uh1j|hj\j�KubhŒœ) for better performance. If you’re going so far as to use a softirq, you probably care about scalable performance enough to justify the extra complexity.”…”�”}”(hj\h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´KâhjKh²hubhú)�”}”(hŒAYou'll need to use spin_lock() and spin_unlock() for shared data.”h]”hŒCYou’ll need to use spin_lock() and spin_unlock() for shared data.”…”�”}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´KçhjKh²hubeh}”(h]”Œthe-same-softirq”ah ]”h"]”Œthe same softirq”ah$]”h&]”uh1hÄhj,h²hh³hÃh´KàubhÅ)�”}”(hhh]”(hÊ)�”}”(hŒDifferent Softirqs”h]”hŒDifferent Softirqs”…”�”}”(hj˜h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÉhj•h²hh³hÃh´Këubhú)�”}”(hŒÄYou'll need to use spin_lock() and spin_unlock() for shared data, whether it be a timer, tasklet, different softirq or the same or another softirq: any of them could be running on a different CPU.”h]”hŒÆYou’ll need to use spin_lock() and spin_unlock() for shared data, whether it be a timer, tasklet, different softirq or the same or another softirq: any of them could be running on a different CPU.”…”�”}”(hj¦h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´Kíhj•h²hubeh}”(h]”Œdifferent-softirqs”ah ]”h"]”Œdifferent softirqs”ah$]”h&]”uh1hÄhj,h²hh³hÃh´Këubeh}”(h]”Œlocking-between-softirqs”ah ]”h"]”Œlocking between softirqs”ah$]”h&]”uh1hÄhjîh²hh³hÃh´KÛubeh}”(h]”Œlocking-in-the-linux-kernel”ah ]”h"]”Œlocking in the linux kernel”ah$]”h&]”uh1hÄhhÆh²hh³hÃh´K_ubhÅ)�”}”(hhh]”(hÊ)�”}”(hŒHard IRQ Context”h]”hŒHard IRQ Context”…”�”}”(hjÏh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÉhjÌh²hh³hÃh´Kóubhú)�”}”(hŒ•Hardware interrupts usually communicate with a tasklet or softirq. Frequently this involves putting work in a queue, which the softirq will take out.”h]”hŒ•Hardware interrupts usually communicate with a tasklet or softirq. Frequently this involves putting work in a queue, which the softirq will take out.”…”�”}”(hjÝh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´KõhjÌh²hubhÅ)�”}”(hhh]”(hÊ)�”}”(hŒ.Locking Between Hard IRQ and Softirqs/Tasklets”h]”hŒ.Locking Between Hard IRQ and Softirqs/Tasklets”…”�”}”(hjîh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÉhjëh²hh³hÃh´Kúubhú)�”}”(hXƒIf a hardware irq handler shares data with a softirq, you have two concerns. Firstly, the softirq processing can be interrupted by a hardware interrupt, and secondly, the critical region could be entered by a hardware interrupt on another CPU. This is where spin_lock_irq() is used. It is defined to disable interrupts on that cpu, then grab the lock. spin_unlock_irq() does the reverse.”h]”hXƒIf a hardware irq handler shares data with a softirq, you have two concerns. Firstly, the softirq processing can be interrupted by a hardware interrupt, and secondly, the critical region could be entered by a hardware interrupt on another CPU. This is where spin_lock_irq() is used. It is defined to disable interrupts on that cpu, then grab the lock. spin_unlock_irq() does the reverse.”…”�”}”(hjüh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´Kühjëh²hubhú)�”}”(hX1The irq handler does not need to use spin_lock_irq(), because the softirq cannot run while the irq handler is running: it can use spin_lock(), which is slightly faster. The only exception would be if a different hardware irq handler uses the same lock: spin_lock_irq() will stop that from interrupting us.”h]”hX1The irq handler does not need to use spin_lock_irq(), because the softirq cannot run while the irq handler is running: it can use spin_lock(), which is slightly faster. The only exception would be if a different hardware irq handler uses the same lock: spin_lock_irq() will stop that from interrupting us.”…”�”}”(hj h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´Mhjëh²hubhú)�”}”(hŒÁThis works perfectly for UP as well: the spin lock vanishes, and this macro simply becomes local_irq_disable() (``include/asm/smp.h``), which protects you from the softirq/tasklet/BH being run.”h]”(hŒpThis works perfectly for UP as well: the spin lock vanishes, and this macro simply becomes local_irq_disable() (”…”�”}”(hj h²hh³Nh´NubjI)�”}”(hŒ``include/asm/smp.h``”h]”hŒinclude/asm/smp.h”…”�”}”(hj h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jHhj ubhŒ<), which protects you from the softirq/tasklet/BH being run.”…”�”}”(hj h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´M hjëh²hubhú)�”}”(hXJspin_lock_irqsave() (``include/linux/spinlock.h``) is a variant which saves whether interrupts were on or off in a flags word, which is passed to spin_unlock_irqrestore(). This means that the same code can be used inside an hard irq handler (where interrupts are already off) and in softirqs (where the irq disabling is required).”h]”(hŒspin_lock_irqsave() (”…”�”}”(hj8 h²hh³Nh´NubjI)�”}”(hŒ``include/linux/spinlock.h``”h]”hŒinclude/linux/spinlock.h”…”�”}”(hj@ h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jHhj8 ubhX) is a variant which saves whether interrupts were on or off in a flags word, which is passed to spin_unlock_irqrestore(). This means that the same code can be used inside an hard irq handler (where interrupts are already off) and in softirqs (where the irq disabling is required).”…”�”}”(hj8 h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´Mhjëh²hubhú)�”}”(hŒÙNote that softirqs (and hence tasklets and timers) are run on return from hardware interrupts, so spin_lock_irq() also stops these. In that sense, spin_lock_irqsave() is the most general and powerful locking function.”h]”hŒÙNote that softirqs (and hence tasklets and timers) are run on return from hardware interrupts, so spin_lock_irq() also stops these. In that sense, spin_lock_irqsave() is the most general and powerful locking function.”…”�”}”(hjX h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´Mhjëh²hubeh}”(h]”Œ.locking-between-hard-irq-and-softirqs-tasklets”ah ]”h"]”Œ.locking between hard irq and softirqs/tasklets”ah$]”h&]”uh1hÄhjÌh²hh³hÃh´KúubhÅ)�”}”(hhh]”(hÊ)�”}”(hŒ%Locking Between Two Hard IRQ Handlers”h]”hŒ%Locking Between Two Hard IRQ Handlers”…”�”}”(hjq h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÉhjn h²hh³hÃh´Mubhú)�”}”(hŒÍIt is rare to have to share data between two IRQ handlers, but if you do, spin_lock_irqsave() should be used: it is architecture-specific whether all interrupts are disabled inside irq handlers themselves.”h]”hŒÍIt is rare to have to share data between two IRQ handlers, but if you do, spin_lock_irqsave() should be used: it is architecture-specific whether all interrupts are disabled inside irq handlers themselves.”…”�”}”(hj h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´Mhjn h²hubeh}”(h]”Œ%locking-between-two-hard-irq-handlers”ah ]”h"]”Œ%locking between two hard irq handlers”ah$]”h&]”uh1hÄhjÌh²hh³hÃh´Mubeh}”(h]”j6ah ]”h"]”Œhard irq context”ah$]”h&]”uh1hÄhhÆh²hh³hÃh´KóŒ referenced”KubhÅ)�”}”(hhh]”(hÊ)�”}”(hŒCheat Sheet For Locking”h]”hŒCheat Sheet For Locking”…”�”}”(hj  h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÉhj� h²hh³hÃh´M$ubhú)�”}”(hŒ)Pete Zaitcev gives the following summary:”h]”hŒ)Pete Zaitcev gives the following summary:”…”�”}”(hj® h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´M&hj� h²hubhŒ bullet_list”“”)�”}”(hhh]”(hŒ list_item”“”)�”}”(hŒ³If you are in a process context (any syscall) and want to lock other process out, use a mutex. You can take a mutex and sleep (``copy_from_user()`` or ``kmalloc(x,GFP_KERNEL)``). ”h]”hú)�”}”(hŒ²If you are in a process context (any syscall) and want to lock other process out, use a mutex. You can take a mutex and sleep (``copy_from_user()`` or ``kmalloc(x,GFP_KERNEL)``).”h]”(hŒIf you are in a process context (any syscall) and want to lock other process out, use a mutex. You can take a mutex and sleep (”…”�”}”(hjÇ h²hh³Nh´NubjI)�”}”(hŒ``copy_from_user()``”h]”hŒcopy_from_user()”…”�”}”(hjÏ h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jHhjÇ ubhŒ or ”…”�”}”(hjÇ h²hh³Nh´NubjI)�”}”(hŒ``kmalloc(x,GFP_KERNEL)``”h]”hŒkmalloc(x,GFP_KERNEL)”…”�”}”(hjá h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jHhjÇ ubhŒ).”…”�”}”(hjÇ h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´M(hjà ubah}”(h]”h ]”h"]”h$]”h&]”uh1jÁ hj¾ h²hh³hÃh´Nubj )�”}”(hŒjOtherwise (== data can be touched in an interrupt), use spin_lock_irqsave() and spin_unlock_irqrestore(). ”h]”hú)�”}”(hŒiOtherwise (== data can be touched in an interrupt), use spin_lock_irqsave() and spin_unlock_irqrestore().”h]”hŒiOtherwise (== data can be touched in an interrupt), use spin_lock_irqsave() and spin_unlock_irqrestore().”…”�”}”(hj h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´M,hjÿ ubah}”(h]”h ]”h"]”h$]”h&]”uh1jÁ hj¾ h²hh³hÃh´Nubj )�”}”(hŒsAvoid holding spinlock for more than 5 lines of code and across any function call (except accessors like readb()). ”h]”hú)�”}”(hŒrAvoid holding spinlock for more than 5 lines of code and across any function call (except accessors like readb()).”h]”hŒrAvoid holding spinlock for more than 5 lines of code and across any function call (except accessors like readb()).”…”�”}”(hj h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´M0hj ubah}”(h]”h ]”h"]”h$]”h&]”uh1jÁ hj¾ h²hh³hÃh´Nubeh}”(h]”h ]”h"]”h$]”h&]”Œbullet”Œ-”uh1j¼ h³hÃh´M(hj� h²hubhÅ)�”}”(hhh]”(hÊ)�”}”(hŒTable of Minimum Requirements”h]”hŒTable of Minimum Requirements”…”�”}”(hj: h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÉhj7 h²hh³hÃh´M4ubhú)�”}”(hXPThe following table lists the **minimum** locking requirements between various contexts. In some cases, the same context can only be running on one CPU at a time, so no locking is required for that context (eg. a particular thread can only run on one CPU at a time, but if it needs shares data with another thread, locking is required).”h]”(hŒThe following table lists the ”…”�”}”(hjH h²hh³Nh´Nubj)�”}”(hŒ **minimum**”h]”hŒminimum”…”�”}”(hjP h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhjH ubhX' locking requirements between various contexts. In some cases, the same context can only be running on one CPU at a time, so no locking is required for that context (eg. a particular thread can only run on one CPU at a time, but if it needs shares data with another thread, locking is required).”…”�”}”(hjH h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´M6hj7 h²hubhú)�”}”(hŒxRemember the advice above: you can always use spin_lock_irqsave(), which is a superset of all other spinlock primitives.”h]”hŒxRemember the advice above: you can always use spin_lock_irqsave(), which is a superset of all other spinlock primitives.”…”�”}”(hjh h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´M<hj7 h²hubjž)�”}”(hhh]”j±)�”}”(hhh]”(j¶)�”}”(hhh]”h}”(h]”h ]”h"]”h$]”h&]”Œcolwidth”Kuh1jµhjy ubj¶)�”}”(hhh]”h}”(h]”h ]”h"]”h$]”h&]”Œcolwidth”K uh1jµhjy ubj¶)�”}”(hhh]”h}”(h]”h ]”h"]”h$]”h&]”Œcolwidth”K uh1jµhjy ubj¶)�”}”(hhh]”h}”(h]”h ]”h"]”h$]”h&]”Œcolwidth”K uh1jµhjy ubj¶)�”}”(hhh]”h}”(h]”h ]”h"]”h$]”h&]”Œcolwidth”K uh1jµhjy ubj¶)�”}”(hhh]”h}”(h]”h ]”h"]”h$]”h&]”Œcolwidth”K uh1jµhjy ubj¶)�”}”(hhh]”h}”(h]”h ]”h"]”h$]”h&]”Œcolwidth”K uh1jµhjy ubj¶)�”}”(hhh]”h}”(h]”h ]”h"]”h$]”h&]”Œcolwidth”Kuh1jµhjy ubj¶)�”}”(hhh]”h}”(h]”h ]”h"]”h$]”h&]”Œcolwidth”Kuh1jµhjy ubj¶)�”}”(hhh]”h}”(h]”h ]”h"]”h$]”h&]”Œcolwidth”Kuh1jµhjy ubj¶)�”}”(hhh]”h}”(h]”h ]”h"]”h$]”h&]”Œcolwidth”Kuh1jµhjy ubjÌ)�”}”(hhh]”jÑ)�”}”(hhh]”(jÖ)�”}”(hhh]”hú)�”}”(hŒ.”h]”hŒ.”…”�”}”(hjó h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´MAhjð ubah}”(h]”h ]”h"]”h$]”h&]”uh1jÕhjí ubjÖ)�”}”(hhh]”hú)�”}”(hŒ IRQ Handler A”h]”hŒ IRQ Handler A”…”�”}”(hj h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´MAhj ubah}”(h]”h ]”h"]”h$]”h&]”uh1jÕhjí ubjÖ)�”}”(hhh]”hú)�”}”(hŒ IRQ Handler B”h]”hŒ IRQ Handler B”…”�”}”(hj! h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´MAhj ubah}”(h]”h ]”h"]”h$]”h&]”uh1jÕhjí ubjÖ)�”}”(hhh]”hú)�”}”(hŒ Softirq A”h]”hŒ Softirq A”…”�”}”(hj8 h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´MAhj5 ubah}”(h]”h ]”h"]”h$]”h&]”uh1jÕhjí ubjÖ)�”}”(hhh]”hú)�”}”(hŒ Softirq B”h]”hŒ Softirq B”…”�”}”(hjO h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´MAhjL ubah}”(h]”h ]”h"]”h$]”h&]”uh1jÕhjí ubjÖ)�”}”(hhh]”hú)�”}”(hŒ Tasklet A”h]”hŒ Tasklet A”…”�”}”(hjf h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´MAhjc ubah}”(h]”h ]”h"]”h$]”h&]”uh1jÕhjí ubjÖ)�”}”(hhh]”hú)�”}”(hŒ Tasklet B”h]”hŒ Tasklet B”…”�”}”(hj} h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´MAhjz ubah}”(h]”h ]”h"]”h$]”h&]”uh1jÕhjí ubjÖ)�”}”(hhh]”hú)�”}”(hŒTimer A”h]”hŒTimer A”…”�”}”(hj” h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´MAhj‘ ubah}”(h]”h ]”h"]”h$]”h&]”uh1jÕhjí ubjÖ)�”}”(hhh]”hú)�”}”(hŒTimer B”h]”hŒTimer B”…”�”}”(hj« h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´MAhj¨ ubah}”(h]”h ]”h"]”h$]”h&]”uh1jÕhjí ubjÖ)�”}”(hhh]”hú)�”}”(hŒUser Context A”h]”hŒUser Context A”…”�”}”(hj h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´MAhj¿ ubah}”(h]”h ]”h"]”h$]”h&]”uh1jÕhjí ubjÖ)�”}”(hhh]”hú)�”}”(hŒUser Context B”h]”hŒUser Context B”…”�”}”(hjÙ h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´MAhjÖ ubah}”(h]”h ]”h"]”h$]”h&]”uh1jÕhjí ubeh}”(h]”h ]”h"]”h$]”h&]”uh1jÐhjê ubah}”(h]”h ]”h"]”h$]”h&]”uh1jËhjy ubj)�”}”(hhh]”(jÑ)�”}”(hhh]”(jÖ)�”}”(hhh]”hú)�”}”(hŒ IRQ Handler A”h]”hŒ IRQ Handler A”…”�”}”(hj h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´MChjÿ ubah}”(h]”h ]”h"]”h$]”h&]”uh1jÕhjü ubjÖ)�”}”(hhh]”hú)�”}”(hŒNone”h]”hŒNone”…”�”}”(hj h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´MChj ubah}”(h]”h ]”h"]”h$]”h&]”uh1jÕhjü ubjÖ)�”}”(hhh]”h}”(h]”h ]”h"]”h$]”h&]”uh1jÕhjü ubjÖ)�”}”(hhh]”h}”(h]”h ]”h"]”h$]”h&]”uh1jÕhjü ubjÖ)�”}”(hhh]”h}”(h]”h ]”h"]”h$]”h&]”uh1jÕhjü ubjÖ)�”}”(hhh]”h}”(h]”h ]”h"]”h$]”h&]”uh1jÕhjü ubjÖ)�”}”(hhh]”h}”(h]”h ]”h"]”h$]”h&]”uh1jÕhjü ubjÖ)�”}”(hhh]”h}”(h]”h ]”h"]”h$]”h&]”uh1jÕhjü ubjÖ)�”}”(hhh]”h}”(h]”h ]”h"]”h$]”h&]”uh1jÕhjü ubjÖ)�”}”(hhh]”h}”(h]”h ]”h"]”h$]”h&]”uh1jÕhjü ubjÖ)�”}”(hhh]”h}”(h]”h ]”h"]”h$]”h&]”uh1jÕhjü ubeh}”(h]”h ]”h"]”h$]”h&]”uh1jÐhjù ubjÑ)�”}”(hhh]”(jÖ)�”}”(hhh]”hú)�”}”(hŒ IRQ Handler B”h]”hŒ IRQ Handler B”…”�”}”(hjŠ h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´MDhj‡ ubah}”(h]”h ]”h"]”h$]”h&]”uh1jÕhj„ ubjÖ)�”}”(hhh]”hú)�”}”(hŒSLIS”h]”hŒSLIS”…”�”}”(hj¡ h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´MDhjž ubah}”(h]”h ]”h"]”h$]”h&]”uh1jÕhj„ ubjÖ)�”}”(hhh]”hú)�”}”(hŒNone”h]”hŒNone”…”�”}”(hj¸ h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´MDhjµ ubah}”(h]”h ]”h"]”h$]”h&]”uh1jÕhj„ ubjÖ)�”}”(hhh]”h}”(h]”h ]”h"]”h$]”h&]”uh1jÕhj„ ubjÖ)�”}”(hhh]”h}”(h]”h ]”h"]”h$]”h&]”uh1jÕhj„ ubjÖ)�”}”(hhh]”h}”(h]”h ]”h"]”h$]”h&]”uh1jÕhj„ ubjÖ)�”}”(hhh]”h}”(h]”h ]”h"]”h$]”h&]”uh1jÕhj„ ubjÖ)�”}”(hhh]”h}”(h]”h ]”h"]”h$]”h&]”uh1jÕhj„ ubjÖ)�”}”(hhh]”h}”(h]”h ]”h"]”h$]”h&]”uh1jÕhj„ ubjÖ)�”}”(hhh]”h}”(h]”h ]”h"]”h$]”h&]”uh1jÕhj„ ubjÖ)�”}”(hhh]”h}”(h]”h ]”h"]”h$]”h&]”uh1jÕhj„ ubeh}”(h]”h ]”h"]”h$]”h&]”uh1jÐhjù ubjÑ)�”}”(hhh]”(jÖ)�”}”(hhh]”hú)�”}”(hŒ Softirq A”h]”hŒ Softirq A”…”�”}”(hj h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´MEhj ubah}”(h]”h ]”h"]”h$]”h&]”uh1jÕhj ubjÖ)�”}”(hhh]”hú)�”}”(hŒSLI”h]”hŒSLI”…”�”}”(hj7 h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´MEhj4 ubah}”(h]”h ]”h"]”h$]”h&]”uh1jÕhj ubjÖ)�”}”(hhh]”hú)�”}”(hŒSLI”h]”hŒSLI”…”�”}”(hjN h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´MEhjK ubah}”(h]”h ]”h"]”h$]”h&]”uh1jÕhj ubjÖ)�”}”(hhh]”hú)�”}”(hŒSL”h]”hŒSL”…”�”}”(hje h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´MEhjb ubah}”(h]”h ]”h"]”h$]”h&]”uh1jÕhj ubjÖ)�”}”(hhh]”h}”(h]”h ]”h"]”h$]”h&]”uh1jÕhj ubjÖ)�”}”(hhh]”h}”(h]”h ]”h"]”h$]”h&]”uh1jÕhj ubjÖ)�”}”(hhh]”h}”(h]”h ]”h"]”h$]”h&]”uh1jÕhj ubjÖ)�”}”(hhh]”h}”(h]”h ]”h"]”h$]”h&]”uh1jÕhj ubjÖ)�”}”(hhh]”h}”(h]”h ]”h"]”h$]”h&]”uh1jÕhj ubjÖ)�”}”(hhh]”h}”(h]”h ]”h"]”h$]”h&]”uh1jÕhj ubjÖ)�”}”(hhh]”h}”(h]”h ]”h"]”h$]”h&]”uh1jÕhj ubeh}”(h]”h ]”h"]”h$]”h&]”uh1jÐhjù ubjÑ)�”}”(hhh]”(jÖ)�”}”(hhh]”hú)�”}”(hŒ Softirq B”h]”hŒ Softirq B”…”�”}”(hjÄ h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´MFhjÁ ubah}”(h]”h ]”h"]”h$]”h&]”uh1jÕhj¾ ubjÖ)�”}”(hhh]”hú)�”}”(hŒSLI”h]”hŒSLI”…”�”}”(hjÛ h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´MFhjØ ubah}”(h]”h ]”h"]”h$]”h&]”uh1jÕhj¾ ubjÖ)�”}”(hhh]”hú)�”}”(hŒSLI”h]”hŒSLI”…”�”}”(hjò h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´MFhjï ubah}”(h]”h ]”h"]”h$]”h&]”uh1jÕhj¾ ubjÖ)�”}”(hhh]”hú)�”}”(hŒSL”h]”hŒSL”…”�”}”(hj h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´MFhjubah}”(h]”h ]”h"]”h$]”h&]”uh1jÕhj¾ ubjÖ)�”}”(hhh]”hú)�”}”(hŒSL”h]”hŒSL”…”�”}”(hj h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´MFhjubah}”(h]”h ]”h"]”h$]”h&]”uh1jÕhj¾ ubjÖ)�”}”(hhh]”h}”(h]”h ]”h"]”h$]”h&]”uh1jÕhj¾ ubjÖ)�”}”(hhh]”h}”(h]”h ]”h"]”h$]”h&]”uh1jÕhj¾ ubjÖ)�”}”(hhh]”h}”(h]”h ]”h"]”h$]”h&]”uh1jÕhj¾ ubjÖ)�”}”(hhh]”h}”(h]”h ]”h"]”h$]”h&]”uh1jÕhj¾ ubjÖ)�”}”(hhh]”h}”(h]”h ]”h"]”h$]”h&]”uh1jÕhj¾ ubjÖ)�”}”(hhh]”h}”(h]”h ]”h"]”h$]”h&]”uh1jÕhj¾ ubeh}”(h]”h ]”h"]”h$]”h&]”uh1jÐhjù ubjÑ)�”}”(hhh]”(jÖ)�”}”(hhh]”hú)�”}”(hŒ Tasklet A”h]”hŒ Tasklet A”…”�”}”(hjvh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´MGhjsubah}”(h]”h ]”h"]”h$]”h&]”uh1jÕhjpubjÖ)�”}”(hhh]”hú)�”}”(hŒSLI”h]”hŒSLI”…”�”}”(hj�h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´MGhjŠubah}”(h]”h ]”h"]”h$]”h&]”uh1jÕhjpubjÖ)�”}”(hhh]”hú)�”}”(hŒSLI”h]”hŒSLI”…”�”}”(hj¤h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´MGhj¡ubah}”(h]”h ]”h"]”h$]”h&]”uh1jÕhjpubjÖ)�”}”(hhh]”hú)�”}”(hŒSL”h]”hŒSL”…”�”}”(hj»h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´MGhj¸ubah}”(h]”h ]”h"]”h$]”h&]”uh1jÕhjpubjÖ)�”}”(hhh]”hú)�”}”(hŒSL”h]”hŒSL”…”�”}”(hjÒh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´MGhjÏubah}”(h]”h ]”h"]”h$]”h&]”uh1jÕhjpubjÖ)�”}”(hhh]”hú)�”}”(hŒNone”h]”hŒNone”…”�”}”(hjéh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´MGhjæubah}”(h]”h ]”h"]”h$]”h&]”uh1jÕhjpubjÖ)�”}”(hhh]”h}”(h]”h ]”h"]”h$]”h&]”uh1jÕhjpubjÖ)�”}”(hhh]”h}”(h]”h ]”h"]”h$]”h&]”uh1jÕhjpubjÖ)�”}”(hhh]”h}”(h]”h ]”h"]”h$]”h&]”uh1jÕhjpubjÖ)�”}”(hhh]”h}”(h]”h ]”h"]”h$]”h&]”uh1jÕhjpubjÖ)�”}”(hhh]”h}”(h]”h ]”h"]”h$]”h&]”uh1jÕhjpubeh}”(h]”h ]”h"]”h$]”h&]”uh1jÐhjù ubjÑ)�”}”(hhh]”(jÖ)�”}”(hhh]”hú)�”}”(hŒ Tasklet B”h]”hŒ Tasklet B”…”�”}”(hj6h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´MHhj3ubah}”(h]”h ]”h"]”h$]”h&]”uh1jÕhj0ubjÖ)�”}”(hhh]”hú)�”}”(hŒSLI”h]”hŒSLI”…”�”}”(hjMh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´MHhjJubah}”(h]”h ]”h"]”h$]”h&]”uh1jÕhj0ubjÖ)�”}”(hhh]”hú)�”}”(hŒSLI”h]”hŒSLI”…”�”}”(hjdh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´MHhjaubah}”(h]”h ]”h"]”h$]”h&]”uh1jÕhj0ubjÖ)�”}”(hhh]”hú)�”}”(hŒSL”h]”hŒSL”…”�”}”(hj{h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´MHhjxubah}”(h]”h ]”h"]”h$]”h&]”uh1jÕhj0ubjÖ)�”}”(hhh]”hú)�”}”(hŒSL”h]”hŒSL”…”�”}”(hj’h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´MHhj�ubah}”(h]”h ]”h"]”h$]”h&]”uh1jÕhj0ubjÖ)�”}”(hhh]”hú)�”}”(hŒSL”h]”hŒSL”…”�”}”(hj©h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´MHhj¦ubah}”(h]”h ]”h"]”h$]”h&]”uh1jÕhj0ubjÖ)�”}”(hhh]”hú)�”}”(hŒNone”h]”hŒNone”…”�”}”(hjÀh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´MHhj½ubah}”(h]”h ]”h"]”h$]”h&]”uh1jÕhj0ubjÖ)�”}”(hhh]”h}”(h]”h ]”h"]”h$]”h&]”uh1jÕhj0ubjÖ)�”}”(hhh]”h}”(h]”h ]”h"]”h$]”h&]”uh1jÕhj0ubjÖ)�”}”(hhh]”h}”(h]”h ]”h"]”h$]”h&]”uh1jÕhj0ubjÖ)�”}”(hhh]”h}”(h]”h ]”h"]”h$]”h&]”uh1jÕhj0ubeh}”(h]”h ]”h"]”h$]”h&]”uh1jÐhjù ubjÑ)�”}”(hhh]”(jÖ)�”}”(hhh]”hú)�”}”(hŒTimer A”h]”hŒTimer A”…”�”}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´MIhjubah}”(h]”h ]”h"]”h$]”h&]”uh1jÕhjþubjÖ)�”}”(hhh]”hú)�”}”(hŒSLI”h]”hŒSLI”…”�”}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´MIhjubah}”(h]”h ]”h"]”h$]”h&]”uh1jÕhjþubjÖ)�”}”(hhh]”hú)�”}”(hŒSLI”h]”hŒSLI”…”�”}”(hj2h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´MIhj/ubah}”(h]”h ]”h"]”h$]”h&]”uh1jÕhjþubjÖ)�”}”(hhh]”hú)�”}”(hŒSL”h]”hŒSL”…”�”}”(hjIh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´MIhjFubah}”(h]”h ]”h"]”h$]”h&]”uh1jÕhjþubjÖ)�”}”(hhh]”hú)�”}”(hŒSL”h]”hŒSL”…”�”}”(hj`h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´MIhj]ubah}”(h]”h ]”h"]”h$]”h&]”uh1jÕhjþubjÖ)�”}”(hhh]”hú)�”}”(hŒSL”h]”hŒSL”…”�”}”(hjwh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´MIhjtubah}”(h]”h ]”h"]”h$]”h&]”uh1jÕhjþubjÖ)�”}”(hhh]”hú)�”}”(hŒSL”h]”hŒSL”…”�”}”(hjŽh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´MIhj‹ubah}”(h]”h ]”h"]”h$]”h&]”uh1jÕhjþubjÖ)�”}”(hhh]”hú)�”}”(hŒNone”h]”hŒNone”…”�”}”(hj¥h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´MIhj¢ubah}”(h]”h ]”h"]”h$]”h&]”uh1jÕhjþubjÖ)�”}”(hhh]”h}”(h]”h ]”h"]”h$]”h&]”uh1jÕhjþubjÖ)�”}”(hhh]”h}”(h]”h ]”h"]”h$]”h&]”uh1jÕhjþubjÖ)�”}”(hhh]”h}”(h]”h ]”h"]”h$]”h&]”uh1jÕhjþubeh}”(h]”h ]”h"]”h$]”h&]”uh1jÐhjù ubjÑ)�”}”(hhh]”(jÖ)�”}”(hhh]”hú)�”}”(hŒTimer B”h]”hŒTimer B”…”�”}”(hjàh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´MJhjÝubah}”(h]”h ]”h"]”h$]”h&]”uh1jÕhjÚubjÖ)�”}”(hhh]”hú)�”}”(hŒSLI”h]”hŒSLI”…”�”}”(hj÷h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´MJhjôubah}”(h]”h ]”h"]”h$]”h&]”uh1jÕhjÚubjÖ)�”}”(hhh]”hú)�”}”(hŒSLI”h]”hŒSLI”…”�”}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´MJhj ubah}”(h]”h ]”h"]”h$]”h&]”uh1jÕhjÚubjÖ)�”}”(hhh]”hú)�”}”(hŒSL”h]”hŒSL”…”�”}”(hj%h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´MJhj"ubah}”(h]”h ]”h"]”h$]”h&]”uh1jÕhjÚubjÖ)�”}”(hhh]”hú)�”}”(hŒSL”h]”hŒSL”…”�”}”(hj<h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´MJhj9ubah}”(h]”h ]”h"]”h$]”h&]”uh1jÕhjÚubjÖ)�”}”(hhh]”hú)�”}”(hŒSL”h]”hŒSL”…”�”}”(hjSh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´MJhjPubah}”(h]”h ]”h"]”h$]”h&]”uh1jÕhjÚubjÖ)�”}”(hhh]”hú)�”}”(hŒSL”h]”hŒSL”…”�”}”(hjjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´MJhjgubah}”(h]”h ]”h"]”h$]”h&]”uh1jÕhjÚubjÖ)�”}”(hhh]”hú)�”}”(hŒSL”h]”hŒSL”…”�”}”(hj�h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´MJhj~ubah}”(h]”h ]”h"]”h$]”h&]”uh1jÕhjÚubjÖ)�”}”(hhh]”hú)�”}”(hŒNone”h]”hŒNone”…”�”}”(hj˜h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´MJhj•ubah}”(h]”h ]”h"]”h$]”h&]”uh1jÕhjÚubjÖ)�”}”(hhh]”h}”(h]”h ]”h"]”h$]”h&]”uh1jÕhjÚubjÖ)�”}”(hhh]”h}”(h]”h ]”h"]”h$]”h&]”uh1jÕhjÚubeh}”(h]”h ]”h"]”h$]”h&]”uh1jÐhjù ubjÑ)�”}”(hhh]”(jÖ)�”}”(hhh]”hú)�”}”(hŒUser Context A”h]”hŒUser Context A”…”�”}”(hjÊh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´MKhjÇubah}”(h]”h ]”h"]”h$]”h&]”uh1jÕhjÄubjÖ)�”}”(hhh]”hú)�”}”(hŒSLI”h]”hŒSLI”…”�”}”(hjáh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´MKhjÞubah}”(h]”h ]”h"]”h$]”h&]”uh1jÕhjÄubjÖ)�”}”(hhh]”hú)�”}”(hŒSLI”h]”hŒSLI”…”�”}”(hjøh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´MKhjõubah}”(h]”h ]”h"]”h$]”h&]”uh1jÕhjÄubjÖ)�”}”(hhh]”hú)�”}”(hŒSLBH”h]”hŒSLBH”…”�”}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´MKhj ubah}”(h]”h ]”h"]”h$]”h&]”uh1jÕhjÄubjÖ)�”}”(hhh]”hú)�”}”(hŒSLBH”h]”hŒSLBH”…”�”}”(hj&h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´MKhj#ubah}”(h]”h ]”h"]”h$]”h&]”uh1jÕhjÄubjÖ)�”}”(hhh]”hú)�”}”(hŒSLBH”h]”hŒSLBH”…”�”}”(hj=h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´MKhj:ubah}”(h]”h ]”h"]”h$]”h&]”uh1jÕhjÄubjÖ)�”}”(hhh]”hú)�”}”(hŒSLBH”h]”hŒSLBH”…”�”}”(hjTh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´MKhjQubah}”(h]”h ]”h"]”h$]”h&]”uh1jÕhjÄubjÖ)�”}”(hhh]”hú)�”}”(hŒSLBH”h]”hŒSLBH”…”�”}”(hjkh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´MKhjhubah}”(h]”h ]”h"]”h$]”h&]”uh1jÕhjÄubjÖ)�”}”(hhh]”hú)�”}”(hŒSLBH”h]”hŒSLBH”…”�”}”(hj‚h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´MKhjubah}”(h]”h ]”h"]”h$]”h&]”uh1jÕhjÄubjÖ)�”}”(hhh]”hú)�”}”(hŒNone”h]”hŒNone”…”�”}”(hj™h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´MKhj–ubah}”(h]”h ]”h"]”h$]”h&]”uh1jÕhjÄubjÖ)�”}”(hhh]”h}”(h]”h ]”h"]”h$]”h&]”uh1jÕhjÄubeh}”(h]”h ]”h"]”h$]”h&]”uh1jÐhjù ubjÑ)�”}”(hhh]”(jÖ)�”}”(hhh]”hú)�”}”(hŒUser Context B”h]”hŒUser Context B”…”�”}”(hjÂh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´MLhj¿ubah}”(h]”h ]”h"]”h$]”h&]”uh1jÕhj¼ubjÖ)�”}”(hhh]”hú)�”}”(hŒSLI”h]”hŒSLI”…”�”}”(hjÙh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´MLhjÖubah}”(h]”h ]”h"]”h$]”h&]”uh1jÕhj¼ubjÖ)�”}”(hhh]”hú)�”}”(hŒSLI”h]”hŒSLI”…”�”}”(hjðh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´MLhjíubah}”(h]”h ]”h"]”h$]”h&]”uh1jÕhj¼ubjÖ)�”}”(hhh]”hú)�”}”(hŒSLBH”h]”hŒSLBH”…”�”}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´MLhjubah}”(h]”h ]”h"]”h$]”h&]”uh1jÕhj¼ubjÖ)�”}”(hhh]”hú)�”}”(hŒSLBH”h]”hŒSLBH”…”�”}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´MLhjubah}”(h]”h ]”h"]”h$]”h&]”uh1jÕhj¼ubjÖ)�”}”(hhh]”hú)�”}”(hŒSLBH”h]”hŒSLBH”…”�”}”(hj5h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´MLhj2ubah}”(h]”h ]”h"]”h$]”h&]”uh1jÕhj¼ubjÖ)�”}”(hhh]”hú)�”}”(hŒSLBH”h]”hŒSLBH”…”�”}”(hjLh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´MLhjIubah}”(h]”h ]”h"]”h$]”h&]”uh1jÕhj¼ubjÖ)�”}”(hhh]”hú)�”}”(hŒSLBH”h]”hŒSLBH”…”�”}”(hjch²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´MLhj`ubah}”(h]”h ]”h"]”h$]”h&]”uh1jÕhj¼ubjÖ)�”}”(hhh]”hú)�”}”(hŒSLBH”h]”hŒSLBH”…”�”}”(hjzh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´MLhjwubah}”(h]”h ]”h"]”h$]”h&]”uh1jÕhj¼ubjÖ)�”}”(hhh]”hú)�”}”(hŒMLI”h]”hŒMLI”…”�”}”(hj‘h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´MLhjŽubah}”(h]”h ]”h"]”h$]”h&]”uh1jÕhj¼ubjÖ)�”}”(hhh]”hú)�”}”(hŒNone”h]”hŒNone”…”�”}”(hj¨h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´MLhj¥ubah}”(h]”h ]”h"]”h$]”h&]”uh1jÕhj¼ubeh}”(h]”h ]”h"]”h$]”h&]”uh1jÐhjù ubeh}”(h]”h ]”h"]”h$]”h&]”uh1jhjy ubeh}”(h]”h ]”h"]”h$]”h&]”Œcols”K uh1j°hjv ubah}”(h]”h ]”h"]”h$]”h&]”uh1j�hj7 h²hh³hÃh´Nubhú)�”}”(hŒ$Table: Table of Locking Requirements”h]”hŒ$Table: Table of Locking Requirements”…”�”}”(hjÕh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´MOhj7 h²hubjž)�”}”(hhh]”j±)�”}”(hhh]”(j¶)�”}”(hhh]”h}”(h]”h ]”h"]”h$]”h&]”Œcolwidth”Kuh1jµhjæubj¶)�”}”(hhh]”h}”(h]”h ]”h"]”h$]”h&]”Œcolwidth”Kuh1jµhjæubj)�”}”(hhh]”(jÑ)�”}”(hhh]”(jÖ)�”}”(hhh]”hú)�”}”(hŒSLIS”h]”hŒSLIS”…”�”}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´MRhjubah}”(h]”h ]”h"]”h$]”h&]”uh1jÕhjubjÖ)�”}”(hhh]”hú)�”}”(hŒspin_lock_irqsave”h]”hŒspin_lock_irqsave”…”�”}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´MRhjubah}”(h]”h ]”h"]”h$]”h&]”uh1jÕhjubeh}”(h]”h ]”h"]”h$]”h&]”uh1jÐhjýubjÑ)�”}”(hhh]”(jÖ)�”}”(hhh]”hú)�”}”(hŒSLI”h]”hŒSLI”…”�”}”(hj=h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´MThj:ubah}”(h]”h ]”h"]”h$]”h&]”uh1jÕhj7ubjÖ)�”}”(hhh]”hú)�”}”(hŒ spin_lock_irq”h]”hŒ spin_lock_irq”…”�”}”(hjTh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´MThjQubah}”(h]”h ]”h"]”h$]”h&]”uh1jÕhj7ubeh}”(h]”h ]”h"]”h$]”h&]”uh1jÐhjýubjÑ)�”}”(hhh]”(jÖ)�”}”(hhh]”hú)�”}”(hŒSL”h]”hŒSL”…”�”}”(hjth²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´MVhjqubah}”(h]”h ]”h"]”h$]”h&]”uh1jÕhjnubjÖ)�”}”(hhh]”hú)�”}”(hŒ spin_lock”h]”hŒ spin_lock”…”�”}”(hj‹h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´MVhjˆubah}”(h]”h ]”h"]”h$]”h&]”uh1jÕhjnubeh}”(h]”h ]”h"]”h$]”h&]”uh1jÐhjýubjÑ)�”}”(hhh]”(jÖ)�”}”(hhh]”hú)�”}”(hŒSLBH”h]”hŒSLBH”…”�”}”(hj«h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´MXhj¨ubah}”(h]”h ]”h"]”h$]”h&]”uh1jÕhj¥ubjÖ)�”}”(hhh]”hú)�”}”(hŒ spin_lock_bh”h]”hŒ spin_lock_bh”…”�”}”(hjÂh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´MXhj¿ubah}”(h]”h ]”h"]”h$]”h&]”uh1jÕhj¥ubeh}”(h]”h ]”h"]”h$]”h&]”uh1jÐhjýubjÑ)�”}”(hhh]”(jÖ)�”}”(hhh]”hú)�”}”(hŒMLI”h]”hŒMLI”…”�”}”(hjâh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´MZhjßubah}”(h]”h ]”h"]”h$]”h&]”uh1jÕhjÜubjÖ)�”}”(hhh]”hú)�”}”(hŒmutex_lock_interruptible”h]”hŒmutex_lock_interruptible”…”�”}”(hjùh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´MZhjöubah}”(h]”h ]”h"]”h$]”h&]”uh1jÕhjÜubeh}”(h]”h ]”h"]”h$]”h&]”uh1jÐhjýubeh}”(h]”h ]”h"]”h$]”h&]”uh1jhjæubeh}”(h]”h ]”h"]”h$]”h&]”Œcols”Kuh1j°hjãubah}”(h]”h ]”h"]”h$]”h&]”uh1j�hj7 h²hh³hÃh´Nubhú)�”}”(hŒ,Table: Legend for Locking Requirements Table”h]”hŒ,Table: Legend for Locking Requirements Table”…”�”}”(hj&h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´M]hj7 h²hubeh}”(h]”Œtable-of-minimum-requirements”ah ]”h"]”Œtable of minimum requirements”ah$]”h&]”uh1hÄhj� h²hh³hÃh´M4ubeh}”(h]”Œcheat-sheet-for-locking”ah ]”h"]”Œcheat sheet for locking”ah$]”h&]”uh1hÄhhÆh²hh³hÃh´M$ubhÅ)�”}”(hhh]”(hÊ)�”}”(hŒThe trylock Functions”h]”hŒThe trylock Functions”…”�”}”(hjGh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÉhjDh²hh³hÃh´M`ubhú)�”}”(hXcThere are functions that try to acquire a lock only once and immediately return a value telling about success or failure to acquire the lock. They can be used if you need no access to the data protected with the lock when some other thread is holding the lock. You should acquire the lock later if you then need access to the data protected with the lock.”h]”hXcThere are functions that try to acquire a lock only once and immediately return a value telling about success or failure to acquire the lock. They can be used if you need no access to the data protected with the lock when some other thread is holding the lock. You should acquire the lock later if you then need access to the data protected with the lock.”…”�”}”(hjUh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´MbhjDh²hubhú)�”}”(hŒÿspin_trylock() does not spin but returns non-zero if it acquires the spinlock on the first try or 0 if not. This function can be used in all contexts like spin_lock(): you must have disabled the contexts that might interrupt you and acquire the spin lock.”h]”hŒÿspin_trylock() does not spin but returns non-zero if it acquires the spinlock on the first try or 0 if not. This function can be used in all contexts like spin_lock(): you must have disabled the contexts that might interrupt you and acquire the spin lock.”…”�”}”(hjch²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´MhhjDh²hubhú)�”}”(hŒÝmutex_trylock() does not suspend your task but returns non-zero if it could lock the mutex on the first try or 0 if not. This function cannot be safely used in hardware or software interrupt contexts despite not sleeping.”h]”hŒÝmutex_trylock() does not suspend your task but returns non-zero if it could lock the mutex on the first try or 0 if not. This function cannot be safely used in hardware or software interrupt contexts despite not sleeping.”…”�”}”(hjqh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´MnhjDh²hubeh}”(h]”Œthe-trylock-functions”ah ]”h"]”Œthe trylock functions”ah$]”h&]”uh1hÄhhÆh²hh³hÃh´M`ubhÅ)�”}”(hhh]”(hÊ)�”}”(hŒCommon Examples”h]”hŒCommon Examples”…”�”}”(hjŠh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÉhj‡h²hh³hÃh´Mtubhú)�”}”(hŒÀLet's step through a simple example: a cache of number to name mappings. The cache keeps a count of how often each of the objects is used, and when it gets full, throws out the least used one.”h]”hŒÂLet’s step through a simple example: a cache of number to name mappings. The cache keeps a count of how often each of the objects is used, and when it gets full, throws out the least used one.”…”�”}”(hj˜h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´Mvhj‡h²hubhÅ)�”}”(hhh]”(hÊ)�”}”(hŒAll In User Context”h]”hŒAll In User Context”…”�”}”(hj©h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÉhj¦h²hh³hÃh´M{ubhú)�”}”(hŒÖFor our first example, we assume that all operations are in user context (ie. from system calls), so we can sleep. This means we can use a mutex to protect the cache and all the objects within it. Here's the code::”h]”hŒ×For our first example, we assume that all operations are in user context (ie. from system calls), so we can sleep. This means we can use a mutex to protect the cache and all the objects within it. Here’s the code:”…”�”}”(hj·h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´M}hj¦h²hubj~)�”}”(hX‡#include #include #include #include #include struct object { struct list_head list; int id; char name[32]; int popularity; }; /* Protects the cache, cache_num, and the objects within it */ static DEFINE_MUTEX(cache_lock); static LIST_HEAD(cache); static unsigned int cache_num = 0; #define MAX_CACHE_SIZE 10 /* Must be holding cache_lock */ static struct object *__cache_find(int id) { struct object *i; list_for_each_entry(i, &cache, list) if (i->id == id) { i->popularity++; return i; } return NULL; } /* Must be holding cache_lock */ static void __cache_delete(struct object *obj) { BUG_ON(!obj); list_del(&obj->list); kfree(obj); cache_num--; } /* Must be holding cache_lock */ static void __cache_add(struct object *obj) { list_add(&obj->list, &cache); if (++cache_num > MAX_CACHE_SIZE) { struct object *i, *outcast = NULL; list_for_each_entry(i, &cache, list) { if (!outcast || i->popularity < outcast->popularity) outcast = i; } __cache_delete(outcast); } } int cache_add(int id, const char *name) { struct object *obj; if ((obj = kmalloc_obj(*obj)) == NULL) return -ENOMEM; strscpy(obj->name, name, sizeof(obj->name)); obj->id = id; obj->popularity = 0; mutex_lock(&cache_lock); __cache_add(obj); mutex_unlock(&cache_lock); return 0; } void cache_delete(int id) { mutex_lock(&cache_lock); __cache_delete(__cache_find(id)); mutex_unlock(&cache_lock); } int cache_find(int id, char *name) { struct object *obj; int ret = -ENOENT; mutex_lock(&cache_lock); obj = __cache_find(id); if (obj) { ret = 0; strscpy(name, obj->name); } mutex_unlock(&cache_lock); return ret; }”•áh]”hX‡#include #include #include #include #include struct object { struct list_head list; int id; char name[32]; int popularity; }; /* Protects the cache, cache_num, and the objects within it */ static DEFINE_MUTEX(cache_lock); static LIST_HEAD(cache); static unsigned int cache_num = 0; #define MAX_CACHE_SIZE 10 /* Must be holding cache_lock */ static struct object *__cache_find(int id) { struct object *i; list_for_each_entry(i, &cache, list) if (i->id == id) { i->popularity++; return i; } return NULL; } /* Must be holding cache_lock */ static void __cache_delete(struct object *obj) { BUG_ON(!obj); list_del(&obj->list); kfree(obj); cache_num--; } /* Must be holding cache_lock */ static void __cache_add(struct object *obj) { list_add(&obj->list, &cache); if (++cache_num > MAX_CACHE_SIZE) { struct object *i, *outcast = NULL; list_for_each_entry(i, &cache, list) { if (!outcast || i->popularity < outcast->popularity) outcast = i; } __cache_delete(outcast); } } int cache_add(int id, const char *name) { struct object *obj; if ((obj = kmalloc_obj(*obj)) == NULL) return -ENOMEM; strscpy(obj->name, name, sizeof(obj->name)); obj->id = id; obj->popularity = 0; mutex_lock(&cache_lock); __cache_add(obj); mutex_unlock(&cache_lock); return 0; } void cache_delete(int id) { mutex_lock(&cache_lock); __cache_delete(__cache_find(id)); mutex_unlock(&cache_lock); } int cache_find(int id, char *name) { struct object *obj; int ret = -ENOENT; mutex_lock(&cache_lock); obj = __cache_find(id); if (obj) { ret = 0; strscpy(name, obj->name); } mutex_unlock(&cache_lock); return ret; }”…”�”}”hjÅsbah}”(h]”h ]”h"]”h$]”h&]”j�jŽuh1j}h³hÃh´M�hj¦h²hubhú)�”}”(hX,Note that we always make sure we have the cache_lock when we add, delete, or look up the cache: both the cache infrastructure itself and the contents of the objects are protected by the lock. In this case it's easy, since we copy the data for the user, and never let them access the objects directly.”h]”hX.Note that we always make sure we have the cache_lock when we add, delete, or look up the cache: both the cache infrastructure itself and the contents of the objects are protected by the lock. In this case it’s easy, since we copy the data for the user, and never let them access the objects directly.”…”�”}”(hjÓh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´Màhj¦h²hubhú)�”}”(hŒÂThere is a slight (and common) optimization here: in cache_add() we set up the fields of the object before grabbing the lock. This is safe, as no-one else can access it until we put it in cache.”h]”hŒÂThere is a slight (and common) optimization here: in cache_add() we set up the fields of the object before grabbing the lock. This is safe, as no-one else can access it until we put it in cache.”…”�”}”(hjáh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´Mæhj¦h²hubeh}”(h]”Œall-in-user-context”ah ]”h"]”Œall in user context”ah$]”h&]”uh1hÄhj‡h²hh³hÃh´M{ubhÅ)�”}”(hhh]”(hÊ)�”}”(hŒ Accessing From Interrupt Context”h]”hŒ Accessing From Interrupt Context”…”�”}”(hjúh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÉhj÷h²hh³hÃh´Mìubhú)�”}”(hŒ¹Now consider the case where cache_find() can be called from interrupt context: either a hardware interrupt or a softirq. An example would be a timer which deletes object from the cache.”h]”hŒ¹Now consider the case where cache_find() can be called from interrupt context: either a hardware interrupt or a softirq. An example would be a timer which deletes object from the cache.”…”�”}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´Mîhj÷h²hubhú)�”}”(hŒ‡The change is shown below, in standard patch format: the ``-`` are lines which are taken away, and the ``+`` are lines which are added.”h]”(hŒ9The change is shown below, in standard patch format: the ”…”�”}”(hjh²hh³Nh´NubjI)�”}”(hŒ``-``”h]”hŒ-”…”�”}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jHhjubhŒ) are lines which are taken away, and the ”…”�”}”(hjh²hh³Nh´NubjI)�”}”(hŒ``+``”h]”hŒ+”…”�”}”(hj0h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jHhjubhŒ are lines which are added.”…”�”}”(hjh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´Mòhj÷h²hubj~)�”}”(hX--- cache.c.usercontext 2003-12-09 13:58:54.000000000 +1100 +++ cache.c.interrupt 2003-12-09 14:07:49.000000000 +1100 @@ -12,7 +12,7 @@ int popularity; }; -static DEFINE_MUTEX(cache_lock); +static DEFINE_SPINLOCK(cache_lock); static LIST_HEAD(cache); static unsigned int cache_num = 0; #define MAX_CACHE_SIZE 10 @@ -55,6 +55,7 @@ int cache_add(int id, const char *name) { struct object *obj; + unsigned long flags; if ((obj = kmalloc_obj(*obj)) == NULL) return -ENOMEM; @@ -63,30 +64,33 @@ obj->id = id; obj->popularity = 0; - mutex_lock(&cache_lock); + spin_lock_irqsave(&cache_lock, flags); __cache_add(obj); - mutex_unlock(&cache_lock); + spin_unlock_irqrestore(&cache_lock, flags); return 0; } void cache_delete(int id) { - mutex_lock(&cache_lock); + unsigned long flags; + + spin_lock_irqsave(&cache_lock, flags); __cache_delete(__cache_find(id)); - mutex_unlock(&cache_lock); + spin_unlock_irqrestore(&cache_lock, flags); } int cache_find(int id, char *name) { struct object *obj; int ret = -ENOENT; + unsigned long flags; - mutex_lock(&cache_lock); + spin_lock_irqsave(&cache_lock, flags); obj = __cache_find(id); if (obj) { ret = 0; strscpy(name, obj->name); } - mutex_unlock(&cache_lock); + spin_unlock_irqrestore(&cache_lock, flags); return ret; }”h]”hX--- cache.c.usercontext 2003-12-09 13:58:54.000000000 +1100 +++ cache.c.interrupt 2003-12-09 14:07:49.000000000 +1100 @@ -12,7 +12,7 @@ int popularity; }; -static DEFINE_MUTEX(cache_lock); +static DEFINE_SPINLOCK(cache_lock); static LIST_HEAD(cache); static unsigned int cache_num = 0; #define MAX_CACHE_SIZE 10 @@ -55,6 +55,7 @@ int cache_add(int id, const char *name) { struct object *obj; + unsigned long flags; if ((obj = kmalloc_obj(*obj)) == NULL) return -ENOMEM; @@ -63,30 +64,33 @@ obj->id = id; obj->popularity = 0; - mutex_lock(&cache_lock); + spin_lock_irqsave(&cache_lock, flags); __cache_add(obj); - mutex_unlock(&cache_lock); + spin_unlock_irqrestore(&cache_lock, flags); return 0; } void cache_delete(int id) { - mutex_lock(&cache_lock); + unsigned long flags; + + spin_lock_irqsave(&cache_lock, flags); __cache_delete(__cache_find(id)); - mutex_unlock(&cache_lock); + spin_unlock_irqrestore(&cache_lock, flags); } int cache_find(int id, char *name) { struct object *obj; int ret = -ENOENT; + unsigned long flags; - mutex_lock(&cache_lock); + spin_lock_irqsave(&cache_lock, flags); obj = __cache_find(id); if (obj) { ret = 0; strscpy(name, obj->name); } - mutex_unlock(&cache_lock); + spin_unlock_irqrestore(&cache_lock, flags); return ret; }”…”�”}”hjHsbah}”(h]”h ]”h"]”h$]”h&]”j�jŽuh1j}h³hÃh´M÷hj÷h²hubhú)�”}”(hŒÇNote that the spin_lock_irqsave() will turn off interrupts if they are on, otherwise does nothing (if we are already in an interrupt handler), hence these functions are safe to call from any context.”h]”hŒÇNote that the spin_lock_irqsave() will turn off interrupts if they are on, otherwise does nothing (if we are already in an interrupt handler), hence these functions are safe to call from any context.”…”�”}”(hjVh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´M3hj÷h²hubhú)�”}”(hŒìUnfortunately, cache_add() calls kmalloc() with the ``GFP_KERNEL`` flag, which is only legal in user context. I have assumed that cache_add() is still only called in user context, otherwise this should become a parameter to cache_add().”h]”(hŒ4Unfortunately, cache_add() calls kmalloc() with the ”…”�”}”(hjdh²hh³Nh´NubjI)�”}”(hŒ``GFP_KERNEL``”h]”hŒ GFP_KERNEL”…”�”}”(hjlh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jHhjdubhŒª flag, which is only legal in user context. I have assumed that cache_add() is still only called in user context, otherwise this should become a parameter to cache_add().”…”�”}”(hjdh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´M8hj÷h²hubeh}”(h]”Œ accessing-from-interrupt-context”ah ]”h"]”Œ accessing from interrupt context”ah$]”h&]”uh1hÄhj‡h²hh³hÃh´MìubhÅ)�”}”(hhh]”(hÊ)�”}”(hŒ"Exposing Objects Outside This File”h]”hŒ"Exposing Objects Outside This File”…”�”}”(hj�h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÉhjŒh²hh³hÃh´M?ubhú)�”}”(hXIf our objects contained more information, it might not be sufficient to copy the information in and out: other parts of the code might want to keep pointers to these objects, for example, rather than looking up the id every time. This produces two problems.”h]”hXIf our objects contained more information, it might not be sufficient to copy the information in and out: other parts of the code might want to keep pointers to these objects, for example, rather than looking up the id every time. This produces two problems.”…”�”}”(hj�h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´MAhjŒh²hubhú)�”}”(hŒÏThe first problem is that we use the ``cache_lock`` to protect objects: we'd need to make this non-static so the rest of the code can use it. This makes locking trickier, as it is no longer all in one place.”h]”(hŒ%The first problem is that we use the ”…”�”}”(hj«h²hh³Nh´NubjI)�”}”(hŒ``cache_lock``”h]”hŒ cache_lock”…”�”}”(hj³h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jHhj«ubhŒž to protect objects: we’d need to make this non-static so the rest of the code can use it. This makes locking trickier, as it is no longer all in one place.”…”�”}”(hj«h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´MFhjŒh²hubhú)�”}”(hX=The second problem is the lifetime problem: if another structure keeps a pointer to an object, it presumably expects that pointer to remain valid. Unfortunately, this is only guaranteed while you hold the lock, otherwise someone might call cache_delete() and even worse, add another object, re-using the same address.”h]”hX=The second problem is the lifetime problem: if another structure keeps a pointer to an object, it presumably expects that pointer to remain valid. Unfortunately, this is only guaranteed while you hold the lock, otherwise someone might call cache_delete() and even worse, add another object, re-using the same address.”…”�”}”(hjËh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´MJhjŒh²hubhú)�”}”(hŒZAs there is only one lock, you can't hold it forever: no-one else would get any work done.”h]”hŒ\As there is only one lock, you can’t hold it forever: no-one else would get any work done.”…”�”}”(hjÙh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´MPhjŒh²hubhú)�”}”(hXThe solution to this problem is to use a reference count: everyone who has a pointer to the object increases it when they first get the object, and drops the reference count when they're finished with it. Whoever drops it to zero knows it is unused, and can actually delete it.”h]”hXThe solution to this problem is to use a reference count: everyone who has a pointer to the object increases it when they first get the object, and drops the reference count when they’re finished with it. Whoever drops it to zero knows it is unused, and can actually delete it.”…”�”}”(hjçh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´MShjŒh²hubhú)�”}”(hŒHere is the code::”h]”hŒHere is the code:”…”�”}”(hjõh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´MXhjŒh²hubj~)�”}”(hXÚ--- cache.c.interrupt 2003-12-09 14:25:43.000000000 +1100 +++ cache.c.refcnt 2003-12-09 14:33:05.000000000 +1100 @@ -7,6 +7,7 @@ struct object { struct list_head list; + unsigned int refcnt; int id; char name[32]; int popularity; @@ -17,6 +18,35 @@ static unsigned int cache_num = 0; #define MAX_CACHE_SIZE 10 +static void __object_put(struct object *obj) +{ + if (--obj->refcnt == 0) + kfree(obj); +} + +static void __object_get(struct object *obj) +{ + obj->refcnt++; +} + +void object_put(struct object *obj) +{ + unsigned long flags; + + spin_lock_irqsave(&cache_lock, flags); + __object_put(obj); + spin_unlock_irqrestore(&cache_lock, flags); +} + +void object_get(struct object *obj) +{ + unsigned long flags; + + spin_lock_irqsave(&cache_lock, flags); + __object_get(obj); + spin_unlock_irqrestore(&cache_lock, flags); +} + /* Must be holding cache_lock */ static struct object *__cache_find(int id) { @@ -35,6 +65,7 @@ { BUG_ON(!obj); list_del(&obj->list); + __object_put(obj); cache_num--; } @@ -63,6 +94,7 @@ strscpy(obj->name, name, sizeof(obj->name)); obj->id = id; obj->popularity = 0; + obj->refcnt = 1; /* The cache holds a reference */ spin_lock_irqsave(&cache_lock, flags); __cache_add(obj); @@ -79,18 +111,15 @@ spin_unlock_irqrestore(&cache_lock, flags); } -int cache_find(int id, char *name) +struct object *cache_find(int id) { struct object *obj; - int ret = -ENOENT; unsigned long flags; spin_lock_irqsave(&cache_lock, flags); obj = __cache_find(id); - if (obj) { - ret = 0; - strscpy(name, obj->name); - } + if (obj) + __object_get(obj); spin_unlock_irqrestore(&cache_lock, flags); - return ret; + return obj; }”h]”hXÚ--- cache.c.interrupt 2003-12-09 14:25:43.000000000 +1100 +++ cache.c.refcnt 2003-12-09 14:33:05.000000000 +1100 @@ -7,6 +7,7 @@ struct object { struct list_head list; + unsigned int refcnt; int id; char name[32]; int popularity; @@ -17,6 +18,35 @@ static unsigned int cache_num = 0; #define MAX_CACHE_SIZE 10 +static void __object_put(struct object *obj) +{ + if (--obj->refcnt == 0) + kfree(obj); +} + +static void __object_get(struct object *obj) +{ + obj->refcnt++; +} + +void object_put(struct object *obj) +{ + unsigned long flags; + + spin_lock_irqsave(&cache_lock, flags); + __object_put(obj); + spin_unlock_irqrestore(&cache_lock, flags); +} + +void object_get(struct object *obj) +{ + unsigned long flags; + + spin_lock_irqsave(&cache_lock, flags); + __object_get(obj); + spin_unlock_irqrestore(&cache_lock, flags); +} + /* Must be holding cache_lock */ static struct object *__cache_find(int id) { @@ -35,6 +65,7 @@ { BUG_ON(!obj); list_del(&obj->list); + __object_put(obj); cache_num--; } @@ -63,6 +94,7 @@ strscpy(obj->name, name, sizeof(obj->name)); obj->id = id; obj->popularity = 0; + obj->refcnt = 1; /* The cache holds a reference */ spin_lock_irqsave(&cache_lock, flags); __cache_add(obj); @@ -79,18 +111,15 @@ spin_unlock_irqrestore(&cache_lock, flags); } -int cache_find(int id, char *name) +struct object *cache_find(int id) { struct object *obj; - int ret = -ENOENT; unsigned long flags; spin_lock_irqsave(&cache_lock, flags); obj = __cache_find(id); - if (obj) { - ret = 0; - strscpy(name, obj->name); - } + if (obj) + __object_get(obj); spin_unlock_irqrestore(&cache_lock, flags); - return ret; + return obj; }”…”�”}”hjsbah}”(h]”h ]”h"]”h$]”h&]”j�jŽuh1j}h³hÃh´MZhjŒh²hubhú)�”}”(hŒûWe encapsulate the reference counting in the standard 'get' and 'put' functions. Now we can return the object itself from cache_find() which has the advantage that the user can now sleep holding the object (eg. to copy_to_user() to name to userspace).”h]”hXWe encapsulate the reference counting in the standard ‘get’ and ‘put’ functions. Now we can return the object itself from cache_find() which has the advantage that the user can now sleep holding the object (eg. to copy_to_user() to name to userspace).”…”�”}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´M°hjŒh²hubhú)�”}”(hXThe other point to note is that I said a reference should be held for every pointer to the object: thus the reference count is 1 when first inserted into the cache. In some versions the framework does not hold a reference count, but they are more complicated.”h]”hXThe other point to note is that I said a reference should be held for every pointer to the object: thus the reference count is 1 when first inserted into the cache. In some versions the framework does not hold a reference count, but they are more complicated.”…”�”}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´M¶hjŒh²hubhÅ)�”}”(hhh]”(hÊ)�”}”(hŒ/Using Atomic Operations For The Reference Count”h]”hŒ/Using Atomic Operations For The Reference Count”…”�”}”(hj0h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÉhj-h²hh³hÃh´M¼ubhú)�”}”(hXIn practice, :c:type:`atomic_t` would usually be used for refcnt. There are a number of atomic operations defined in ``include/asm/atomic.h``: these are guaranteed to be seen atomically from all CPUs in the system, so no lock is required. In this case, it is simpler than using spinlocks, although for anything non-trivial using spinlocks is clearer. The atomic_inc() and atomic_dec_and_test() are used instead of the standard increment and decrement operators, and the lock is no longer used to protect the reference count itself.”h]”(hŒ In practice, ”…”�”}”(hj>h²hh³Nh´Nubh)�”}”(hŒ:c:type:`atomic_t`”h]”jI)�”}”(hjHh]”hŒatomic_t”…”�”}”(hjJh²hh³Nh´Nubah}”(h]”h ]”(Œxref”Œc”Œc-type”eh"]”h$]”h&]”uh1jHhjFubah}”(h]”h ]”h"]”h$]”h&]”Œrefdoc”Œkernel-hacking/locking”Œ refdomain”jUŒreftype”Œtype”Œ refexplicit”‰Œrefwarn”‰Œ reftarget”Œatomic_t”uh1hh³hÃh´M¾hj>ubhŒV would usually be used for refcnt. There are a number of atomic operations defined in ”…”�”}”(hj>h²hh³Nh´NubjI)�”}”(hŒ``include/asm/atomic.h``”h]”hŒinclude/asm/atomic.h”…”�”}”(hjmh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jHhj>ubhX†: these are guaranteed to be seen atomically from all CPUs in the system, so no lock is required. In this case, it is simpler than using spinlocks, although for anything non-trivial using spinlocks is clearer. The atomic_inc() and atomic_dec_and_test() are used instead of the standard increment and decrement operators, and the lock is no longer used to protect the reference count itself.”…”�”}”(hj>h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´M¾hj-h²hubj~)�”}”(hXg--- cache.c.refcnt 2003-12-09 15:00:35.000000000 +1100 +++ cache.c.refcnt-atomic 2003-12-11 15:49:42.000000000 +1100 @@ -7,7 +7,7 @@ struct object { struct list_head list; - unsigned int refcnt; + atomic_t refcnt; int id; char name[32]; int popularity; @@ -18,33 +18,15 @@ static unsigned int cache_num = 0; #define MAX_CACHE_SIZE 10 -static void __object_put(struct object *obj) -{ - if (--obj->refcnt == 0) - kfree(obj); -} - -static void __object_get(struct object *obj) -{ - obj->refcnt++; -} - void object_put(struct object *obj) { - unsigned long flags; - - spin_lock_irqsave(&cache_lock, flags); - __object_put(obj); - spin_unlock_irqrestore(&cache_lock, flags); + if (atomic_dec_and_test(&obj->refcnt)) + kfree(obj); } void object_get(struct object *obj) { - unsigned long flags; - - spin_lock_irqsave(&cache_lock, flags); - __object_get(obj); - spin_unlock_irqrestore(&cache_lock, flags); + atomic_inc(&obj->refcnt); } /* Must be holding cache_lock */ @@ -65,7 +47,7 @@ { BUG_ON(!obj); list_del(&obj->list); - __object_put(obj); + object_put(obj); cache_num--; } @@ -94,7 +76,7 @@ strscpy(obj->name, name, sizeof(obj->name)); obj->id = id; obj->popularity = 0; - obj->refcnt = 1; /* The cache holds a reference */ + atomic_set(&obj->refcnt, 1); /* The cache holds a reference */ spin_lock_irqsave(&cache_lock, flags); __cache_add(obj); @@ -119,7 +101,7 @@ spin_lock_irqsave(&cache_lock, flags); obj = __cache_find(id); if (obj) - __object_get(obj); + object_get(obj); spin_unlock_irqrestore(&cache_lock, flags); return obj; }”h]”hXg--- cache.c.refcnt 2003-12-09 15:00:35.000000000 +1100 +++ cache.c.refcnt-atomic 2003-12-11 15:49:42.000000000 +1100 @@ -7,7 +7,7 @@ struct object { struct list_head list; - unsigned int refcnt; + atomic_t refcnt; int id; char name[32]; int popularity; @@ -18,33 +18,15 @@ static unsigned int cache_num = 0; #define MAX_CACHE_SIZE 10 -static void __object_put(struct object *obj) -{ - if (--obj->refcnt == 0) - kfree(obj); -} - -static void __object_get(struct object *obj) -{ - obj->refcnt++; -} - void object_put(struct object *obj) { - unsigned long flags; - - spin_lock_irqsave(&cache_lock, flags); - __object_put(obj); - spin_unlock_irqrestore(&cache_lock, flags); + if (atomic_dec_and_test(&obj->refcnt)) + kfree(obj); } void object_get(struct object *obj) { - unsigned long flags; - - spin_lock_irqsave(&cache_lock, flags); - __object_get(obj); - spin_unlock_irqrestore(&cache_lock, flags); + atomic_inc(&obj->refcnt); } /* Must be holding cache_lock */ @@ -65,7 +47,7 @@ { BUG_ON(!obj); list_del(&obj->list); - __object_put(obj); + object_put(obj); cache_num--; } @@ -94,7 +76,7 @@ strscpy(obj->name, name, sizeof(obj->name)); obj->id = id; obj->popularity = 0; - obj->refcnt = 1; /* The cache holds a reference */ + atomic_set(&obj->refcnt, 1); /* The cache holds a reference */ spin_lock_irqsave(&cache_lock, flags); __cache_add(obj); @@ -119,7 +101,7 @@ spin_lock_irqsave(&cache_lock, flags); obj = __cache_find(id); if (obj) - __object_get(obj); + object_get(obj); spin_unlock_irqrestore(&cache_lock, flags); return obj; }”…”�”}”hj…sbah}”(h]”h ]”h"]”h$]”h&]”j�jŽuh1j}h³hÃh´MÉhj-h²hubeh}”(h]”Œ/using-atomic-operations-for-the-reference-count”ah ]”h"]”Œ/using atomic operations for the reference count”ah$]”h&]”uh1hÄhjŒh²hh³hÃh´M¼ubeh}”(h]”Œ"exposing-objects-outside-this-file”ah ]”h"]”Œ"exposing objects outside this file”ah$]”h&]”uh1hÄhj‡h²hh³hÃh´M?ubhÅ)�”}”(hhh]”(hÊ)�”}”(hŒ!Protecting The Objects Themselves”h]”hŒ!Protecting The Objects Themselves”…”�”}”(hj¦h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÉhj£h²hh³hÃh´Mubhú)�”}”(hŒºIn these examples, we assumed that the objects (except the reference counts) never changed once they are created. If we wanted to allow the name to change, there are three possibilities:”h]”hŒºIn these examples, we assumed that the objects (except the reference counts) never changed once they are created. If we wanted to allow the name to change, there are three possibilities:”…”�”}”(hj´h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´Mhj£h²hubj½ )�”}”(hhh]”(j )�”}”(hŒrYou can make ``cache_lock`` non-static, and tell people to grab that lock before changing the name in any object. ”h]”hú)�”}”(hŒqYou can make ``cache_lock`` non-static, and tell people to grab that lock before changing the name in any object.”h]”(hŒ You can make ”…”�”}”(hjÉh²hh³Nh´NubjI)�”}”(hŒ``cache_lock``”h]”hŒ cache_lock”…”�”}”(hjÑh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jHhjÉubhŒV non-static, and tell people to grab that lock before changing the name in any object.”…”�”}”(hjÉh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´MhjÅubah}”(h]”h ]”h"]”h$]”h&]”uh1jÁ hjÂh²hh³hÃh´Nubj )�”}”(hŒˆYou can provide a cache_obj_rename() which grabs this lock and changes the name for the caller, and tell everyone to use that function. ”h]”hú)�”}”(hŒ‡You can provide a cache_obj_rename() which grabs this lock and changes the name for the caller, and tell everyone to use that function.”h]”hŒ‡You can provide a cache_obj_rename() which grabs this lock and changes the name for the caller, and tell everyone to use that function.”…”�”}”(hjóh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´Mhjïubah}”(h]”h ]”h"]”h$]”h&]”uh1jÁ hjÂh²hh³hÃh´Nubj )�”}”(hŒiYou can make the ``cache_lock`` protect only the cache itself, and use another lock to protect the name. ”h]”hú)�”}”(hŒhYou can make the ``cache_lock`` protect only the cache itself, and use another lock to protect the name.”h]”(hŒYou can make the ”…”�”}”(hj h²hh³Nh´NubjI)�”}”(hŒ``cache_lock``”h]”hŒ cache_lock”…”�”}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jHhj ubhŒI protect only the cache itself, and use another lock to protect the name.”…”�”}”(hj h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´M#hjubah}”(h]”h ]”h"]”h$]”h&]”uh1jÁ hjÂh²hh³hÃh´Nubeh}”(h]”h ]”h"]”h$]”h&]”j5 j6 uh1j¼ h³hÃh´Mhj£h²hubhú)�”}”(hŒ�Theoretically, you can make the locks as fine-grained as one lock for every field, for every object. In practice, the most common variants are:”h]”hŒ�Theoretically, you can make the locks as fine-grained as one lock for every field, for every object. In practice, the most common variants are:”…”�”}”(hj7h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´M&hj£h²hubj½ )�”}”(hhh]”(j )�”}”(hŒ‡One lock which protects the infrastructure (the ``cache`` list in this example) and all the objects. This is what we have done so far. ”h]”hú)�”}”(hŒ†One lock which protects the infrastructure (the ``cache`` list in this example) and all the objects. This is what we have done so far.”h]”(hŒ0One lock which protects the infrastructure (the ”…”�”}”(hjLh²hh³Nh´NubjI)�”}”(hŒ ``cache``”h]”hŒcache”…”�”}”(hjTh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jHhjLubhŒM list in this example) and all the objects. This is what we have done so far.”…”�”}”(hjLh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´M*hjHubah}”(h]”h ]”h"]”h$]”h&]”uh1jÁ hjEh²hh³hÃh´Nubj )�”}”(hŒ¤One lock which protects the infrastructure (including the list pointers inside the objects), and one lock inside the object which protects the rest of that object. ”h]”hú)�”}”(hŒ£One lock which protects the infrastructure (including the list pointers inside the objects), and one lock inside the object which protects the rest of that object.”h]”hŒ£One lock which protects the infrastructure (including the list pointers inside the objects), and one lock inside the object which protects the rest of that object.”…”�”}”(hjvh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´M-hjrubah}”(h]”h ]”h"]”h$]”h&]”uh1jÁ hjEh²hh³hÃh´Nubj )�”}”(hŒvMultiple locks to protect the infrastructure (eg. one lock per hash chain), possibly with a separate per-object lock. ”h]”hú)�”}”(hŒuMultiple locks to protect the infrastructure (eg. one lock per hash chain), possibly with a separate per-object lock.”h]”hŒuMultiple locks to protect the infrastructure (eg. one lock per hash chain), possibly with a separate per-object lock.”…”�”}”(hjŽh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´M1hjŠubah}”(h]”h ]”h"]”h$]”h&]”uh1jÁ hjEh²hh³hÃh´Nubeh}”(h]”h ]”h"]”h$]”h&]”j5 j6 uh1j¼ h³hÃh´M*hj£h²hubhú)�”}”(hŒ-Here is the "lock-per-object" implementation:”h]”hŒ1Here is the “lock-per-objectâ€� implementation:”…”�”}”(hj¨h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´M4hj£h²hubj~)�”}”(hXù--- cache.c.refcnt-atomic 2003-12-11 15:50:54.000000000 +1100 +++ cache.c.perobjectlock 2003-12-11 17:15:03.000000000 +1100 @@ -6,11 +6,17 @@ struct object { + /* These two protected by cache_lock. */ struct list_head list; + int popularity; + atomic_t refcnt; + + /* Doesn't change once created. */ int id; + + spinlock_t lock; /* Protects the name */ char name[32]; - int popularity; }; static DEFINE_SPINLOCK(cache_lock); @@ -77,6 +84,7 @@ obj->id = id; obj->popularity = 0; atomic_set(&obj->refcnt, 1); /* The cache holds a reference */ + spin_lock_init(&obj->lock); spin_lock_irqsave(&cache_lock, flags); __cache_add(obj);”h]”hXù--- cache.c.refcnt-atomic 2003-12-11 15:50:54.000000000 +1100 +++ cache.c.perobjectlock 2003-12-11 17:15:03.000000000 +1100 @@ -6,11 +6,17 @@ struct object { + /* These two protected by cache_lock. */ struct list_head list; + int popularity; + atomic_t refcnt; + + /* Doesn't change once created. */ int id; + + spinlock_t lock; /* Protects the name */ char name[32]; - int popularity; }; static DEFINE_SPINLOCK(cache_lock); @@ -77,6 +84,7 @@ obj->id = id; obj->popularity = 0; atomic_set(&obj->refcnt, 1); /* The cache holds a reference */ + spin_lock_init(&obj->lock); spin_lock_irqsave(&cache_lock, flags); __cache_add(obj);”…”�”}”hj¶sbah}”(h]”h ]”h"]”h$]”h&]”j�jŽuh1j}h³hÃh´M8hj£h²hubhú)�”}”(hX`Note that I decide that the popularity count should be protected by the ``cache_lock`` rather than the per-object lock: this is because it (like the :c:type:`struct list_head ` inside the object) is logically part of the infrastructure. This way, I don't need to grab the lock of every object in __cache_add() when seeking the least popular.”h]”(hŒHNote that I decide that the popularity count should be protected by the ”…”�”}”(hjÄh²hh³Nh´NubjI)�”}”(hŒ``cache_lock``”h]”hŒ cache_lock”…”�”}”(hjÌh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jHhjÄubhŒ? rather than the per-object lock: this is because it (like the ”…”�”}”(hjÄh²hh³Nh´Nubh)�”}”(hŒ&:c:type:`struct list_head `”h]”jI)�”}”(hjàh]”hŒstruct list_head”…”�”}”(hjâh²hh³Nh´Nubah}”(h]”h ]”(jTjUŒc-type”eh"]”h$]”h&]”uh1jHhjÞubah}”(h]”h ]”h"]”h$]”h&]”Œrefdoc”jaŒ refdomain”jUŒreftype”Œtype”Œ refexplicit”ˆŒrefwarn”‰jgŒ list_head”uh1hh³hÃh´MVhjÄubhŒ§ inside the object) is logically part of the infrastructure. This way, I don’t need to grab the lock of every object in __cache_add() when seeking the least popular.”…”�”}”(hjÄh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´MVhj£h²hubhú)�”}”(hŒÔI also decided that the id member is unchangeable, so I don't need to grab each object lock in __cache_find() to examine the id: the object lock is only used by a caller who wants to read or write the name field.”h]”hŒÖI also decided that the id member is unchangeable, so I don’t need to grab each object lock in __cache_find() to examine the id: the object lock is only used by a caller who wants to read or write the name field.”…”�”}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´M]hj£h²hubhú)�”}”(hŒþNote also that I added a comment describing what data was protected by which locks. This is extremely important, as it describes the runtime behavior of the code, and can be hard to gain from just reading. And as Alan Cox says, “Lock data, not codeâ€�.”h]”hŒþNote also that I added a comment describing what data was protected by which locks. This is extremely important, as it describes the runtime behavior of the code, and can be hard to gain from just reading. And as Alan Cox says, “Lock data, not codeâ€�.”…”�”}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´Mbhj£h²hubeh}”(h]”Œ!protecting-the-objects-themselves”ah ]”h"]”Œ!protecting the objects themselves”ah$]”h&]”uh1hÄhj‡h²hh³hÃh´Mubeh}”(h]”Œcommon-examples”ah ]”h"]”Œcommon examples”ah$]”h&]”uh1hÄhhÆh²hh³hÃh´MtubhÅ)�”}”(hhh]”(hÊ)�”}”(hŒCommon Problems”h]”hŒCommon Problems”…”�”}”(hj6h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÉhj3h²hh³hÃh´MhubhÅ)�”}”(hhh]”(hÊ)�”}”(hŒDeadlock: Simple and Advanced”h]”hŒDeadlock: Simple and Advanced”…”�”}”(hjGh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÉhjDh²hh³hÃh´Mkubhú)�”}”(hX&There is a coding bug where a piece of code tries to grab a spinlock twice: it will spin forever, waiting for the lock to be released (spinlocks, rwlocks and mutexes are not recursive in Linux). This is trivial to diagnose: not a stay-up-five-nights-talk-to-fluffy-code-bunnies kind of problem.”h]”hX&There is a coding bug where a piece of code tries to grab a spinlock twice: it will spin forever, waiting for the lock to be released (spinlocks, rwlocks and mutexes are not recursive in Linux). This is trivial to diagnose: not a stay-up-five-nights-talk-to-fluffy-code-bunnies kind of problem.”…”�”}”(hjUh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´MmhjDh²hubhú)�”}”(hX3For a slightly more complex case, imagine you have a region shared by a softirq and user context. If you use a spin_lock() call to protect it, it is possible that the user context will be interrupted by the softirq while it holds the lock, and the softirq will then spin forever trying to get the same lock.”h]”hX3For a slightly more complex case, imagine you have a region shared by a softirq and user context. If you use a spin_lock() call to protect it, it is possible that the user context will be interrupted by the softirq while it holds the lock, and the softirq will then spin forever trying to get the same lock.”…”�”}”(hjch²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´MshjDh²hubhú)�”}”(hŒôBoth of these are called deadlock, and as shown above, it can occur even with a single CPU (although not on UP compiles, since spinlocks vanish on kernel compiles with ``CONFIG_SMP``\ =n. You'll still get data corruption in the second example).”h]”(hŒ¨Both of these are called deadlock, and as shown above, it can occur even with a single CPU (although not on UP compiles, since spinlocks vanish on kernel compiles with ”…”�”}”(hjqh²hh³Nh´NubjI)�”}”(hŒ``CONFIG_SMP``”h]”hŒ CONFIG_SMP”…”�”}”(hjyh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jHhjqubhŒ@ =n. You’ll still get data corruption in the second example).”…”�”}”(hjqh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´MyhjDh²hubhú)�”}”(hŒÀThis complete lockup is easy to diagnose: on SMP boxes the watchdog timer or compiling with ``DEBUG_SPINLOCK`` set (``include/linux/spinlock.h``) will show this up immediately when it happens.”h]”(hŒ\This complete lockup is easy to diagnose: on SMP boxes the watchdog timer or compiling with ”…”�”}”(hj‘h²hh³Nh´NubjI)�”}”(hŒ``DEBUG_SPINLOCK``”h]”hŒDEBUG_SPINLOCK”…”�”}”(hj™h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jHhj‘ubhŒ set (”…”�”}”(hj‘h²hh³Nh´NubjI)�”}”(hŒ``include/linux/spinlock.h``”h]”hŒinclude/linux/spinlock.h”…”�”}”(hj«h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jHhj‘ubhŒ0) will show this up immediately when it happens.”…”�”}”(hj‘h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´M~hjDh²hubhú)�”}”(hX¸A more complex problem is the so-called 'deadly embrace', involving two or more locks. Say you have a hash table: each entry in the table is a spinlock, and a chain of hashed objects. Inside a softirq handler, you sometimes want to alter an object from one place in the hash to another: you grab the spinlock of the old hash chain and the spinlock of the new hash chain, and delete the object from the old one, and insert it in the new one.”h]”hX¼A more complex problem is the so-called ‘deadly embrace’, involving two or more locks. Say you have a hash table: each entry in the table is a spinlock, and a chain of hashed objects. Inside a softirq handler, you sometimes want to alter an object from one place in the hash to another: you grab the spinlock of the old hash chain and the spinlock of the new hash chain, and delete the object from the old one, and insert it in the new one.”…”�”}”(hjÃh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´MƒhjDh²hubhú)�”}”(hX There are two problems here. First, if your code ever tries to move the object to the same chain, it will deadlock with itself as it tries to lock it twice. Secondly, if the same softirq on another CPU is trying to move another object in the reverse direction, the following could happen:”h]”hX There are two problems here. First, if your code ever tries to move the object to the same chain, it will deadlock with itself as it tries to lock it twice. Secondly, if the same softirq on another CPU is trying to move another object in the reverse direction, the following could happen:”…”�”}”(hjÑh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´M‹hjDh²hubjž)�”}”(hhh]”j±)�”}”(hhh]”(j¶)�”}”(hhh]”h}”(h]”h ]”h"]”h$]”h&]”Œcolwidth”Kuh1jµhjâubj¶)�”}”(hhh]”h}”(h]”h ]”h"]”h$]”h&]”Œcolwidth”Kuh1jµhjâubjÌ)�”}”(hhh]”jÑ)�”}”(hhh]”(jÖ)�”}”(hhh]”hú)�”}”(hŒCPU 1”h]”hŒCPU 1”…”�”}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´M’hjÿubah}”(h]”h ]”h"]”h$]”h&]”uh1jÕhjüubjÖ)�”}”(hhh]”hú)�”}”(hŒCPU 2”h]”hŒCPU 2”…”�”}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´M’hjubah}”(h]”h ]”h"]”h$]”h&]”uh1jÕhjüubeh}”(h]”h ]”h"]”h$]”h&]”uh1jÐhjùubah}”(h]”h ]”h"]”h$]”h&]”uh1jËhjâubj)�”}”(hhh]”(jÑ)�”}”(hhh]”(jÖ)�”}”(hhh]”hú)�”}”(hŒGrab lock A -> OK”h]”hŒGrab lock A -> OK”…”�”}”(hjBh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´M”hj?ubah}”(h]”h ]”h"]”h$]”h&]”uh1jÕhj<ubjÖ)�”}”(hhh]”hú)�”}”(hŒGrab lock B -> OK”h]”hŒGrab lock B -> OK”…”�”}”(hjYh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´M”hjVubah}”(h]”h ]”h"]”h$]”h&]”uh1jÕhj<ubeh}”(h]”h ]”h"]”h$]”h&]”uh1jÐhj9ubjÑ)�”}”(hhh]”(jÖ)�”}”(hhh]”hú)�”}”(hŒGrab lock B -> spin”h]”hŒGrab lock B -> spin”…”�”}”(hjyh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´M–hjvubah}”(h]”h ]”h"]”h$]”h&]”uh1jÕhjsubjÖ)�”}”(hhh]”hú)�”}”(hŒGrab lock A -> spin”h]”hŒGrab lock A -> spin”…”�”}”(hj�h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´M–hj�ubah}”(h]”h ]”h"]”h$]”h&]”uh1jÕhjsubeh}”(h]”h ]”h"]”h$]”h&]”uh1jÐhj9ubeh}”(h]”h ]”h"]”h$]”h&]”uh1jhjâubeh}”(h]”h ]”h"]”h$]”h&]”Œcols”Kuh1j°hjßubah}”(h]”h ]”h"]”h$]”h&]”uh1j�hjDh²hh³hÃh´Nubhú)�”}”(hŒTable: Consequences”h]”hŒTable: Consequences”…”�”}”(hj½h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´M™hjDh²hubhú)�”}”(hŒxThe two CPUs will spin forever, waiting for the other to give up their lock. It will look, smell, and feel like a crash.”h]”hŒxThe two CPUs will spin forever, waiting for the other to give up their lock. It will look, smell, and feel like a crash.”…”�”}”(hjËh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´M›hjDh²hubeh}”(h]”j²ah ]”h"]”Œdeadlock: simple and advanced”ah$]”h&]”uh1hÄhj3h²hh³hÃh´Mkjœ KubhÅ)�”}”(hhh]”(hÊ)�”}”(hŒPreventing Deadlock”h]”hŒPreventing Deadlock”…”�”}”(hjãh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÉhjàh²hh³hÃh´MŸubhú)�”}”(hX#Textbooks will tell you that if you always lock in the same order, you will never get this kind of deadlock. Practice will tell you that this approach doesn't scale: when I create a new lock, I don't understand enough of the kernel to figure out where in the 5000 lock hierarchy it will fit.”h]”hX'Textbooks will tell you that if you always lock in the same order, you will never get this kind of deadlock. Practice will tell you that this approach doesn’t scale: when I create a new lock, I don’t understand enough of the kernel to figure out where in the 5000 lock hierarchy it will fit.”…”�”}”(hjñh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´M¡hjàh²hubhú)�”}”(hX_The best locks are encapsulated: they never get exposed in headers, and are never held around calls to non-trivial functions outside the same file. You can read through this code and see that it will never deadlock, because it never tries to grab another lock while it has that one. People using your code don't even need to know you are using a lock.”h]”hXaThe best locks are encapsulated: they never get exposed in headers, and are never held around calls to non-trivial functions outside the same file. You can read through this code and see that it will never deadlock, because it never tries to grab another lock while it has that one. People using your code don’t even need to know you are using a lock.”…”�”}”(hjÿh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´M§hjàh²hubhú)�”}”(hŒºA classic problem here is when you provide callbacks or hooks: if you call these with the lock held, you risk simple deadlock, or a deadly embrace (who knows what the callback will do?).”h]”hŒºA classic problem here is when you provide callbacks or hooks: if you call these with the lock held, you risk simple deadlock, or a deadly embrace (who knows what the callback will do?).”…”�”}”(hj h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´M®hjàh²hubhÅ)�”}”(hhh]”(hÊ)�”}”(hŒ#Overzealous Prevention Of Deadlocks”h]”hŒ#Overzealous Prevention Of Deadlocks”…”�”}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÉhjh²hh³hÃh´M³ubhú)�”}”(hŒÞDeadlocks are problematic, but not as bad as data corruption. Code which grabs a read lock, searches a list, fails to find what it wants, drops the read lock, grabs a write lock and inserts the object has a race condition.”h]”hŒÞDeadlocks are problematic, but not as bad as data corruption. Code which grabs a read lock, searches a list, fails to find what it wants, drops the read lock, grabs a write lock and inserts the object has a race condition.”…”�”}”(hj,h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´Mµhjh²hubeh}”(h]”Œ#overzealous-prevention-of-deadlocks”ah ]”h"]”Œ#overzealous prevention of deadlocks”ah$]”h&]”uh1hÄhjàh²hh³hÃh´M³ubeh}”(h]”Œpreventing-deadlock”ah ]”h"]”Œpreventing deadlock”ah$]”h&]”uh1hÄhj3h²hh³hÃh´MŸubhÅ)�”}”(hhh]”(hÊ)�”}”(hŒRacing Timers: A Kernel Pastime”h]”hŒRacing Timers: A Kernel Pastime”…”�”}”(hjMh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÉhjJh²hh³hÃh´M»ubhú)�”}”(hŒ¦Timers can produce their own special problems with races. Consider a collection of objects (list, hash, etc) where each object has a timer which is due to destroy it.”h]”hŒ¦Timers can produce their own special problems with races. Consider a collection of objects (list, hash, etc) where each object has a timer which is due to destroy it.”…”�”}”(hj[h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´M½hjJh²hubhú)�”}”(hŒbIf you want to destroy the entire collection (say on module removal), you might do the following::”h]”hŒaIf you want to destroy the entire collection (say on module removal), you might do the following:”…”�”}”(hjih²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´MÁhjJh²hubj~)�”}”(hX/* THIS CODE BAD BAD BAD BAD: IF IT WAS ANY WORSE IT WOULD USE HUNGARIAN NOTATION */ spin_lock_bh(&list_lock); while (list) { struct foo *next = list->next; timer_delete(&list->timer); kfree(list); list = next; } spin_unlock_bh(&list_lock);”h]”hX/* THIS CODE BAD BAD BAD BAD: IF IT WAS ANY WORSE IT WOULD USE HUNGARIAN NOTATION */ spin_lock_bh(&list_lock); while (list) { struct foo *next = list->next; timer_delete(&list->timer); kfree(list); list = next; } spin_unlock_bh(&list_lock);”…”�”}”hjwsbah}”(h]”h ]”h"]”h$]”h&]”j�jŽuh1j}h³hÃh´MÄhjJh²hubhú)�”}”(hŒåSooner or later, this will crash on SMP, because a timer can have just gone off before the spin_lock_bh(), and it will only get the lock after we spin_unlock_bh(), and then try to free the element (which has already been freed!).”h]”hŒåSooner or later, this will crash on SMP, because a timer can have just gone off before the spin_lock_bh(), and it will only get the lock after we spin_unlock_bh(), and then try to free the element (which has already been freed!).”…”�”}”(hj…h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´MÒhjJh²hubhú)�”}”(hŒµThis can be avoided by checking the result of timer_delete(): if it returns 1, the timer has been deleted. If 0, it means (in this case) that it is currently running, so we can do::”h]”hŒ´This can be avoided by checking the result of timer_delete(): if it returns 1, the timer has been deleted. If 0, it means (in this case) that it is currently running, so we can do:”…”�”}”(hj“h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´M×hjJh²hubj~)�”}”(hX¶retry: spin_lock_bh(&list_lock); while (list) { struct foo *next = list->next; if (!timer_delete(&list->timer)) { /* Give timer a chance to delete this */ spin_unlock_bh(&list_lock); goto retry; } kfree(list); list = next; } spin_unlock_bh(&list_lock);”h]”hX¶retry: spin_lock_bh(&list_lock); while (list) { struct foo *next = list->next; if (!timer_delete(&list->timer)) { /* Give timer a chance to delete this */ spin_unlock_bh(&list_lock); goto retry; } kfree(list); list = next; } spin_unlock_bh(&list_lock);”…”�”}”hj¡sbah}”(h]”h ]”h"]”h$]”h&]”j�jŽuh1j}h³hÃh´MÜhjJh²hubhú)�”}”(hXAnother common problem is deleting timers which restart themselves (by calling add_timer() at the end of their timer function). Because this is a fairly common case which is prone to races, you should use timer_delete_sync() (``include/linux/timer.h``) to handle this case.”h]”(hŒâAnother common problem is deleting timers which restart themselves (by calling add_timer() at the end of their timer function). Because this is a fairly common case which is prone to races, you should use timer_delete_sync() (”…”�”}”(hj¯h²hh³Nh´NubjI)�”}”(hŒ``include/linux/timer.h``”h]”hŒinclude/linux/timer.h”…”�”}”(hj·h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jHhj¯ubhŒ) to handle this case.”…”�”}”(hj¯h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´MíhjJh²hubhú)�”}”(hŒÎBefore freeing a timer, timer_shutdown() or timer_shutdown_sync() should be called which will keep it from being rearmed. Any subsequent attempt to rearm the timer will be silently ignored by the core code.”h]”hŒÎBefore freeing a timer, timer_shutdown() or timer_shutdown_sync() should be called which will keep it from being rearmed. Any subsequent attempt to rearm the timer will be silently ignored by the core code.”…”�”}”(hjÏh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´MòhjJh²hubeh}”(h]”Œracing-timers-a-kernel-pastime”ah ]”h"]”Œracing timers: a kernel pastime”ah$]”h&]”uh1hÄhj3h²hh³hÃh´M»ubeh}”(h]”Œcommon-problems”ah ]”h"]”Œcommon problems”ah$]”h&]”uh1hÄhhÆh²hh³hÃh´MhubhÅ)�”}”(hhh]”(hÊ)�”}”(hŒ Locking Speed”h]”hŒ Locking Speed”…”�”}”(hjðh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÉhjíh²hh³hÃh´Møubhú)�”}”(hX¤There are three main things to worry about when considering speed of some code which does locking. First is concurrency: how many things are going to be waiting while someone else is holding a lock. Second is the time taken to actually acquire and release an uncontended lock. Third is using fewer, or smarter locks. I'm assuming that the lock is used fairly often: otherwise, you wouldn't be concerned about efficiency.”h]”hX¨There are three main things to worry about when considering speed of some code which does locking. First is concurrency: how many things are going to be waiting while someone else is holding a lock. Second is the time taken to actually acquire and release an uncontended lock. Third is using fewer, or smarter locks. I’m assuming that the lock is used fairly often: otherwise, you wouldn’t be concerned about efficiency.”…”�”}”(hjþh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´Múhjíh²hubhú)�”}”(hX Concurrency depends on how long the lock is usually held: you should hold the lock for as long as needed, but no longer. In the cache example, we always create the object without the lock held, and then grab the lock only when we are ready to insert it in the list.”h]”hX Concurrency depends on how long the lock is usually held: you should hold the lock for as long as needed, but no longer. In the cache example, we always create the object without the lock held, and then grab the lock only when we are ready to insert it in the list.”…”�”}”(hj h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´Mhjíh²hubhú)�”}”(hXoAcquisition times depend on how much damage the lock operations do to the pipeline (pipeline stalls) and how likely it is that this CPU was the last one to grab the lock (ie. is the lock cache-hot for this CPU): on a machine with more CPUs, this likelihood drops fast. Consider a 700MHz Intel Pentium III: an instruction takes about 0.7ns, an atomic increment takes about 58ns, a lock which is cache-hot on this CPU takes 160ns, and a cacheline transfer from another CPU takes an additional 170 to 360ns. (These figures from Paul McKenney's `Linux Journal RCU article `__).”h]”(hXAcquisition times depend on how much damage the lock operations do to the pipeline (pipeline stalls) and how likely it is that this CPU was the last one to grab the lock (ie. is the lock cache-hot for this CPU): on a machine with more CPUs, this likelihood drops fast. Consider a 700MHz Intel Pentium III: an instruction takes about 0.7ns, an atomic increment takes about 58ns, a lock which is cache-hot on this CPU takes 160ns, and a cacheline transfer from another CPU takes an additional 170 to 360ns. (These figures from Paul McKenney’s ”…”�”}”(hjh²hh³Nh´Nubj})�”}”(hŒP`Linux Journal RCU article `__”h]”hŒLinux Journal RCU article”…”�”}”(hj"h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”Œname”ŒLinux Journal RCU article”Œrefuri”Œ0http://www.linuxjournal.com/article.php?sid=6993”uh1j|hjubhŒ).”…”�”}”(hjh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´Mhjíh²hubhú)�”}”(hX;These two aims conflict: holding a lock for a short time might be done by splitting locks into parts (such as in our final per-object-lock example), but this increases the number of lock acquisitions, and the results are often slower than having a single lock. This is another reason to advocate locking simplicity.”h]”hX;These two aims conflict: holding a lock for a short time might be done by splitting locks into parts (such as in our final per-object-lock example), but this increases the number of lock acquisitions, and the results are often slower than having a single lock. This is another reason to advocate locking simplicity.”…”�”}”(hj>h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´Mhjíh²hubhú)�”}”(hŒtThe third concern is addressed below: there are some methods to reduce the amount of locking which needs to be done.”h]”hŒtThe third concern is addressed below: there are some methods to reduce the amount of locking which needs to be done.”…”�”}”(hjLh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´Mhjíh²hubhÅ)�”}”(hhh]”(hÊ)�”}”(hŒRead/Write Lock Variants”h]”hŒRead/Write Lock Variants”…”�”}”(hj]h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÉhjZh²hh³hÃh´Mubhú)�”}”(hXfBoth spinlocks and mutexes have read/write variants: ``rwlock_t`` and :c:type:`struct rw_semaphore `. These divide users into two classes: the readers and the writers. If you are only reading the data, you can get a read lock, but to write to the data you need the write lock. Many people can hold a read lock, but a writer must be sole holder.”h]”(hŒ5Both spinlocks and mutexes have read/write variants: ”…”�”}”(hjkh²hh³Nh´NubjI)�”}”(hŒ ``rwlock_t``”h]”hŒrwlock_t”…”�”}”(hjsh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jHhjkubhŒ and ”…”�”}”(hjkh²hh³Nh´Nubh)�”}”(hŒ,:c:type:`struct rw_semaphore `”h]”jI)�”}”(hj‡h]”hŒstruct rw_semaphore”…”�”}”(hj‰h²hh³Nh´Nubah}”(h]”h ]”(jTjUŒc-type”eh"]”h$]”h&]”uh1jHhj…ubah}”(h]”h ]”h"]”h$]”h&]”Œrefdoc”jaŒ refdomain”jUŒreftype”Œtype”Œ refexplicit”ˆŒrefwarn”‰jgŒ rw_semaphore”uh1hh³hÃh´MhjkubhŒô. These divide users into two classes: the readers and the writers. If you are only reading the data, you can get a read lock, but to write to the data you need the write lock. Many people can hold a read lock, but a writer must be sole holder.”…”�”}”(hjkh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´MhjZh²hubhú)�”}”(hXIf your code divides neatly along reader/writer lines (as our cache code does), and the lock is held by readers for significant lengths of time, using these locks can help. They are slightly slower than the normal locks though, so in practice ``rwlock_t`` is not usually worthwhile.”h]”(hŒóIf your code divides neatly along reader/writer lines (as our cache code does), and the lock is held by readers for significant lengths of time, using these locks can help. They are slightly slower than the normal locks though, so in practice ”…”�”}”(hj®h²hh³Nh´NubjI)�”}”(hŒ ``rwlock_t``”h]”hŒrwlock_t”…”�”}”(hj¶h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jHhj®ubhŒ is not usually worthwhile.”…”�”}”(hj®h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´M#hjZh²hubeh}”(h]”Œread-write-lock-variants”ah ]”h"]”Œread/write lock variants”ah$]”h&]”uh1hÄhjíh²hh³hÃh´MubhÅ)�”}”(hhh]”(hÊ)�”}”(hŒ Avoiding Locks: Read Copy Update”h]”hŒ Avoiding Locks: Read Copy Update”…”�”}”(hjÙh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÉhjÖh²hh³hÃh´M)ubhú)�”}”(hXThere is a special method of read/write locking called Read Copy Update. Using RCU, the readers can avoid taking a lock altogether: as we expect our cache to be read more often than updated (otherwise the cache is a waste of time), it is a candidate for this optimization.”h]”hXThere is a special method of read/write locking called Read Copy Update. Using RCU, the readers can avoid taking a lock altogether: as we expect our cache to be read more often than updated (otherwise the cache is a waste of time), it is a candidate for this optimization.”…”�”}”(hjçh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´M+hjÖh²hubhú)�”}”(hXLHow do we get rid of read locks? Getting rid of read locks means that writers may be changing the list underneath the readers. That is actually quite simple: we can read a linked list while an element is being added if the writer adds the element very carefully. For example, adding ``new`` to a single linked list called ``list``::”h]”(hXHow do we get rid of read locks? Getting rid of read locks means that writers may be changing the list underneath the readers. That is actually quite simple: we can read a linked list while an element is being added if the writer adds the element very carefully. For example, adding ”…”�”}”(hjõh²hh³Nh´NubjI)�”}”(hŒ``new``”h]”hŒnew”…”�”}”(hjýh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jHhjõubhŒ to a single linked list called ”…”�”}”(hjõh²hh³Nh´NubjI)�”}”(hŒ``list``”h]”hŒlist”…”�”}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jHhjõubhŒ:”…”�”}”(hjõh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´M0hjÖh²hubj~)�”}”(hŒ0new->next = list->next; wmb(); list->next = new;”h]”hŒ0new->next = list->next; wmb(); list->next = new;”…”�”}”hj'sbah}”(h]”h ]”h"]”h$]”h&]”j�jŽuh1j}h³hÃh´M6hjÖh²hubhú)�”}”(hXîThe wmb() is a write memory barrier. It ensures that the first operation (setting the new element's ``next`` pointer) is complete and will be seen by all CPUs, before the second operation is (putting the new element into the list). This is important, since modern compilers and modern CPUs can both reorder instructions unless told otherwise: we want a reader to either not see the new element at all, or see the new element with the ``next`` pointer correctly pointing at the rest of the list.”h]”(hŒfThe wmb() is a write memory barrier. It ensures that the first operation (setting the new element’s ”…”�”}”(hj5h²hh³Nh´NubjI)�”}”(hŒ``next``”h]”hŒnext”…”�”}”(hj=h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jHhj5ubhXF pointer) is complete and will be seen by all CPUs, before the second operation is (putting the new element into the list). This is important, since modern compilers and modern CPUs can both reorder instructions unless told otherwise: we want a reader to either not see the new element at all, or see the new element with the ”…”�”}”(hj5h²hh³Nh´NubjI)�”}”(hŒ``next``”h]”hŒnext”…”�”}”(hjOh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jHhj5ubhŒ4 pointer correctly pointing at the rest of the list.”…”�”}”(hj5h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´M;hjÖh²hubhú)�”}”(hŒ‘Fortunately, there is a function to do this for standard :c:type:`struct list_head ` lists: list_add_rcu() (``include/linux/list.h``).”h]”(hŒ9Fortunately, there is a function to do this for standard ”…”�”}”(hjgh²hh³Nh´Nubh)�”}”(hŒ&:c:type:`struct list_head `”h]”jI)�”}”(hjqh]”hŒstruct list_head”…”�”}”(hjsh²hh³Nh´Nubah}”(h]”h ]”(jTjUŒc-type”eh"]”h$]”h&]”uh1jHhjoubah}”(h]”h ]”h"]”h$]”h&]”Œrefdoc”jaŒ refdomain”jUŒreftype”Œtype”Œ refexplicit”ˆŒrefwarn”‰jgŒ list_head”uh1hh³hÃh´MDhjgubhŒ lists: list_add_rcu() (”…”�”}”(hjgh²hh³Nh´NubjI)�”}”(hŒ``include/linux/list.h``”h]”hŒinclude/linux/list.h”…”�”}”(hj’h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jHhjgubhŒ).”…”�”}”(hjgh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´MDhjÖh²hubhú)�”}”(hŒ®Removing an element from the list is even simpler: we replace the pointer to the old element with a pointer to its successor, and readers will either see it, or skip over it.”h]”hŒ®Removing an element from the list is even simpler: we replace the pointer to the old element with a pointer to its successor, and readers will either see it, or skip over it.”…”�”}”(hjªh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´MHhjÖh²hubj~)�”}”(hŒlist->next = old->next;”h]”hŒlist->next = old->next;”…”�”}”hj¸sbah}”(h]”h ]”h"]”h$]”h&]”j�jŽuh1j}h³hÃh´MNhjÖh²hubhú)�”}”(hŒ„There is list_del_rcu() (``include/linux/list.h``) which does this (the normal version poisons the old object, which we don't want).”h]”(hŒThere is list_del_rcu() (”…”�”}”(hjÆh²hh³Nh´NubjI)�”}”(hŒ``include/linux/list.h``”h]”hŒinclude/linux/list.h”…”�”}”(hjÎh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jHhjÆubhŒU) which does this (the normal version poisons the old object, which we don’t want).”…”�”}”(hjÆh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´MQhjÖh²hubhú)�”}”(hXµThe reader must also be careful: some CPUs can look through the ``next`` pointer to start reading the contents of the next element early, but don't realize that the pre-fetched contents is wrong when the ``next`` pointer changes underneath them. Once again, there is a list_for_each_entry_rcu() (``include/linux/list.h``) to help you. Of course, writers can just use list_for_each_entry(), since there cannot be two simultaneous writers.”h]”(hŒ@The reader must also be careful: some CPUs can look through the ”…”�”}”(hjæh²hh³Nh´NubjI)�”}”(hŒ``next``”h]”hŒnext”…”�”}”(hjîh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jHhjæubhŒ† pointer to start reading the contents of the next element early, but don’t realize that the pre-fetched contents is wrong when the ”…”�”}”(hjæh²hh³Nh´NubjI)�”}”(hŒ``next``”h]”hŒnext”…”�”}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jHhjæubhŒT pointer changes underneath them. Once again, there is a list_for_each_entry_rcu() (”…”�”}”(hjæh²hh³Nh´NubjI)�”}”(hŒ``include/linux/list.h``”h]”hŒinclude/linux/list.h”…”�”}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jHhjæubhŒu) to help you. Of course, writers can just use list_for_each_entry(), since there cannot be two simultaneous writers.”…”�”}”(hjæh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´MUhjÖh²hubhú)�”}”(hXYOur final dilemma is this: when can we actually destroy the removed element? Remember, a reader might be stepping through this element in the list right now: if we free this element and the ``next`` pointer changes, the reader will jump off into garbage and crash. We need to wait until we know that all the readers who were traversing the list when we deleted the element are finished. We use call_rcu() to register a callback which will actually destroy the object once all pre-existing readers are finished. Alternatively, synchronize_rcu() may be used to block until all pre-existing are finished.”h]”(hŒ¾Our final dilemma is this: when can we actually destroy the removed element? Remember, a reader might be stepping through this element in the list right now: if we free this element and the ”…”�”}”(hj*h²hh³Nh´NubjI)�”}”(hŒ``next``”h]”hŒnext”…”�”}”(hj2h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jHhj*ubhX“ pointer changes, the reader will jump off into garbage and crash. We need to wait until we know that all the readers who were traversing the list when we deleted the element are finished. We use call_rcu() to register a callback which will actually destroy the object once all pre-existing readers are finished. Alternatively, synchronize_rcu() may be used to block until all pre-existing are finished.”…”�”}”(hj*h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´M^hjÖh²hubhú)�”}”(hX But how does Read Copy Update know when the readers are finished? The method is this: firstly, the readers always traverse the list inside rcu_read_lock()/rcu_read_unlock() pairs: these simply disable preemption so the reader won't go to sleep while reading the list.”h]”hX But how does Read Copy Update know when the readers are finished? The method is this: firstly, the readers always traverse the list inside rcu_read_lock()/rcu_read_unlock() pairs: these simply disable preemption so the reader won’t go to sleep while reading the list.”…”�”}”(hjJh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´MihjÖh²hubhú)�”}”(hX9RCU then waits until every other CPU has slept at least once: since readers cannot sleep, we know that any readers which were traversing the list during the deletion are finished, and the callback is triggered. The real Read Copy Update code is a little more optimized than this, but this is the fundamental idea.”h]”hX9RCU then waits until every other CPU has slept at least once: since readers cannot sleep, we know that any readers which were traversing the list during the deletion are finished, and the callback is triggered. The real Read Copy Update code is a little more optimized than this, but this is the fundamental idea.”…”�”}”(hjXh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´MohjÖh²hubj~)�”}”(hXÄ--- cache.c.perobjectlock 2003-12-11 17:15:03.000000000 +1100 +++ cache.c.rcupdate 2003-12-11 17:55:14.000000000 +1100 @@ -1,15 +1,18 @@ #include #include #include +#include #include #include struct object { - /* These two protected by cache_lock. */ + /* This is protected by RCU */ struct list_head list; int popularity; + struct rcu_head rcu; + atomic_t refcnt; /* Doesn't change once created. */ @@ -40,7 +43,7 @@ { struct object *i; - list_for_each_entry(i, &cache, list) { + list_for_each_entry_rcu(i, &cache, list) { if (i->id == id) { i->popularity++; return i; @@ -49,19 +52,25 @@ return NULL; } +/* Final discard done once we know no readers are looking. */ +static void cache_delete_rcu(void *arg) +{ + object_put(arg); +} + /* Must be holding cache_lock */ static void __cache_delete(struct object *obj) { BUG_ON(!obj); - list_del(&obj->list); - object_put(obj); + list_del_rcu(&obj->list); cache_num--; + call_rcu(&obj->rcu, cache_delete_rcu); } /* Must be holding cache_lock */ static void __cache_add(struct object *obj) { - list_add(&obj->list, &cache); + list_add_rcu(&obj->list, &cache); if (++cache_num > MAX_CACHE_SIZE) { struct object *i, *outcast = NULL; list_for_each_entry(i, &cache, list) { @@ -104,12 +114,11 @@ struct object *cache_find(int id) { struct object *obj; - unsigned long flags; - spin_lock_irqsave(&cache_lock, flags); + rcu_read_lock(); obj = __cache_find(id); if (obj) object_get(obj); - spin_unlock_irqrestore(&cache_lock, flags); + rcu_read_unlock(); return obj; }”•h]”hXÄ--- cache.c.perobjectlock 2003-12-11 17:15:03.000000000 +1100 +++ cache.c.rcupdate 2003-12-11 17:55:14.000000000 +1100 @@ -1,15 +1,18 @@ #include #include #include +#include #include #include struct object { - /* These two protected by cache_lock. */ + /* This is protected by RCU */ struct list_head list; int popularity; + struct rcu_head rcu; + atomic_t refcnt; /* Doesn't change once created. */ @@ -40,7 +43,7 @@ { struct object *i; - list_for_each_entry(i, &cache, list) { + list_for_each_entry_rcu(i, &cache, list) { if (i->id == id) { i->popularity++; return i; @@ -49,19 +52,25 @@ return NULL; } +/* Final discard done once we know no readers are looking. */ +static void cache_delete_rcu(void *arg) +{ + object_put(arg); +} + /* Must be holding cache_lock */ static void __cache_delete(struct object *obj) { BUG_ON(!obj); - list_del(&obj->list); - object_put(obj); + list_del_rcu(&obj->list); cache_num--; + call_rcu(&obj->rcu, cache_delete_rcu); } /* Must be holding cache_lock */ static void __cache_add(struct object *obj) { - list_add(&obj->list, &cache); + list_add_rcu(&obj->list, &cache); if (++cache_num > MAX_CACHE_SIZE) { struct object *i, *outcast = NULL; list_for_each_entry(i, &cache, list) { @@ -104,12 +114,11 @@ struct object *cache_find(int id) { struct object *obj; - unsigned long flags; - spin_lock_irqsave(&cache_lock, flags); + rcu_read_lock(); obj = __cache_find(id); if (obj) object_get(obj); - spin_unlock_irqrestore(&cache_lock, flags); + rcu_read_unlock(); return obj; }”…”�”}”hjfsbah}”(h]”h ]”h"]”h$]”h&]”j�jŽuh1j}h³hÃh´MwhjÖh²hubhú)�”}”(hX Note that the reader will alter the popularity member in __cache_find(), and now it doesn't hold a lock. One solution would be to make it an ``atomic_t``, but for this usage, we don't really care about races: an approximate result is good enough, so I didn't change it.”h]”(hŒ�Note that the reader will alter the popularity member in __cache_find(), and now it doesn’t hold a lock. One solution would be to make it an ”…”�”}”(hjth²hh³Nh´NubjI)�”}”(hŒ ``atomic_t``”h]”hŒatomic_t”…”�”}”(hj|h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jHhjtubhŒx, but for this usage, we don’t really care about races: an approximate result is good enough, so I didn’t change it.”…”�”}”(hjth²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´MÃhjÖh²hubhú)�”}”(hŒ‡The result is that cache_find() requires no synchronization with any other functions, so is almost as fast on SMP as it would be on UP.”h]”hŒ‡The result is that cache_find() requires no synchronization with any other functions, so is almost as fast on SMP as it would be on UP.”…”�”}”(hj”h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´MÉhjÖh²hubhú)�”}”(hX6There is a further optimization possible here: remember our original cache code, where there were no reference counts and the caller simply held the lock whenever using the object? This is still possible: if you hold the lock, no one can delete the object, so you don't need to get and put the reference count.”h]”hX8There is a further optimization possible here: remember our original cache code, where there were no reference counts and the caller simply held the lock whenever using the object? This is still possible: if you hold the lock, no one can delete the object, so you don’t need to get and put the reference count.”…”�”}”(hj¢h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´MÍhjÖh²hubhú)�”}”(hX;Now, because the 'read lock' in RCU is simply disabling preemption, a caller which always has preemption disabled between calling cache_find() and object_put() does not need to actually get and put the reference count: we could expose __cache_find() by making it non-static, and such callers could simply call that.”h]”hX?Now, because the ‘read lock’ in RCU is simply disabling preemption, a caller which always has preemption disabled between calling cache_find() and object_put() does not need to actually get and put the reference count: we could expose __cache_find() by making it non-static, and such callers could simply call that.”…”�”}”(hj°h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´MÓhjÖh²hubhú)�”}”(hŒšThe benefit here is that the reference count is not written to: the object is not altered in any way, which is much faster on SMP machines due to caching.”h]”hŒšThe benefit here is that the reference count is not written to: the object is not altered in any way, which is much faster on SMP machines due to caching.”…”�”}”(hj¾h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´MÚhjÖh²hubeh}”(h]”Œavoiding-locks-read-copy-update”ah ]”h"]”Œ avoiding locks: read copy update”ah$]”h&]”uh1hÄhjíh²hh³hÃh´M)ubhÅ)�”}”(hhh]”(hÊ)�”}”(hŒ Per-CPU Data”h]”hŒ Per-CPU Data”…”�”}”(hj×h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÉhjÔh²hh³hÃh´Mßubhú)�”}”(hŒïAnother technique for avoiding locking which is used fairly widely is to duplicate information for each CPU. For example, if you wanted to keep a count of a common condition, you could use a spin lock and a single counter. Nice and simple.”h]”hŒïAnother technique for avoiding locking which is used fairly widely is to duplicate information for each CPU. For example, if you wanted to keep a count of a common condition, you could use a spin lock and a single counter. Nice and simple.”…”�”}”(hjåh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´MáhjÔh²hubhú)�”}”(hXIf that was too slow (it's usually not, but if you've got a really big machine to test on and can show that it is), you could instead use a counter for each CPU, then none of them need an exclusive lock. See DEFINE_PER_CPU(), get_cpu_var() and put_cpu_var() (``include/linux/percpu.h``).”h]”(hXIf that was too slow (it’s usually not, but if you’ve got a really big machine to test on and can show that it is), you could instead use a counter for each CPU, then none of them need an exclusive lock. See DEFINE_PER_CPU(), get_cpu_var() and put_cpu_var() (”…”�”}”(hjóh²hh³Nh´NubjI)�”}”(hŒ``include/linux/percpu.h``”h]”hŒinclude/linux/percpu.h”…”�”}”(hjûh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jHhjóubhŒ).”…”�”}”(hjóh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´MæhjÔh²hubhú)�”}”(hŒÐOf particular use for simple per-cpu counters is the ``local_t`` type, and the cpu_local_inc() and related functions, which are more efficient than simple code on some architectures (``include/asm/local.h``).”h]”(hŒ5Of particular use for simple per-cpu counters is the ”…”�”}”(hjh²hh³Nh´NubjI)�”}”(hŒ ``local_t``”h]”hŒlocal_t”…”�”}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jHhjubhŒw type, and the cpu_local_inc() and related functions, which are more efficient than simple code on some architectures (”…”�”}”(hjh²hh³Nh´NubjI)�”}”(hŒ``include/asm/local.h``”h]”hŒinclude/asm/local.h”…”�”}”(hj-h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jHhjubhŒ).”…”�”}”(hjh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´MìhjÔh²hubhú)�”}”(hŒœNote that there is no simple, reliable way of getting an exact value of such a counter, without introducing more locks. This is not a problem for some uses.”h]”hŒœNote that there is no simple, reliable way of getting an exact value of such a counter, without introducing more locks. This is not a problem for some uses.”…”�”}”(hjEh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´MñhjÔh²hubeh}”(h]”jtah ]”h"]”Œ per-cpu data”ah$]”h&]”uh1hÄhjíh²hh³hÃh´Mßjœ KubhÅ)�”}”(hhh]”(hÊ)�”}”(hŒ(Data Which Mostly Used By An IRQ Handler”h]”hŒ(Data Which Mostly Used By An IRQ Handler”…”�”}”(hj]h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÉhjZh²hh³hÃh´Möubhú)�”}”(hŒ»If data is always accessed from within the same IRQ handler, you don't need a lock at all: the kernel already guarantees that the irq handler will not run simultaneously on multiple CPUs.”h]”hŒ½If data is always accessed from within the same IRQ handler, you don’t need a lock at all: the kernel already guarantees that the irq handler will not run simultaneously on multiple CPUs.”…”�”}”(hjkh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´MøhjZh²hubhú)�”}”(hŒÖManfred Spraul points out that you can still do this, even if the data is very occasionally accessed in user context or softirqs/tasklets. The irq handler doesn't use a lock, and all other accesses are done as so::”h]”hŒ×Manfred Spraul points out that you can still do this, even if the data is very occasionally accessed in user context or softirqs/tasklets. The irq handler doesn’t use a lock, and all other accesses are done as so:”…”�”}”(hjyh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´MühjZh²hubj~)�”}”(hŒNmutex_lock(&lock); disable_irq(irq); ... enable_irq(irq); mutex_unlock(&lock);”h]”hŒNmutex_lock(&lock); disable_irq(irq); ... enable_irq(irq); mutex_unlock(&lock);”…”�”}”hj‡sbah}”(h]”h ]”h"]”h$]”h&]”j�jŽuh1j}h³hÃh´MhjZh²hubhú)�”}”(hXFThe disable_irq() prevents the irq handler from running (and waits for it to finish if it's currently running on other CPUs). The spinlock prevents any other accesses happening at the same time. Naturally, this is slower than just a spin_lock_irq() call, so it only makes sense if this type of access happens extremely rarely.”h]”hXHThe disable_irq() prevents the irq handler from running (and waits for it to finish if it’s currently running on other CPUs). The spinlock prevents any other accesses happening at the same time. Naturally, this is slower than just a spin_lock_irq() call, so it only makes sense if this type of access happens extremely rarely.”…”�”}”(hj•h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´MhjZh²hubeh}”(h]”Œ(data-which-mostly-used-by-an-irq-handler”ah ]”h"]”Œ(data which mostly used by an irq handler”ah$]”h&]”uh1hÄhjíh²hh³hÃh´Möubeh}”(h]”Œ locking-speed”ah ]”h"]”Œ locking speed”ah$]”h&]”uh1hÄhhÆh²hh³hÃh´MøubhÅ)�”}”(hhh]”(hÊ)�”}”(hŒ0What Functions Are Safe To Call From Interrupts?”h]”hŒ0What Functions Are Safe To Call From Interrupts?”…”�”}”(hj¶h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÉhj³h²hh³hÃh´Mubhú)�”}”(hŒúMany functions in the kernel sleep (ie. call schedule()) directly or indirectly: you can never call them while holding a spinlock, or with preemption disabled. This also means you need to be in user context: calling them from an interrupt is illegal.”h]”hŒúMany functions in the kernel sleep (ie. call schedule()) directly or indirectly: you can never call them while holding a spinlock, or with preemption disabled. This also means you need to be in user context: calling them from an interrupt is illegal.”…”�”}”(hjÄh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´Mhj³h²hubhÅ)�”}”(hhh]”(hÊ)�”}”(hŒSome Functions Which Sleep”h]”hŒSome Functions Which Sleep”…”�”}”(hjÕh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÉhjÒh²hh³hÃh´Mubhú)�”}”(hX=The most common ones are listed below, but you usually have to read the code to find out if other calls are safe. If everyone else who calls it can sleep, you probably need to be able to sleep, too. In particular, registration and deregistration functions usually expect to be called from user context, and can sleep.”h]”hX=The most common ones are listed below, but you usually have to read the code to find out if other calls are safe. If everyone else who calls it can sleep, you probably need to be able to sleep, too. In particular, registration and deregistration functions usually expect to be called from user context, and can sleep.”…”�”}”(hjãh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´MhjÒh²hubj½ )�”}”(hhh]”(j )�”}”(hŒ]Accesses to userspace: - copy_from_user() - copy_to_user() - get_user() - put_user() ”h]”(hú)�”}”(hŒAccesses to userspace:”h]”hŒAccesses to userspace:”…”�”}”(hjøh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´Mhjôubj½ )�”}”(hhh]”(j )�”}”(hŒcopy_from_user() ”h]”hú)�”}”(hŒcopy_from_user()”h]”hŒcopy_from_user()”…”�”}”(hj h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´M hj ubah}”(h]”h ]”h"]”h$]”h&]”uh1jÁ hj ubj )�”}”(hŒcopy_to_user() ”h]”hú)�”}”(hŒcopy_to_user()”h]”hŒcopy_to_user()”…”�”}”(hj% h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´M"hj! ubah}”(h]”h ]”h"]”h$]”h&]”uh1jÁ hj ubj )�”}”(hŒ get_user() ”h]”hú)�”}”(hŒ get_user()”h]”hŒ get_user()”…”�”}”(hj= h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´M$hj9 ubah}”(h]”h ]”h"]”h$]”h&]”uh1jÁ hj ubj )�”}”(hŒ put_user() ”h]”hú)�”}”(hŒ put_user()”h]”hŒ put_user()”…”�”}”(hjU h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´M&hjQ ubah}”(h]”h ]”h"]”h$]”h&]”uh1jÁ hj ubeh}”(h]”h ]”h"]”h$]”h&]”j5 j6 uh1j¼ h³hÃh´M hjôubeh}”(h]”h ]”h"]”h$]”h&]”uh1jÁ hjñh²hh³Nh´Nubj )�”}”(hŒkmalloc(GFP_KERNEL) ”h]”hú)�”}”(hŒkmalloc(GFP_KERNEL) ”h]”hŒkmalloc(GFP_KERNEL) ”…”�”}”(hjy h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´M(hju ubah}”(h]”h ]”h"]”h$]”h&]”uh1jÁ hjñh²hh³hÃh´Nubj )�”}”(hXWmutex_lock_interruptible() and mutex_lock() There is a mutex_trylock() which does not sleep. Still, it must not be used inside interrupt context since its implementation is not safe for that. mutex_unlock() will also never sleep. It cannot be used in interrupt context either since a mutex must be released by the same task that acquired it. ”h]”(hú)�”}”(hŒ+mutex_lock_interruptible() and mutex_lock()”h]”hŒ+mutex_lock_interruptible() and mutex_lock()”…”�”}”(hj‘ h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´M*hj� ubhú)�”}”(hX)There is a mutex_trylock() which does not sleep. Still, it must not be used inside interrupt context since its implementation is not safe for that. mutex_unlock() will also never sleep. It cannot be used in interrupt context either since a mutex must be released by the same task that acquired it.”h]”hX)There is a mutex_trylock() which does not sleep. Still, it must not be used inside interrupt context since its implementation is not safe for that. mutex_unlock() will also never sleep. It cannot be used in interrupt context either since a mutex must be released by the same task that acquired it.”…”�”}”(hjŸ h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´M-hj� ubeh}”(h]”h ]”h"]”h$]”h&]”uh1jÁ hjñh²hh³hÃh´Nubeh}”(h]”h ]”h"]”h$]”h&]”j5 j6 uh1j¼ h³hÃh´MhjÒh²hubeh}”(h]”Œsome-functions-which-sleep”ah ]”h"]”Œsome functions which sleep”ah$]”h&]”uh1hÄhj³h²hh³hÃh´MubhÅ)�”}”(hhh]”(hÊ)�”}”(hŒ Some Functions Which Don't Sleep”h]”hŒ"Some Functions Which Don’t Sleep”…”�”}”(hjÄ h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÉhjÁ h²hh³hÃh´M4ubhú)�”}”(hŒMSome functions are safe to call from any context, or holding almost any lock.”h]”hŒMSome functions are safe to call from any context, or holding almost any lock.”…”�”}”(hjÒ h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´M6hjÁ h²hubj½ )�”}”(hhh]”(j )�”}”(hŒ printk() ”h]”hú)�”}”(hŒprintk()”h]”hŒprintk()”…”�”}”(hjç h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´M9hjã ubah}”(h]”h ]”h"]”h$]”h&]”uh1jÁ hjà h²hh³hÃh´Nubj )�”}”(hŒkfree() ”h]”hú)�”}”(hŒkfree()”h]”hŒkfree()”…”�”}”(hjÿ h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´M;hjû ubah}”(h]”h ]”h"]”h$]”h&]”uh1jÁ hjà h²hh³hÃh´Nubj )�”}”(hŒadd_timer() and timer_delete() ”h]”hú)�”}”(hŒadd_timer() and timer_delete()”h]”hŒadd_timer() and timer_delete()”…”�”}”(hj!h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´M=hj!ubah}”(h]”h ]”h"]”h$]”h&]”uh1jÁ hjà h²hh³hÃh´Nubeh}”(h]”h ]”h"]”h$]”h&]”j5 j6 uh1j¼ h³hÃh´M9hjÁ h²hubeh}”(h]”Œ some-functions-which-don-t-sleep”ah ]”h"]”Œ some functions which don't sleep”ah$]”h&]”uh1hÄhj³h²hh³hÃh´M4ubeh}”(h]”jŽah ]”h"]”Œ0what functions are safe to call from interrupts?”ah$]”h&]”uh1hÄhhÆh²hh³hÃh´Mjœ KubhÅ)�”}”(hhh]”(hÊ)�”}”(hŒMutex API reference”h]”hŒMutex API reference”…”�”}”(hjC!h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÉhj@!h²hh³hÃh´M@ubhŒindex”“”)�”}”(hhh]”h}”(h]”h ]”h"]”h$]”h&]”Œentries”]”(Œsingle”Œmutex_init (C macro)”Œ c.mutex_init”hNt”auh1jQ!hj@!h²hh³Nh´NubhŒdesc”“”)�”}”(hhh]”(hŒdesc_signature”“”)�”}”(hŒ mutex_init”h]”hŒdesc_signature_line”“”)�”}”(hŒ mutex_init”h]”hŒ desc_name”“”)�”}”(hŒ mutex_init”h]”hŒ desc_sig_name”“”)�”}”(hjk!h]”hŒ mutex_init”…”�”}”(hj{!h²hh³Nh´Nubah}”(h]”h ]”Œn”ah"]”h$]”h&]”uh1jy!hju!ubah}”(h]”h ]”(Œsig-name”Œdescname”eh"]”h$]”h&]”j�jŽuh1js!hjo!h²hh³Œ^/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1346: ./include/linux/mutex.h”h´K5ubah}”(h]”h ]”h"]”h$]”h&]”j�jŽŒ add_permalink”ˆuh1jm!Œsphinx_line_type”Œ declarator”hji!h²hh³j‘!h´K5ubah}”(h]”j`!ah ]”(Œsig”Œ sig-object”eh"]”h$]”h&]”Œ is_multiline”ˆŒ _toc_parts”)Œ _toc_name”huh1jg!h³j‘!h´K5hjd!h²hubhŒ desc_content”“”)�”}”(hhh]”h}”(h]”h ]”h"]”h$]”h&]”uh1j¦!hjd!h²hh³j‘!h´K5ubeh}”(h]”h ]”(jUŒmacro”eh"]”h$]”h&]”Œdomain”jUŒobjtype”j´!Œdesctype”j´!Œnoindex”‰Œ noindexentry”‰Œnocontentsentry”‰uh1jb!h²hhj@!h³Nh´Nubhú)�”}”(hŒ``mutex_init (mutex)``”h]”jI)�”}”(hjÀ!h]”hŒmutex_init (mutex)”…”�”}”(hjÂ!h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jHhj¾!ubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³Œ^/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1346: ./include/linux/mutex.h”h´K7hj@!h²hubhŒ block_quote”“”)�”}”(hŒinitialize the mutex ”h]”hú)�”}”(hŒinitialize the mutex”h]”hŒinitialize the mutex”…”�”}”(hjÜ!h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³Œ^/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1346: ./include/linux/mutex.h”h´K5hjØ!ubah}”(h]”h ]”h"]”h$]”h&]”uh1jÖ!h³jê!h´K5hj@!h²hubhŒ container”“”)�”}”(hŒ«**Parameters** ``mutex`` the mutex to be initialized **Description** Initialize the mutex to unlocked state. It is not allowed to initialize an already locked mutex.”h]”(hú)�”}”(hŒ**Parameters**”h]”j)�”}”(hjù!h]”hŒ Parameters”…”�”}”(hjû!h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhj÷!ubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³Œ^/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1346: ./include/linux/mutex.h”h´K9hjó!ubhŒdefinition_list”“”)�”}”(hhh]”hŒdefinition_list_item”“”)�”}”(hŒ&``mutex`` the mutex to be initialized ”h]”(hŒterm”“”)�”}”(hŒ ``mutex``”h]”jI)�”}”(hj"h]”hŒmutex”…”�”}”(hj "h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jHhj"ubah}”(h]”h ]”h"]”h$]”h&]”uh1j"h³Œ^/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1346: ./include/linux/mutex.h”h´K6hj"ubhŒ definition”“”)�”}”(hhh]”hú)�”}”(hŒthe mutex to be initialized”h]”hŒthe mutex to be initialized”…”�”}”(hj9"h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³j3"h´K6hj6"ubah}”(h]”h ]”h"]”h$]”h&]”uh1j4"hj"ubeh}”(h]”h ]”h"]”h$]”h&]”uh1j"h³j3"h´K6hj"ubah}”(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&]”uh1jhjY"ubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³Œ^/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1346: ./include/linux/mutex.h”h´K8hjó!ubhú)�”}”(hŒ'Initialize the mutex to unlocked state.”h]”hŒ'Initialize the mutex to unlocked state.”…”�”}”(hjq"h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³Œ^/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1346: ./include/linux/mutex.h”h´K7hjó!ubhú)�”}”(hŒ8It is not allowed to initialize an already locked mutex.”h]”hŒ8It is not allowed to initialize an already locked mutex.”…”�”}”(hj€"h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³Œ^/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1346: ./include/linux/mutex.h”h´K9hjó!ubeh}”(h]”h ]”Œ kernelindent”ah"]”h$]”h&]”uh1jñ!hj@!h²hh³Nh´NubjR!)�”}”(hhh]”h}”(h]”h ]”h"]”h$]”h&]”Œentries”]”(j^!Œmutex_init_with_key (C macro)”Œc.mutex_init_with_key”hNt”auh1jQ!hj@!h²hh³Nh´Nubjc!)�”}”(hhh]”(jh!)�”}”(hŒmutex_init_with_key”h]”jn!)�”}”(hŒmutex_init_with_key”h]”jt!)�”}”(hŒmutex_init_with_key”h]”jz!)�”}”(hj©"h]”hŒmutex_init_with_key”…”�”}”(hj³"h²hh³Nh´Nubah}”(h]”h ]”j…!ah"]”h$]”h&]”uh1jy!hj¯"ubah}”(h]”h ]”(jŒ!j�!eh"]”h$]”h&]”j�jŽuh1js!hj«"h²hh³Œ^/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1346: ./include/linux/mutex.h”h´KDubah}”(h]”h ]”h"]”h$]”h&]”j�jŽj˜!ˆuh1jm!j™!jš!hj§"h²hh³jÆ"h´KDubah}”(h]”j¢"ah ]”(jž!jŸ!eh"]”h$]”h&]”j£!ˆj¤!)j¥!huh1jg!h³jÆ"h´KDhj¤"h²hubj§!)�”}”(hhh]”h}”(h]”h ]”h"]”h$]”h&]”uh1j¦!hj¤"h²hh³jÆ"h´KDubeh}”(h]”h ]”(jUŒmacro”eh"]”h$]”h&]”j¸!jUj¹!jß"jº!jß"j»!‰j¼!‰j½!‰uh1jb!h²hhj@!h³Nh´Nubhú)�”}”(hŒ$``mutex_init_with_key (mutex, key)``”h]”jI)�”}”(hjå"h]”hŒ mutex_init_with_key (mutex, key)”…”�”}”(hjç"h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jHhjã"ubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³Œ^/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1346: ./include/linux/mutex.h”h´KFhj@!h²hubj×!)�”}”(hŒ,initialize a mutex with a given lockdep key ”h]”hú)�”}”(hŒ+initialize a mutex with a given lockdep key”h]”hŒ+initialize a mutex with a given lockdep key”…”�”}”(hjÿ"h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³Œ^/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1346: ./include/linux/mutex.h”h´KDhjû"ubah}”(h]”h ]”h"]”h$]”h&]”uh1jÖ!h³j #h´KDhj@!h²hubjò!)�”}”(hŒê**Parameters** ``mutex`` the mutex to be initialized ``key`` the lockdep key to be associated with the mutex **Description** Initialize the mutex to the unlocked state. It is not allowed to initialize an already locked mutex.”h]”(hú)�”}”(hŒ**Parameters**”h]”j)�”}”(hj#h]”hŒ Parameters”…”�”}”(hj#h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhj#ubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³Œ^/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1346: ./include/linux/mutex.h”h´KHhj#ubj")�”}”(hhh]”(j")�”}”(hŒ&``mutex`` the mutex to be initialized ”h]”(j")�”}”(hŒ ``mutex``”h]”jI)�”}”(hj9#h]”hŒmutex”…”�”}”(hj;#h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jHhj7#ubah}”(h]”h ]”h"]”h$]”h&]”uh1j"h³Œ^/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1346: ./include/linux/mutex.h”h´KEhj3#ubj5")�”}”(hhh]”hú)�”}”(hŒthe mutex to be initialized”h]”hŒthe mutex to be initialized”…”�”}”(hjR#h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³jN#h´KEhjO#ubah}”(h]”h ]”h"]”h$]”h&]”uh1j4"hj3#ubeh}”(h]”h ]”h"]”h$]”h&]”uh1j"h³jN#h´KEhj0#ubj")�”}”(hŒ8``key`` the lockdep key to be associated with the mutex ”h]”(j")�”}”(hŒ``key``”h]”jI)�”}”(hjr#h]”hŒkey”…”�”}”(hjt#h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jHhjp#ubah}”(h]”h ]”h"]”h$]”h&]”uh1j"h³Œ^/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1346: ./include/linux/mutex.h”h´KFhjl#ubj5")�”}”(hhh]”hú)�”}”(hŒ/the lockdep key to be associated with the mutex”h]”hŒ/the lockdep key to be associated with the mutex”…”�”}”(hj‹#h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³j‡#h´KFhjˆ#ubah}”(h]”h ]”h"]”h$]”h&]”uh1j4"hjl#ubeh}”(h]”h ]”h"]”h$]”h&]”uh1j"h³j‡#h´KFhj0#ubeh}”(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&]”uh1jhj«#ubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³Œ^/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1346: ./include/linux/mutex.h”h´KHhj#ubhú)�”}”(hŒ+Initialize the mutex to the unlocked state.”h]”hŒ+Initialize the mutex to the unlocked state.”…”�”}”(hjÃ#h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³Œ^/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1346: ./include/linux/mutex.h”h´KGhj#ubhú)�”}”(hŒ8It is not allowed to initialize an already locked mutex.”h]”hŒ8It is not allowed to initialize an already locked mutex.”…”�”}”(hjÒ#h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³Œ^/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1346: ./include/linux/mutex.h”h´KIhj#ubeh}”(h]”h ]”Œ kernelindent”ah"]”h$]”h&]”uh1jñ!hj@!h²hh³Nh´NubjR!)�”}”(hhh]”h}”(h]”h ]”h"]”h$]”h&]”Œentries”]”(j^!Œmutex_is_locked (C function)”Œc.mutex_is_locked”hNt”auh1jQ!hj@!h²hh³Nh´Nubjc!)�”}”(hhh]”(jh!)�”}”(hŒ)bool mutex_is_locked (struct mutex *lock)”h]”jn!)�”}”(hŒ(bool mutex_is_locked(struct mutex *lock)”h]”(hŒdesc_sig_keyword_type”“”)�”}”(hŒbool”h]”hŒbool”…”�”}”(hj$h²hh³Nh´Nubah}”(h]”h ]”Œkt”ah"]”h$]”h&]”uh1j$hjý#h²hh³Œ^/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1346: ./include/linux/mutex.h”h´KlubhŒdesc_sig_space”“”)�”}”(hŒ ”h]”hŒ ”…”�”}”(hj$h²hh³Nh´Nubah}”(h]”h ]”Œw”ah"]”h$]”h&]”uh1j$hjý#h²hh³j$h´Klubjt!)�”}”(hŒmutex_is_locked”h]”jz!)�”}”(hŒmutex_is_locked”h]”hŒmutex_is_locked”…”�”}”(hj($h²hh³Nh´Nubah}”(h]”h ]”j…!ah"]”h$]”h&]”uh1jy!hj$$ubah}”(h]”h ]”(jŒ!j�!eh"]”h$]”h&]”j�jŽuh1js!hjý#h²hh³j$h´KlubhŒdesc_parameterlist”“”)�”}”(hŒ(struct mutex *lock)”h]”hŒdesc_parameter”“”)�”}”(hŒstruct mutex *lock”h]”(hŒdesc_sig_keyword”“”)�”}”(hŒstruct”h]”hŒstruct”…”�”}”(hjJ$h²hh³Nh´Nubah}”(h]”h ]”Œk”ah"]”h$]”h&]”uh1jH$hjD$ubj$)�”}”(hŒ ”h]”hŒ ”…”�”}”(hjY$h²hh³Nh´Nubah}”(h]”h ]”j $ah"]”h$]”h&]”uh1j$hjD$ubh)�”}”(hhh]”jz!)�”}”(hŒmutex”h]”hŒmutex”…”�”}”(hjj$h²hh³Nh´Nubah}”(h]”h ]”j…!ah"]”h$]”h&]”uh1jy!hjg$ubah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”jUŒreftype”Œ identifier”Œ reftarget”jl$Œmodname”NŒ classname”NŒ c:parent_key”Œsphinx.domains.c”Œ LookupKey”“”)�”}”Œdata”]”j…$Œ ASTIdentifier”“”)�”}”j€$j*$sbŒc.mutex_is_locked”†”asbuh1hhjD$ubj$)�”}”(hŒ ”h]”hŒ ”…”�”}”(hj’$h²hh³Nh´Nubah}”(h]”h ]”j $ah"]”h$]”h&]”uh1j$hjD$ubhŒdesc_sig_punctuation”“”)�”}”(hŒ*”h]”hŒ*”…”�”}”(hj¢$h²hh³Nh´Nubah}”(h]”h ]”Œp”ah"]”h$]”h&]”uh1j $hjD$ubjz!)�”}”(hŒlock”h]”hŒlock”…”�”}”(hj±$h²hh³Nh´Nubah}”(h]”h ]”j…!ah"]”h$]”h&]”uh1jy!hjD$ubeh}”(h]”h ]”h"]”h$]”h&]”Œnoemph”ˆj�jŽuh1jB$hj>$ubah}”(h]”h ]”h"]”h$]”h&]”j�jŽuh1j<$hjý#h²hh³j$h´Klubeh}”(h]”h ]”h"]”h$]”h&]”j�jŽj˜!ˆuh1jm!j™!jš!hjù#h²hh³j$h´Klubah}”(h]”jô#ah ]”(jž!jŸ!eh"]”h$]”h&]”j£!ˆj¤!)j¥!huh1jg!h³j$h´Klhjö#h²hubj§!)�”}”(hhh]”hú)�”}”(hŒis the mutex locked”h]”hŒis the mutex locked”…”�”}”(hjÛ$h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³Œ^/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1346: ./include/linux/mutex.h”h´KlhjØ$h²hubah}”(h]”h ]”h"]”h$]”h&]”uh1j¦!hjö#h²hh³j$h´Klubeh}”(h]”h ]”(jUŒfunction”eh"]”h$]”h&]”j¸!jUj¹!jó$jº!jó$j»!‰j¼!‰j½!‰uh1jb!h²hhj@!h³Nh´Nubjò!)�”}”(hŒŠ**Parameters** ``struct mutex *lock`` the mutex to be queried **Description** Returns true if the mutex is locked, false if unlocked.”h]”(hú)�”}”(hŒ**Parameters**”h]”j)�”}”(hjý$h]”hŒ Parameters”…”�”}”(hjÿ$h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhjû$ubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³Œ^/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1346: ./include/linux/mutex.h”h´Kphj÷$ubj")�”}”(hhh]”j")�”}”(hŒ/``struct mutex *lock`` the mutex to be queried ”h]”(j")�”}”(hŒ``struct mutex *lock``”h]”jI)�”}”(hj%h]”hŒstruct mutex *lock”…”�”}”(hj%h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jHhj%ubah}”(h]”h ]”h"]”h$]”h&]”uh1j"h³Œ^/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1346: ./include/linux/mutex.h”h´Kmhj%ubj5")�”}”(hhh]”hú)�”}”(hŒthe mutex to be queried”h]”hŒthe mutex to be queried”…”�”}”(hj5%h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³j1%h´Kmhj2%ubah}”(h]”h ]”h"]”h$]”h&]”uh1j4"hj%ubeh}”(h]”h ]”h"]”h$]”h&]”uh1j"h³j1%h´Kmhj%ubah}”(h]”h ]”h"]”h$]”h&]”uh1j"hj÷$ubhú)�”}”(hŒ**Description**”h]”j)�”}”(hjW%h]”hŒ Description”…”�”}”(hjY%h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhjU%ubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³Œ^/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1346: ./include/linux/mutex.h”h´Kohj÷$ubhú)�”}”(hŒ7Returns true if the mutex is locked, false if unlocked.”h]”hŒ7Returns true if the mutex is locked, false if unlocked.”…”�”}”(hjm%h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³Œ^/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1346: ./include/linux/mutex.h”h´Knhj÷$ubeh}”(h]”h ]”Œ kernelindent”ah"]”h$]”h&]”uh1jñ!hj@!h²hh³Nh´NubjR!)�”}”(hhh]”h}”(h]”h ]”h"]”h$]”h&]”Œentries”]”(j^!Œmutex_lock (C function)”Œ c.mutex_lock”hNt”auh1jQ!hj@!h²hh³Nh´Nubjc!)�”}”(hhh]”(jh!)�”}”(hŒ$void mutex_lock (struct mutex *lock)”h]”jn!)�”}”(hŒ#void mutex_lock(struct mutex *lock)”h]”(j$)�”}”(hŒvoid”h]”hŒvoid”…”�”}”(hjœ%h²hh³Nh´Nubah}”(h]”h ]”j$ah"]”h$]”h&]”uh1j$hj˜%h²hh³Œ_/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1349: ./kernel/locking/mutex.c”h´M&ubj$)�”}”(hŒ ”h]”hŒ ”…”�”}”(hj«%h²hh³Nh´Nubah}”(h]”h ]”j $ah"]”h$]”h&]”uh1j$hj˜%h²hh³jª%h´M&ubjt!)�”}”(hŒ mutex_lock”h]”jz!)�”}”(hŒ mutex_lock”h]”hŒ mutex_lock”…”�”}”(hj½%h²hh³Nh´Nubah}”(h]”h ]”j…!ah"]”h$]”h&]”uh1jy!hj¹%ubah}”(h]”h ]”(jŒ!j�!eh"]”h$]”h&]”j�jŽuh1js!hj˜%h²hh³jª%h´M&ubj=$)�”}”(hŒ(struct mutex *lock)”h]”jC$)�”}”(hŒstruct mutex *lock”h]”(jI$)�”}”(hjL$h]”hŒstruct”…”�”}”(hjÙ%h²hh³Nh´Nubah}”(h]”h ]”jU$ah"]”h$]”h&]”uh1jH$hjÕ%ubj$)�”}”(hŒ ”h]”hŒ ”…”�”}”(hjæ%h²hh³Nh´Nubah}”(h]”h ]”j $ah"]”h$]”h&]”uh1j$hjÕ%ubh)�”}”(hhh]”jz!)�”}”(hŒmutex”h]”hŒmutex”…”�”}”(hj÷%h²hh³Nh´Nubah}”(h]”h ]”j…!ah"]”h$]”h&]”uh1jy!hjô%ubah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”jUŒreftype”j€$Œ reftarget”jù%Œmodname”NŒ classname”Nj„$j‡$)�”}”jŠ$]”j�$)�”}”j€$j¿%sbŒ c.mutex_lock”†”asbuh1hhjÕ%ubj$)�”}”(hŒ ”h]”hŒ ”…”�”}”(hj&h²hh³Nh´Nubah}”(h]”h ]”j $ah"]”h$]”h&]”uh1j$hjÕ%ubj¡$)�”}”(hj¤$h]”hŒ*”…”�”}”(hj%&h²hh³Nh´Nubah}”(h]”h ]”j­$ah"]”h$]”h&]”uh1j $hjÕ%ubjz!)�”}”(hŒlock”h]”hŒlock”…”�”}”(hj2&h²hh³Nh´Nubah}”(h]”h ]”j…!ah"]”h$]”h&]”uh1jy!hjÕ%ubeh}”(h]”h ]”h"]”h$]”h&]”Œnoemph”ˆj�jŽuh1jB$hjÑ%ubah}”(h]”h ]”h"]”h$]”h&]”j�jŽuh1j<$hj˜%h²hh³jª%h´M&ubeh}”(h]”h ]”h"]”h$]”h&]”j�jŽj˜!ˆuh1jm!j™!jš!hj”%h²hh³jª%h´M&ubah}”(h]”j�%ah ]”(jž!jŸ!eh"]”h$]”h&]”j£!ˆj¤!)j¥!huh1jg!h³jª%h´M&hj‘%h²hubj§!)�”}”(hhh]”hú)�”}”(hŒacquire the mutex”h]”hŒacquire the mutex”…”�”}”(hj\&h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³Œ_/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1349: ./kernel/locking/mutex.c”h´M&hjY&h²hubah}”(h]”h ]”h"]”h$]”h&]”uh1j¦!hj‘%h²hh³jª%h´M&ubeh}”(h]”h ]”(jUŒfunction”eh"]”h$]”h&]”j¸!jUj¹!jt&jº!jt&j»!‰j¼!‰j½!‰uh1jb!h²hhj@!h³Nh´Nubjò!)�”}”(hX**Parameters** ``struct mutex *lock`` the mutex to be acquired **Description** Lock the mutex exclusively for this task. If the mutex is not available right now, it will sleep until it can get it. The mutex must later on be released by the same task that acquired it. Recursive locking is not allowed. The task may not exit without first unlocking the mutex. Also, kernel memory where the mutex resides must not be freed with the mutex still locked. The mutex must first be initialized (or statically defined) before it can be locked. memset()-ing the mutex to 0 is not allowed. (The CONFIG_DEBUG_MUTEXES .config option turns on debugging checks that will enforce the restrictions and will also do deadlock debugging) This function is similar to (but not equivalent to) down().”h]”(hú)�”}”(hŒ**Parameters**”h]”j)�”}”(hj~&h]”hŒ Parameters”…”�”}”(hj€&h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhj|&ubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³Œ_/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1349: ./kernel/locking/mutex.c”h´M*hjx&ubj")�”}”(hhh]”j")�”}”(hŒ0``struct mutex *lock`` the mutex to be acquired ”h]”(j")�”}”(hŒ``struct mutex *lock``”h]”jI)�”}”(hj�&h]”hŒstruct mutex *lock”…”�”}”(hjŸ&h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jHhj›&ubah}”(h]”h ]”h"]”h$]”h&]”uh1j"h³Œ_/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1349: ./kernel/locking/mutex.c”h´M'hj—&ubj5")�”}”(hhh]”hú)�”}”(hŒthe mutex to be acquired”h]”hŒthe mutex to be acquired”…”�”}”(hj¶&h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³j²&h´M'hj³&ubah}”(h]”h ]”h"]”h$]”h&]”uh1j4"hj—&ubeh}”(h]”h ]”h"]”h$]”h&]”uh1j"h³j²&h´M'hj”&ubah}”(h]”h ]”h"]”h$]”h&]”uh1j"hjx&ubhú)�”}”(hŒ**Description**”h]”j)�”}”(hjØ&h]”hŒ Description”…”�”}”(hjÚ&h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhjÖ&ubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³Œ_/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1349: ./kernel/locking/mutex.c”h´M)hjx&ubhú)�”}”(hŒuLock the mutex exclusively for this task. If the mutex is not available right now, it will sleep until it can get it.”h]”hŒuLock the mutex exclusively for this task. If the mutex is not available right now, it will sleep until it can get it.”…”�”}”(hjî&h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³Œ_/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1349: ./kernel/locking/mutex.c”h´M(hjx&ubhú)�”}”(hX}The mutex must later on be released by the same task that acquired it. Recursive locking is not allowed. The task may not exit without first unlocking the mutex. Also, kernel memory where the mutex resides must not be freed with the mutex still locked. The mutex must first be initialized (or statically defined) before it can be locked. memset()-ing the mutex to 0 is not allowed.”h]”hX}The mutex must later on be released by the same task that acquired it. Recursive locking is not allowed. The task may not exit without first unlocking the mutex. Also, kernel memory where the mutex resides must not be freed with the mutex still locked. The mutex must first be initialized (or statically defined) before it can be locked. memset()-ing the mutex to 0 is not allowed.”…”�”}”(hjý&h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³Œ_/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1349: ./kernel/locking/mutex.c”h´M+hjx&ubhú)�”}”(hŒŠ(The CONFIG_DEBUG_MUTEXES .config option turns on debugging checks that will enforce the restrictions and will also do deadlock debugging)”h]”hŒŠ(The CONFIG_DEBUG_MUTEXES .config option turns on debugging checks that will enforce the restrictions and will also do deadlock debugging)”…”�”}”(hj 'h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³Œ_/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1349: ./kernel/locking/mutex.c”h´M3hjx&ubhú)�”}”(hŒ;This function is similar to (but not equivalent to) down().”h]”hŒ;This function is similar to (but not equivalent to) down().”…”�”}”(hj'h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³Œ_/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1349: ./kernel/locking/mutex.c”h´M7hjx&ubeh}”(h]”h ]”Œ kernelindent”ah"]”h$]”h&]”uh1jñ!hj@!h²hh³Nh´NubjR!)�”}”(hhh]”h}”(h]”h ]”h"]”h$]”h&]”Œentries”]”(j^!Œmutex_unlock (C function)”Œc.mutex_unlock”hNt”auh1jQ!hj@!h²hh³Nh´Nubjc!)�”}”(hhh]”(jh!)�”}”(hŒ&void mutex_unlock (struct mutex *lock)”h]”jn!)�”}”(hŒ%void mutex_unlock(struct mutex *lock)”h]”(j$)�”}”(hŒvoid”h]”hŒvoid”…”�”}”(hjJ'h²hh³Nh´Nubah}”(h]”h ]”j$ah"]”h$]”h&]”uh1j$hjF'h²hh³Œ_/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1349: ./kernel/locking/mutex.c”h´M1ubj$)�”}”(hŒ ”h]”hŒ ”…”�”}”(hjY'h²hh³Nh´Nubah}”(h]”h ]”j $ah"]”h$]”h&]”uh1j$hjF'h²hh³jX'h´M1ubjt!)�”}”(hŒ mutex_unlock”h]”jz!)�”}”(hŒ mutex_unlock”h]”hŒ mutex_unlock”…”�”}”(hjk'h²hh³Nh´Nubah}”(h]”h ]”j…!ah"]”h$]”h&]”uh1jy!hjg'ubah}”(h]”h ]”(jŒ!j�!eh"]”h$]”h&]”j�jŽuh1js!hjF'h²hh³jX'h´M1ubj=$)�”}”(hŒ(struct mutex *lock)”h]”jC$)�”}”(hŒstruct mutex *lock”h]”(jI$)�”}”(hjL$h]”hŒstruct”…”�”}”(hj‡'h²hh³Nh´Nubah}”(h]”h ]”jU$ah"]”h$]”h&]”uh1jH$hjƒ'ubj$)�”}”(hŒ ”h]”hŒ ”…”�”}”(hj”'h²hh³Nh´Nubah}”(h]”h ]”j $ah"]”h$]”h&]”uh1j$hjƒ'ubh)�”}”(hhh]”jz!)�”}”(hŒmutex”h]”hŒmutex”…”�”}”(hj¥'h²hh³Nh´Nubah}”(h]”h ]”j…!ah"]”h$]”h&]”uh1jy!hj¢'ubah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”jUŒreftype”j€$Œ reftarget”j§'Œmodname”NŒ classname”Nj„$j‡$)�”}”jŠ$]”j�$)�”}”j€$jm'sbŒc.mutex_unlock”†”asbuh1hhjƒ'ubj$)�”}”(hŒ ”h]”hŒ ”…”�”}”(hjÅ'h²hh³Nh´Nubah}”(h]”h ]”j $ah"]”h$]”h&]”uh1j$hjƒ'ubj¡$)�”}”(hj¤$h]”hŒ*”…”�”}”(hjÓ'h²hh³Nh´Nubah}”(h]”h ]”j­$ah"]”h$]”h&]”uh1j $hjƒ'ubjz!)�”}”(hŒlock”h]”hŒlock”…”�”}”(hjà'h²hh³Nh´Nubah}”(h]”h ]”j…!ah"]”h$]”h&]”uh1jy!hjƒ'ubeh}”(h]”h ]”h"]”h$]”h&]”Œnoemph”ˆj�jŽuh1jB$hj'ubah}”(h]”h ]”h"]”h$]”h&]”j�jŽuh1j<$hjF'h²hh³jX'h´M1ubeh}”(h]”h ]”h"]”h$]”h&]”j�jŽj˜!ˆuh1jm!j™!jš!hjB'h²hh³jX'h´M1ubah}”(h]”j='ah ]”(jž!jŸ!eh"]”h$]”h&]”j£!ˆj¤!)j¥!huh1jg!h³jX'h´M1hj?'h²hubj§!)�”}”(hhh]”hú)�”}”(hŒrelease the mutex”h]”hŒrelease the mutex”…”�”}”(hj (h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³Œ_/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1349: ./kernel/locking/mutex.c”h´M1hj(h²hubah}”(h]”h ]”h"]”h$]”h&]”uh1j¦!hj?'h²hh³jX'h´M1ubeh}”(h]”h ]”(jUŒfunction”eh"]”h$]”h&]”j¸!jUj¹!j"(jº!j"(j»!‰j¼!‰j½!‰uh1jb!h²hhj@!h³Nh´Nubjò!)�”}”(hX4**Parameters** ``struct mutex *lock`` the mutex to be released **Description** Unlock a mutex that has been locked by this task previously. This function must not be used in interrupt context. Unlocking of a not locked mutex is not allowed. The caller must ensure that the mutex stays alive until this function has returned - mutex_unlock() can NOT directly be used to release an object such that another concurrent task can free it. Mutexes are different from spinlocks & refcounts in this aspect. This function is similar to (but not equivalent to) up().”h]”(hú)�”}”(hŒ**Parameters**”h]”j)�”}”(hj,(h]”hŒ Parameters”…”�”}”(hj.(h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhj*(ubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³Œ_/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1349: ./kernel/locking/mutex.c”h´M5hj&(ubj")�”}”(hhh]”j")�”}”(hŒ0``struct mutex *lock`` the mutex to be released ”h]”(j")�”}”(hŒ``struct mutex *lock``”h]”jI)�”}”(hjK(h]”hŒstruct mutex *lock”…”�”}”(hjM(h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jHhjI(ubah}”(h]”h ]”h"]”h$]”h&]”uh1j"h³Œ_/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1349: ./kernel/locking/mutex.c”h´M2hjE(ubj5")�”}”(hhh]”hú)�”}”(hŒthe mutex to be released”h]”hŒthe mutex to be released”…”�”}”(hjd(h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³j`(h´M2hja(ubah}”(h]”h ]”h"]”h$]”h&]”uh1j4"hjE(ubeh}”(h]”h ]”h"]”h$]”h&]”uh1j"h³j`(h´M2hjB(ubah}”(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&]”uh1jhj„(ubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³Œ_/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1349: ./kernel/locking/mutex.c”h´M4hj&(ubhú)�”}”(hŒ/h²hh³Nh´Nubah}”(h]”h ]”j $ah"]”h$]”h&]”uh1j$hjü.ubj¡$)�”}”(hj¤$h]”hŒ*”…”�”}”(hjL/h²hh³Nh´Nubah}”(h]”h ]”j­$ah"]”h$]”h&]”uh1j $hjü.ubjz!)�”}”(hŒlock”h]”hŒlock”…”�”}”(hjY/h²hh³Nh´Nubah}”(h]”h ]”j…!ah"]”h$]”h&]”uh1jy!hjü.ubeh}”(h]”h ]”h"]”h$]”h&]”Œnoemph”ˆj�jŽuh1jB$hjø.ubah}”(h]”h ]”h"]”h$]”h&]”j�jŽuh1j<$hj¿.h²hh³jÑ.h´M^ubeh}”(h]”h ]”h"]”h$]”h&]”j�jŽj˜!ˆuh1jm!j™!jš!hj».h²hh³jÑ.h´M^ubah}”(h]”j¶.ah ]”(jž!jŸ!eh"]”h$]”h&]”j£!ˆj¤!)j¥!huh1jg!h³jÑ.h´M^hj¸.h²hubj§!)�”}”(hhh]”hú)�”}”(hŒ2Acquire the mutex, interruptible by fatal signals.”h]”hŒ2Acquire the mutex, interruptible by fatal signals.”…”�”}”(hjƒ/h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³Œ_/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1349: ./kernel/locking/mutex.c”h´M^hj€/h²hubah}”(h]”h ]”h"]”h$]”h&]”uh1j¦!hj¸.h²hh³jÑ.h´M^ubeh}”(h]”h ]”(jUŒfunction”eh"]”h$]”h&]”j¸!jUj¹!j›/jº!j›/j»!‰j¼!‰j½!‰uh1jb!h²hhj@!h³Nh´Nubjò!)�”}”(hXŽ**Parameters** ``struct mutex *lock`` The mutex to be acquired. **Description** Lock the mutex like mutex_lock(). If a signal which will be fatal to the current process is delivered while the process is sleeping, this function will return without acquiring the mutex. **Context** Process context. **Return** 0 if the lock was successfully acquired or ``-EINTR`` if a fatal signal arrived.”h]”(hú)�”}”(hŒ**Parameters**”h]”j)�”}”(hj¥/h]”hŒ Parameters”…”�”}”(hj§/h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhj£/ubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³Œ_/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1349: ./kernel/locking/mutex.c”h´MbhjŸ/ubj")�”}”(hhh]”j")�”}”(hŒ1``struct mutex *lock`` The mutex to be acquired. ”h]”(j")�”}”(hŒ``struct mutex *lock``”h]”jI)�”}”(hjÄ/h]”hŒstruct mutex *lock”…”�”}”(hjÆ/h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jHhjÂ/ubah}”(h]”h ]”h"]”h$]”h&]”uh1j"h³Œ_/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1349: ./kernel/locking/mutex.c”h´M_hj¾/ubj5")�”}”(hhh]”hú)�”}”(hŒThe mutex to be acquired.”h]”hŒThe mutex to be acquired.”…”�”}”(hjÝ/h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³jÙ/h´M_hjÚ/ubah}”(h]”h ]”h"]”h$]”h&]”uh1j4"hj¾/ube•h}”(h]”h ]”h"]”h$]”h&]”uh1j"h³jÙ/h´M_hj»/ubah}”(h]”h ]”h"]”h$]”h&]”uh1j"hjŸ/ubhú)�”}”(hŒ**Description**”h]”j)�”}”(hjÿ/h]”hŒ Description”…”�”}”(hj0h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhjý/ubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³Œ_/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1349: ./kernel/locking/mutex.c”h´MahjŸ/ubhú)�”}”(hŒ¼Lock the mutex like mutex_lock(). If a signal which will be fatal to the current process is delivered while the process is sleeping, this function will return without acquiring the mutex.”h]”hŒ¼Lock the mutex like mutex_lock(). If a signal which will be fatal to the current process is delivered while the process is sleeping, this function will return without acquiring the mutex.”…”�”}”(hj0h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³Œ_/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1349: ./kernel/locking/mutex.c”h´M`hjŸ/ubhú)�”}”(hŒ **Context**”h]”j)�”}”(hj&0h]”hŒContext”…”�”}”(hj(0h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhj$0ubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³Œ_/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1349: ./kernel/locking/mutex.c”h´MdhjŸ/ubhú)�”}”(hŒProcess context.”h]”hŒProcess context.”…”�”}”(hj<0h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³Œ_/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1349: ./kernel/locking/mutex.c”h´MehjŸ/ubhú)�”}”(hŒ **Return**”h]”j)�”}”(hjM0h]”hŒReturn”…”�”}”(hjO0h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhjK0ubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³Œ_/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1349: ./kernel/locking/mutex.c”h´MghjŸ/ubhú)�”}”(hŒP0 if the lock was successfully acquired or ``-EINTR`` if a fatal signal arrived.”h]”(hŒ+0 if the lock was successfully acquired or ”…”�”}”(hjc0h²hh³Nh´NubjI)�”}”(hŒ ``-EINTR``”h]”hŒ-EINTR”…”�”}”(hjk0h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jHhjc0ubhŒ if a fatal signal arrived.”…”�”}”(hjc0h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hùh³Œ_/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1349: ./kernel/locking/mutex.c”h´MfhjŸ/ubeh}”(h]”h ]”Œ kernelindent”ah"]”h$]”h&]”uh1jñ!hj@!h²hh³Nh´NubjR!)�”}”(hhh]”h}”(h]”h ]”h"]”h$]”h&]”Œentries”]”(j^!Œmutex_lock_io (C function)”Œc.mutex_lock_io”hNt”auh1jQ!hj@!h²hh³Nh´Nubjc!)�”}”(hhh]”(jh!)�”}”(hŒ'void mutex_lock_io (struct mutex *lock)”h]”jn!)�”}”(hŒ&void mutex_lock_io(struct mutex *lock)”h]”(j$)�”}”(hŒvoid”h]”hŒvoid”…”�”}”(hj¤0h²hh³Nh´Nubah}”(h]”h ]”j$ah"]”h$]”h&]”uh1j$hj 0h²hh³Œ_/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1349: ./kernel/locking/mutex.c”h´Muubj$)�”}”(hŒ ”h]”hŒ ”…”�”}”(hj³0h²hh³Nh´Nubah}”(h]”h ]”j $ah"]”h$]”h&]”uh1j$hj 0h²hh³j²0h´Muubjt!)�”}”(hŒ mutex_lock_io”h]”jz!)�”}”(hŒ mutex_lock_io”h]”hŒ mutex_lock_io”…”�”}”(hjÅ0h²hh³Nh´Nubah}”(h]”h ]”j…!ah"]”h$]”h&]”uh1jy!hjÁ0ubah}”(h]”h ]”(jŒ!j�!eh"]”h$]”h&]”j�jŽuh1js!hj 0h²hh³j²0h´Muubj=$)�”}”(hŒ(struct mutex *lock)”h]”jC$)�”}”(hŒstruct mutex *lock”h]”(jI$)�”}”(hjL$h]”hŒstruct”…”�”}”(hjá0h²hh³Nh´Nubah}”(h]”h ]”jU$ah"]”h$]”h&]”uh1jH$hjÝ0ubj$)�”}”(hŒ ”h]”hŒ ”…”�”}”(hjî0h²hh³Nh´Nubah}”(h]”h ]”j $ah"]”h$]”h&]”uh1j$hjÝ0ubh)�”}”(hhh]”jz!)�”}”(hŒmutex”h]”hŒmutex”…”�”}”(hjÿ0h²hh³Nh´Nubah}”(h]”h ]”j…!ah"]”h$]”h&]”uh1jy!hjü0ubah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”jUŒreftype”j€$Œ reftarget”j1Œmodname”NŒ classname”Nj„$j‡$)�”}”jŠ$]”j�$)�”}”j€$jÇ0sbŒc.mutex_lock_io”†”asbuh1hhjÝ0ubj$)�”}”(hŒ ”h]”hŒ ”…”�”}”(hj1h²hh³Nh´Nubah}”(h]”h ]”j $ah"]”h$]”h&]”uh1j$hjÝ0ubj¡$)�”}”(hj¤$h]”hŒ*”…”�”}”(hj-1h²hh³Nh´Nubah}”(h]”h ]”j­$ah"]”h$]”h&]”uh1j $hjÝ0ubjz!)�”}”(hŒlock”h]”hŒlock”…”�”}”(hj:1h²hh³Nh´Nubah}”(h]”h ]”j…!ah"]”h$]”h&]”uh1jy!hjÝ0ubeh}”(h]”h ]”h"]”h$]”h&]”Œnoemph”ˆj�jŽuh1jB$hjÙ0ubah}”(h]”h ]”h"]”h$]”h&]”j�jŽuh1j<$hj 0h²hh³j²0h´Muubeh}”(h]”h ]”h"]”h$]”h&]”j�jŽj˜!ˆuh1jm!j™!jš!hjœ0h²hh³j²0h´Muubah}”(h]”j—0ah ]”(jž!jŸ!eh"]”h$]”h&]”j£!ˆj¤!)j¥!huh1jg!h³j²0h´Muhj™0h²hubj§!)�”}”(hhh]”hú)�”}”(hŒ9Acquire the mutex and mark the process as waiting for I/O”h]”hŒ9Acquire the mutex and mark the process as waiting for I/O”…”�”}”(hjd1h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³Œ_/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1349: ./kernel/locking/mutex.c”h´Muhja1h²hubah}”(h]”h ]”h"]”h$]”h&]”uh1j¦!hj™0h²hh³j²0h´Muubeh}”(h]”h ]”(jUŒfunction”eh"]”h$]”h&]”j¸!jUj¹!j|1jº!j|1j»!‰j¼!‰j½!‰uh1jb!h²hhj@!h³Nh´Nubjò!)�”}”(hX**Parameters** ``struct mutex *lock`` The mutex to be acquired. **Description** Lock the mutex like mutex_lock(). While the task is waiting for this mutex, it will be accounted as being in the IO wait state by the scheduler. **Context** Process context.”h]”(hú)�”}”(hŒ**Parameters**”h]”j)�”}”(hj†1h]”hŒ Parameters”…”�”}”(hjˆ1h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhj„1ubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³Œ_/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1349: ./kernel/locking/mutex.c”h´Myhj€1ubj")�”}”(hhh]”j")�”}”(hŒ1``struct mutex *lock`` The mutex to be acquired. ”h]”(j")�”}”(hŒ``struct mutex *lock``”h]”jI)�”}”(hj¥1h]”hŒstruct mutex *lock”…”�”}”(hj§1h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jHhj£1ubah}”(h]”h ]”h"]”h$]”h&]”uh1j"h³Œ_/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1349: ./kernel/locking/mutex.c”h´MvhjŸ1ubj5")�”}”(hhh]”hú)�”}”(hŒThe mutex to be acquired.”h]”hŒThe mutex to be acquired.”…”�”}”(hj¾1h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³jº1h´Mvhj»1ubah}”(h]”h ]”h"]”h$]”h&]”uh1j4"hjŸ1ubeh}”(h]”h ]”h"]”h$]”h&]”uh1j"h³jº1h´Mvhjœ1ubah}”(h]”h ]”h"]”h$]”h&]”uh1j"hj€1ubhú)�”}”(hŒ**Description**”h]”j)�”}”(hjà1h]”hŒ Description”…”�”}”(hjâ1h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhjÞ1ubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³Œ_/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1349: ./kernel/locking/mutex.c”h´Mxhj€1ubhú)�”}”(hŒ‘Lock the mutex like mutex_lock(). While the task is waiting for this mutex, it will be accounted as being in the IO wait state by the scheduler.”h]”hŒ‘Lock the mutex like mutex_lock(). While the task is waiting for this mutex, it will be accounted as being in the IO wait state by the scheduler.”…”�”}”(hjö1h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³Œ_/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1349: ./kernel/locking/mutex.c”h´Mwhj€1ubhú)�”}”(hŒ **Context**”h]”j)�”}”(hj2h]”hŒContext”…”�”}”(hj 2h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhj2ubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³Œ_/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1349: ./kernel/locking/mutex.c”h´M{hj€1ubhú)�”}”(hŒProcess context.”h]”hŒProcess context.”…”�”}”(hj2h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³Œ_/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1349: ./kernel/locking/mutex.c”h´M|hj€1ubeh}”(h]”h ]”Œ kernelindent”ah"]”h$]”h&]”uh1jñ!hj@!h²hh³Nh´NubjR!)�”}”(hhh]”h}”(h]”h ]”h"]”h$]”h&]”Œentries”]”(j^!Œmutex_trylock (C function)”Œc.mutex_trylock”hNt”auh1jQ!hj@!h²hh³Nh´Nubjc!)�”}”(hhh]”(jh!)�”}”(hŒ&int mutex_trylock (struct mutex *lock)”h]”jn!)�”}”(hŒ%int mutex_trylock(struct mutex *lock)”h]”(j$)�”}”(hŒint”h]”hŒint”…”�”}”(hjL2h²hh³Nh´Nubah}”(h]”h ]”j$ah"]”h$]”h&]”uh1j$hjH2h²hh³Œ_/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1349: ./kernel/locking/mutex.c”h´M³ubj$)�”}”(hŒ ”h]”hŒ ”…”�”}”(hj[2h²hh³Nh´Nubah}”(h]”h ]”j $ah"]”h$]”h&]”uh1j$hjH2h²hh³jZ2h´M³ubjt!)�”}”(hŒ mutex_trylock”h]”jz!)�”}”(hŒ mutex_trylock”h]”hŒ mutex_trylock”…”�”}”(hjm2h²hh³Nh´Nubah}”(h]”h ]”j…!ah"]”h$]”h&]”uh1jy!hji2ubah}”(h]”h ]”(jŒ!j�!eh"]”h$]”h&]”j�jŽuh1js!hjH2h²hh³jZ2h´M³ubj=$)�”}”(hŒ(struct mutex *lock)”h]”jC$)�”}”(hŒstruct mutex *lock”h]”(jI$)�”}”(hjL$h]”hŒstruct”…”�”}”(hj‰2h²hh³Nh´Nubah}”(h]”h ]”jU$ah"]”h$]”h&]”uh1jH$hj…2ubj$)�”}”(hŒ ”h]”hŒ ”…”�”}”(hj–2h²hh³Nh´Nubah}”(h]”h ]”j $ah"]”h$]”h&]”uh1j$hj…2ubh)�”}”(hhh]”jz!)�”}”(hŒmutex”h]”hŒmutex”…”�”}”(hj§2h²hh³Nh´Nubah}”(h]”h ]”j…!ah"]”h$]”h&]”uh1jy!hj¤2ubah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”jUŒreftype”j€$Œ reftarget”j©2Œmodname”NŒ classname”Nj„$j‡$)�”}”jŠ$]”j�$)�”}”j€$jo2sbŒc.mutex_trylock”†”asbuh1hhj…2ubj$)�”}”(hŒ ”h]”hŒ ”…”�”}”(hjÇ2h²hh³Nh´Nubah}”(h]”h ]”j $ah"]”h$]”h&]”uh1j$hj…2ubj¡$)�”}”(hj¤$h]”hŒ*”…”�”}”(hjÕ2h²hh³Nh´Nubah}”(h]”h ]”j­$ah"]”h$]”h&]”uh1j $hj…2ubjz!)�”}”(hŒlock”h]”hŒlock”…”�”}”(hjâ2h²hh³Nh´Nubah}”(h]”h ]”j…!ah"]”h$]”h&]”uh1jy!hj…2ubeh}”(h]”h ]”h"]”h$]”h&]”Œnoemph”ˆj�jŽuh1jB$hj�2ubah}”(h]”h ]”h"]”h$]”h&]”j�jŽuh1j<$hjH2h²hh³jZ2h´M³ubeh}”(h]”h ]”h"]”h$]”h&]”j�jŽj˜!ˆuh1jm!j™!jš!hjD2h²hh³jZ2h´M³ubah}”(h]”j?2ah ]”(jž!jŸ!eh"]”h$]”h&]”j£!ˆj¤!)j¥!huh1jg!h³jZ2h´M³hjA2h²hubj§!)�”}”(hhh]”hú)�”}”(hŒ)try to acquire the mutex, without waiting”h]”hŒ)try to acquire the mutex, without waiting”…”�”}”(hj 3h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³Œ_/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1349: ./kernel/locking/mutex.c”h´M³hj 3h²hubah}”(h]”h ]”h"]”h$]”h&]”uh1j¦!hjA2h²hh³jZ2h´M³ubeh}”(h]”h ]”(jUŒfunction”eh"]”h$]”h&]”j¸!jUj¹!j$3jº!j$3j»!‰j¼!‰j½!‰uh1jb!h²hhj@!h³Nh´Nubjò!)�”}”(hXò**Parameters** ``struct mutex *lock`` the mutex to be acquired **Description** Try to acquire the mutex atomically. Returns 1 if the mutex has been acquired successfully, and 0 on contention. **NOTE** this function follows the spin_trylock() convention, so it is negated from the down_trylock() return values! Be careful about this when converting semaphore users to mutexes. This function must not be used in interrupt context. The mutex must be released by the same task that acquired it.”h]”(hú)�”}”(hŒ**Parameters**”h]”j)�”}”(hj.3h]”hŒ Parameters”…”�”}”(hj03h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhj,3ubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³Œ_/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1349: ./kernel/locking/mutex.c”h´M·hj(3ubj")�”}”(hhh]”j")�”}”(hŒ0``struct mutex *lock`` the mutex to be acquired ”h]”(j")�”}”(hŒ``struct mutex *lock``”h]”jI)�”}”(hjM3h]”hŒstruct mutex *lock”…”�”}”(hjO3h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jHhjK3ubah}”(h]”h ]”h"]”h$]”h&]”uh1j"h³Œ_/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1349: ./kernel/locking/mutex.c”h´M´hjG3ubj5")�”}”(hhh]”hú)�”}”(hŒthe mutex to be acquired”h]”hŒthe mutex to be acquired”…”�”}”(hjf3h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³jb3h´M´hjc3ubah}”(h]”h ]”h"]”h$]”h&]”uh1j4"hjG3ubeh}”(h]”h ]”h"]”h$]”h&]”uh1j"h³jb3h´M´hjD3ubah}”(h]”h ]”h"]”h$]”h&]”uh1j"hj(3ubhú)�”}”(hŒ**Description**”h]”j)�”}”(hjˆ3h]”hŒ Description”…”�”}”(hjŠ3h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhj†3ubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³Œ_/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1349: ./kernel/locking/mutex.c”h´M¶hj(3ubhú)�”}”(hŒpTry to acquire the mutex atomically. Returns 1 if the mutex has been acquired successfully, and 0 on contention.”h]”hŒpTry to acquire the mutex atomically. Returns 1 if the mutex has been acquired successfully, and 0 on contention.”…”�”}”(hjž3h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³Œ_/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1349: ./kernel/locking/mutex.c”h´Mµhj(3ubhú)�”}”(hŒ**NOTE**”h]”j)�”}”(hj¯3h]”hŒNOTE”…”�”}”(hj±3h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhj­3ubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³Œ_/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1349: ./kernel/locking/mutex.c”h´M¸hj(3ubhú)�”}”(hŒ®this function follows the spin_trylock() convention, so it is negated from the down_trylock() return values! Be careful about this when converting semaphore users to mutexes.”h]”hŒ®this function follows the spin_trylock() convention, so it is negated from the down_trylock() return values! Be careful about this when converting semaphore users to mutexes.”…”�”}”(hjÅ3h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³Œ_/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1349: ./kernel/locking/mutex.c”h´M¹hj(3ubhú)�”}”(hŒrThis function must not be used in interrupt context. The mutex must be released by the same task that acquired it.”h]”hŒrThis function must not be used in interrupt context. The mutex must be released by the same task that acquired it.”…”�”}”(hjÔ3h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³Œ_/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1349: ./kernel/locking/mutex.c”h´M½hj(3ubeh}”(h]”h ]”Œ kernelindent”ah"]”h$]”h&]”uh1jñ!hj@!h²hh³Nh´NubjR!)�”}”(hhh]”h}”(h]”h ]”h"]”h$]”h&]”Œentries”]”(j^!Œ&atomic_dec_and_mutex_lock (C function)”Œc.atomic_dec_and_mutex_lock”hNt”auh1jQ!hj@!h²hh³Nh´Nubjc!)�”}”(hhh]”(jh!)�”}”(hŒAint atomic_dec_and_mutex_lock (atomic_t *cnt, struct mutex *lock)”h]”jn!)�”}”(hŒ@int atomic_dec_and_mutex_lock(atomic_t *cnt, struct mutex *lock)”h]”(j$)�”}”(hŒint”h]”hŒint”…”�”}”(hj4h²hh³Nh´Nubah}”(h]”h ]”j$ah"]”h$]”h&]”uh1j$hjÿ3h²hh³Œ_/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1349: ./kernel/locking/mutex.c”h´Mubj$)�”}”(hŒ ”h]”hŒ ”…”�”}”(hj4h²hh³Nh´Nubah}”(h]”h ]”j $ah"]”h$]”h&]”uh1j$hjÿ3h²hh³j4h´Mubjt!)�”}”(hŒatomic_dec_and_mutex_lock”h]”jz!)�”}”(hŒatomic_dec_and_mutex_lock”h]”hŒatomic_dec_and_mutex_lock”…”�”}”(hj$4h²hh³Nh´Nubah}”(h]”h ]”j…!ah"]”h$]”h&]”uh1jy!hj 4ubah}”(h]”h ]”(jŒ!j�!eh"]”h$]”h&]”j�jŽuh1js!hjÿ3h²hh³j4h´Mubj=$)�”}”(hŒ#(atomic_t *cnt, struct mutex *lock)”h]”(jC$)�”}”(hŒ atomic_t *cnt”h]”(h)�”}”(hhh]”jz!)�”}”(hŒatomic_t”h]”hŒatomic_t”…”�”}”(hjC4h²hh³Nh´Nubah}”(h]”h ]”j…!ah"]”h$]”h&]”uh1jy!hj@4ubah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”jUŒreftype”j€$Œ reftarget”jE4Œmodname”NŒ classname”Nj„$j‡$)�”}”jŠ$]”j�$)�”}”j€$j&4sbŒc.atomic_dec_and_mutex_lock”†”asbuh1hhj<4ubj$)�”}”(hŒ ”h]”hŒ ”…”�”}”(hjc4h²hh³Nh´Nubah}”(h]”h ]”j $ah"]”h$]”h&]”uh1j$hj<4ubj¡$)�”}”(hj¤$h]”hŒ*”…”�”}”(hjq4h²hh³Nh´Nubah}”(h]”h ]”j­$ah"]”h$]”h&]”uh1j $hj<4ubjz!)�”}”(hŒcnt”h]”hŒcnt”…”�”}”(hj~4h²hh³Nh´Nubah}”(h]”h ]”j…!ah"]”h$]”h&]”uh1jy!hj<4ubeh}”(h]”h ]”h"]”h$]”h&]”Œnoemph”ˆj�jŽuh1jB$hj84ubjC$)�”}”(hŒstruct mutex *lock”h]”(jI$)�”}”(hjL$h]”hŒstruct”…”�”}”(hj—4h²hh³Nh´Nubah}”(h]”h ]”jU$ah"]”h$]”h&]”uh1jH$hj“4ubj$)�”}”(hŒ ”h]”hŒ ”…”�”}”(hj¤4h²hh³Nh´Nubah}”(h]”h ]”j $ah"]”h$]”h&]”uh1j$hj“4ubh)�”}”(hhh]”jz!)�”}”(hŒmutex”h]”hŒmutex”…”�”}”(hjµ4h²hh³Nh´Nubah}”(h]”h ]”j…!ah"]”h$]”h&]”uh1jy!hj²4ubah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”jUŒreftype”j€$Œ reftarget”j·4Œmodname”NŒ classname”Nj„$j‡$)�”}”jŠ$]”j_4Œc.atomic_dec_and_mutex_lock”†”asbuh1hhj“4ubj$)�”}”(hŒ ”h]”hŒ ”…”�”}”(hjÓ4h²hh³Nh´Nubah}”(h]”h ]”j $ah"]”h$]”h&]”uh1j$hj“4ubj¡$)�”}”(hj¤$h]”hŒ*”…”�”}”(hjá4h²hh³Nh´Nubah}”(h]”h ]”j­$ah"]”h$]”h&]”uh1j $hj“4ubjz!)�”}”(hŒlock”h]”hŒlock”…”�”}”(hjî4h²hh³Nh´Nubah}”(h]”h ]”j…!ah"]”h$]”h&]”uh1jy!hj“4ubeh}”(h]”h ]”h"]”h$]”h&]”Œnoemph”ˆj�jŽuh1jB$hj84ubeh}”(h]”h ]”h"]”h$]”h&]”j�jŽuh1j<$hjÿ3h²hh³j4h´Mubeh}”(h]”h ]”h"]”h$]”h&]”j�jŽj˜!ˆuh1jm!j™!jš!hjû3h²hh³j4h´Mubah}”(h]”jö3ah ]”(jž!jŸ!eh"]”h$]”h&]”j£!ˆj¤!)j¥!huh1jg!h³j4h´Mhjø3h²hubj§!)�”}”(hhh]”hú)�”}”(hŒ#return holding mutex if we dec to 0”h]”hŒ#return holding mutex if we dec to 0”…”�”}”(hj5h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³Œ_/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1349: ./kernel/locking/mutex.c”h´Mhj5h²hubah}”(h]”h ]”h"]”h$]”h&]”uh1j¦!hjø3h²hh³j4h´Mubeh}”(h]”h ]”(jUŒfunction”eh"]”h$]”h&]”j¸!jUj¹!j05jº!j05j»!‰j¼!‰j½!‰uh1jb!h²hhj@!h³Nh´Nubjò!)�”}”(hŒÚ**Parameters** ``atomic_t *cnt`` the atomic which we are to dec ``struct mutex *lock`` the mutex to return holding if we dec to 0 **Description** return true and hold lock if we dec to 0, return false otherwise”h]”(hú)�”}”(hŒ**Parameters**”h]”j)�”}”(hj:5h]”hŒ Parameters”…”�”}”(hj<5h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhj85ubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³Œ_/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1349: ./kernel/locking/mutex.c”h´Mhj45ubj")�”}”(hhh]”(j")�”}”(hŒ1``atomic_t *cnt`` the atomic which we are to dec ”h]”(j")�”}”(hŒ``atomic_t *cnt``”h]”jI)�”}”(hjY5h]”hŒ atomic_t *cnt”…”�”}”(hj[5h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jHhjW5ubah}”(h]”h ]”h"]”h$]”h&]”uh1j"h³Œ_/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1349: ./kernel/locking/mutex.c”h´MhjS5ubj5")�”}”(hhh]”hú)�”}”(hŒthe atomic which we are to dec”h]”hŒthe atomic which we are to dec”…”�”}”(hjr5h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³jn5h´Mhjo5ubah}”(h]”h ]”h"]”h$]”h&]”uh1j4"hjS5ubeh}”(h]”h ]”h"]”h$]”h&]”uh1j"h³jn5h´MhjP5ubj")�”}”(hŒB``struct mutex *lock`` the mutex to return holding if we dec to 0 ”h]”(j")�”}”(hŒ``struct mutex *lock``”h]”jI)�”}”(hj’5h]”hŒstruct mutex *lock”…”�”}”(hj”5h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jHhj�5ubah}”(h]”h ]”h"]”h$]”h&]”uh1j"h³Œ_/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1349: ./kernel/locking/mutex.c”h´MhjŒ5ubj5")�”}”(hhh]”hú)�”}”(hŒ*the mutex to return holding if we dec to 0”h]”hŒ*the mutex to return holding if we dec to 0”…”�”}”(hj«5h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³j§5h´Mhj¨5ubah}”(h]”h ]”h"]”h$]”h&]”uh1j4"hjŒ5ubeh}”(h]”h ]”h"]”h$]”h&]”uh1j"h³j§5h´MhjP5ubeh}”(h]”h ]”h"]”h$]”h&]”uh1j"hj45ubhú)�”}”(hŒ**Description**”h]”j)�”}”(hjÍ5h]”hŒ Description”…”�”}”(hjÏ5h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhjË5ubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³Œ_/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1349: ./kernel/locking/mutex.c”h´Mhj45ubhú)�”}”(hŒ@return true and hold lock if we dec to 0, return false otherwise”h]”hŒ@return true and hold lock if we dec to 0, return false otherwise”…”�”}”(hjã5h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³Œ_/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1349: ./kernel/locking/mutex.c”h´Mhj45ubeh}”(h]”h ]”Œ kernelindent”ah"]”h$]”h&]”uh1jñ!hj@!h²hh³Nh´Nubeh}”(h]”Œmutex-api-reference”ah ]”h"]”Œmutex api reference”ah$]”h&]”uh1hÄhhÆh²hh³hÃh´M@ubhÅ)�”}”(hhh]”(hÊ)�”}”(hŒFutex API reference”h]”hŒFutex API reference”…”�”}”(hj6h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÉhj6h²hh³hÃh´MIubjR!)�”}”(hhh]”h}”(h]”h ]”h"]”h$]”h&]”Œentries”]”(j^!Œ__futex_hash (C function)”Œc.__futex_hash”hNt”auh1jQ!hj6h²hh³Nh´Nubjc!)�”}”(hhh]”(jh!)�”}”(hŒ�struct futex_hash_bucket * __futex_hash (union futex_key *key, struct futex_private_hash *fph, struct futex_private_hash **fph_p)”h]”jn!)�”}”(hŒstruct futex_hash_bucket *__futex_hash(union futex_key *key, struct futex_private_hash *fph, struct futex_private_hash **fph_p)”h]”(jI$)�”}”(hjL$h]”hŒstruct”…”�”}”(hj+6h²hh³Nh´Nubah}”(h]”h ]”jU$ah"]”h$]”h&]”uh1jH$hj'6h²hh³Œ\/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1355: ./kernel/futex/core.c”h´Miubj$)�”}”(hŒ ”h]”hŒ ”…”�”}”(hj96h²hh³Nh´Nubah}”(h]”h ]”j $ah"]”h$]”h&]”uh1j$hj'6h²hh³j86h´Miubh)�”}”(hhh]”jz!)�”}”(hŒfutex_hash_bucket”h]”hŒfutex_hash_bucket”…”�”}”(hjJ6h²hh³Nh´Nubah}”(h]”h ]”j…!ah"]”h$]”h&]”uh1jy!hjG6ubah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”jUŒreftype”j€$Œ reftarget”jL6Œmodname”NŒ classname”Nj„$j‡$)�”}”jŠ$]”j�$)�”}”j€$Œ __futex_hash”sbŒc.__futex_hash”†”asbuh1hhj'6h²hh³j86h´Miubj$)�”}”(hŒ ”h]”hŒ ”…”�”}”(hjk6h²hh³Nh´Nubah}”(h]”h ]”j $ah"]”h$]”h&]”uh1j$hj'6h²hh³j86h´Miubj¡$)�”}”(hj¤$h]”hŒ*”…”�”}”(hjy6h²hh³Nh´Nubah}”(h]”h ]”j­$ah"]”h$]”h&]”uh1j $hj'6h²hh³j86h´Miubjt!)�”}”(hŒ __futex_hash”h]”jz!)�”}”(hjh6h]”hŒ __futex_hash”…”�”}”(hjŠ6h²hh³Nh´Nubah}”(h]”h ]”j…!ah"]”h$]”h&]”uh1jy!hj†6ubah}”(h]”h ]”(jŒ!j�!eh"]”h$]”h&]”j�jŽuh1js!hj'6h²hh³j86h´Miubj=$)�”}”(hŒY(union futex_key *key, struct futex_private_hash *fph, struct futex_private_hash **fph_p)”h]”(jC$)�”}”(hŒunion futex_key *key”h]”(jI$)�”}”(hŒunion”h]”hŒunion”…”�”}”(hj¥6h²hh³Nh´Nubah}”(h]”h ]”jU$ah"]”h$]”h&]”uh1jH$hj¡6ubj$)�”}”(hŒ ”h]”hŒ ”…”�”}”(hj³6h²hh³Nh´Nubah}”(h]”h ]”j $ah"]”h$]”h&]”uh1j$hj¡6ubh)�”}”(hhh]”jz!)�”}”(hŒ futex_key”h]”hŒ futex_key”…”�”}”(hjÄ6h²hh³Nh´Nubah}”(h]”h ]”j…!ah"]”h$]”h&]”uh1jy!hjÁ6ubah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”jUŒreftype”j€$Œ reftarget”jÆ6Œmodname”NŒ classname”Nj„$j‡$)�”}”jŠ$]”jf6Œc.__futex_hash”†”asbuh1hhj¡6ubj$)�”}”(hŒ ”h]”hŒ ”…”�”}”(hjâ6h²hh³Nh´Nubah}”(h]”h ]”j $ah"]”h$]”h&]”uh1j$hj¡6ubj¡$)�”}”(hj¤$h]”hŒ*”…”�”}”(hjð6h²hh³Nh´Nubah}”(h]”h ]”j­$ah"]”h$]”h&]”uh1j $hj¡6ubjz!)�”}”(hŒkey”h]”hŒkey”…”�”}”(hjý6h²hh³Nh´Nubah}”(h]”h ]”j…!ah"]”h$]”h&]”uh1jy!hj¡6ubeh}”(h]”h ]”h"]”h$]”h&]”Œnoemph”ˆj�jŽuh1jB$hj�6ubjC$)�”}”(hŒstruct futex_private_hash *fph”h]”(jI$)�”}”(hjL$h]”hŒstruct”…”�”}”(hj7h²hh³Nh´Nubah}”(h]”h ]”jU$ah"]”h$]”h&]”uh1jH$hj7ubj$)�”}”(hŒ ”h]”hŒ ”…”�”}”(hj#7h²hh³Nh´Nubah}”(h]”h ]”j $ah"]”h$]”h&]”uh1j$hj7ubh)�”}”(hhh]”jz!)�”}”(hŒfutex_private_hash”h]”hŒfutex_private_hash”…”�”}”(hj47h²hh³Nh´Nubah}”(h]”h ]”j…!ah"]”h$]”h&]”uh1jy!hj17ubah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”jUŒreftype”j€$Œ reftarget”j67Œmodname”NŒ classname”Nj„$j‡$)�”}”jŠ$]”jf6Œc.__futex_hash”†”asbuh1hhj7ubj$)�”}”(hŒ ”h]”hŒ ”…”�”}”(hjR7h²hh³Nh´Nubah}”(h]”h ]”j $ah"]”h$]”h&]”uh1j$hj7ubj¡$)�”}”(hj¤$h]”hŒ*”…”�”}”(hj`7h²hh³Nh´Nubah}”(h]”h ]”j­$ah"]”h$]”h&]”uh1j $hj7ubjz!)�”}”(hŒfph”h]”hŒfph”…”�”}”(hjm7h²hh³Nh´Nubah}”(h]”h ]”j…!ah"]”h$]”h&]”uh1jy!hj7ubeh}”(h]”h ]”h"]”h$]”h&]”Œnoemph”ˆj�jŽuh1jB$hj�6ubjC$)�”}”(hŒ!struct futex_private_hash **fph_p”h]”(jI$)�”}”(hjL$h]”hŒstruct”…”�”}”(hj†7h²hh³Nh´Nubah}”(h]”h ]”jU$ah"]”h$]”h&]”uh1jH$hj‚7ubj$)�”}”(hŒ ”h]”hŒ ”…”�”}”(hj“7h²hh³Nh´Nubah}”(h]”h ]”j $ah"]”h$]”h&]”uh1j$hj‚7ubh)�”}”(hhh]”jz!)�”}”(hŒfutex_private_hash”h]”hŒfutex_private_hash”…”�”}”(hj¤7h²hh³Nh´Nubah}”(h]”h ]”j…!ah"]”h$]”h&]”uh1jy!hj¡7ubah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”jUŒreftype”j€$Œ reftarget”j¦7Œmodname”NŒ classname”Nj„$j‡$)�”}”jŠ$]”jf6Œc.__futex_hash”†”asbuh1hhj‚7ubj$)�”}”(hŒ ”h]”hŒ ”…”�”}”(hjÂ7h²hh³Nh´Nubah}”(h]”h ]”j $ah"]”h$]”h&]”uh1j$hj‚7ubj¡$)�”}”(hj¤$h]”hŒ*”…”�”}”(hjÐ7h²hh³Nh´Nubah}”(h]”h ]”j­$ah"]”h$]”h&]”uh1j $hj‚7ubj¡$)�”}”(hj¤$h]”hŒ*”…”�”}”(hjÝ7h²hh³Nh´Nubah}”(h]”h ]”j­$ah"]”h$]”h&]”uh1j $hj‚7ubjz!)�”}”(hŒfph_p”h]”hŒfph_p”…”�”}”(hjê7h²hh³Nh´Nubah}”(h]”h ]”j…!ah"]”h$]”h&]”uh1jy!hj‚7ubeh}”(h]”h ]”h"]”h$]”h&]”Œnoemph”ˆj�jŽuh1jB$hj�6ubeh}”(h]”h ]”h"]”h$]”h&]”j�jŽuh1j<$hj'6h²hh³j86h´Miubeh}”(h]”h ]”h"]”h$]”h&]”j�jŽj˜!ˆuh1jm!j™!jš!hj#6h²hh³j86h´Miubah}”(h]”j6ah ]”(jž!jŸ!eh"]”h$]”h&]”j£!ˆj¤!)j¥!huh1jg!h³j86h´Mihj 6h²hubj§!)�”}”(hhh]”hú)�”}”(hŒReturn the hash bucket”h]”hŒReturn the hash bucket”…”�”}”(hj8h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³Œ\/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1355: ./kernel/futex/core.c”h´Mihj8h²hubah}”(h]”h ]”h"]”h$]”h&]”uh1j¦!hj 6h²hh³j86h´Miubeh}”(h]”h ]”(jUŒfunction”eh"]”h$]”h&]”j¸!jUj¹!j,8jº!j,8j»!‰j¼!‰j½!‰uh1jb!h²hhj6h³Nh´Nubjò!)�”}”(hXF**Parameters** ``union futex_key *key`` Pointer to the futex key for which the hash is calculated ``struct futex_private_hash *fph`` Pointer to private hash if known ``struct futex_private_hash **fph_p`` Pointer to a private hash pointer; output for the private hash used when set. **Description** We hash on the keys returned from get_futex_key (see below) and return the corresponding hash bucket. If the FUTEX is PROCESS_PRIVATE then a per-process hash bucket (from the private hash) is returned if existing. Otherwise a hash bucket from the global hash is returned.”h]”(hú)�”}”(hŒ**Parameters**”h]”j)�”}”(hj68h]”hŒ Parameters”…”�”}”(hj88h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhj48ubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³Œ\/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1355: ./kernel/futex/core.c”h´Mmhj08ubj")�”}”(hhh]”(j")�”}”(hŒS``union futex_key *key`` Pointer to the futex key for which the hash is calculated ”h]”(j")�”}”(hŒ``union futex_key *key``”h]”jI)�”}”(hjU8h]”hŒunion futex_key *key”…”�”}”(hjW8h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jHhjS8ubah}”(h]”h ]”h"]”h$]”h&]”uh1j"h³Œ\/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1355: ./kernel/futex/core.c”h´MjhjO8ubj5")�”}”(hhh]”hú)�”}”(hŒ9Pointer to the futex key for which the hash is calculated”h]”hŒ9Pointer to the futex key for which the hash is calculated”…”�”}”(hjn8h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³jj8h´Mjhjk8ubah}”(h]”h ]”h"]”h$]”h&]”uh1j4"hjO8ubeh}”(h]”h ]”h"]”h$]”h&]”uh1j"h³jj8h´MjhjL8ubj")�”}”(hŒD``struct futex_private_hash *fph`` Pointer to private hash if known ”h]”(j")�”}”(hŒ"``struct futex_private_hash *fph``”h]”jI)�”}”(hjŽ8h]”hŒstruct futex_private_hash *fph”…”�”}”(hj�8h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jHhjŒ8ubah}”(h]”h ]”h"]”h$]”h&]”uh1j"h³Œ\/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1355: ./kernel/futex/core.c”h´Mkhjˆ8ubj5")�”}”(hhh]”hú)�”}”(hŒ Pointer to private hash if known”h]”hŒ Pointer to private hash if known”…”�”}”(hj§8h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³j£8h´Mkhj¤8ubah}”(h]”h ]”h"]”h$]”h&]”uh1j4"hjˆ8ubeh}”(h]”h ]”h"]”h$]”h&]”uh1j"h³j£8h´MkhjL8ubj")�”}”(hŒt``struct futex_private_hash **fph_p`` Pointer to a private hash pointer; output for the private hash used when set. ”h]”(j")�”}”(hŒ%``struct futex_private_hash **fph_p``”h]”jI)�”}”(hjÇ8h]”hŒ!struct futex_private_hash **fph_p”…”�”}”(hjÉ8h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jHhjÅ8ubah}”(h]”h ]”h"]”h$]”h&]”uh1j"h³Œ\/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1355: ./kernel/futex/core.c”h´MmhjÁ8ubj5")�”}”(hhh]”hú)�”}”(hŒMPointer to a private hash pointer; output for the private hash used when set.”h]”hŒMPointer to a private hash pointer; output for the private hash used when set.”…”�”}”(hjà8h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³Œ\/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1355: ./kernel/futex/core.c”h´MlhjÝ8ubah}”(h]”h ]”h"]”h$]”h&]”uh1j4"hjÁ8ubeh}”(h]”h ]”h"]”h$]”h&]”uh1j"h³jÜ8h´MmhjL8ubeh}”(h]”h ]”h"]”h$]”h&]”uh1j"hj08ubhú)�”}”(hŒ**Description**”h]”j)�”}”(hj9h]”hŒ Description”…”�”}”(hj9h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhj9ubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³Œ\/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1355: ./kernel/futex/core.c”h´Mohj08ubhú)�”}”(hXWe hash on the keys returned from get_futex_key (see below) and return the corresponding hash bucket. If the FUTEX is PROCESS_PRIVATE then a per-process hash bucket (from the private hash) is returned if existing. Otherwise a hash bucket from the global hash is returned.”h]”hXWe hash on the keys returned from get_futex_key (see below) and return the corresponding hash bucket. If the FUTEX is PROCESS_PRIVATE then a per-process hash bucket (from the private hash) is returned if existing. Otherwise a hash bucket from the global hash is returned.”…”�”}”(hj9h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³Œ\/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1355: ./kernel/futex/core.c”h´Mnhj08ubeh}”(h]”h ]”Œ kernelindent”ah"]”h$]”h&]”uh1jñ!hj6h²hh³Nh´NubjR!)�”}”(hhh]”h}”(h]”h ]”h"]”h$]”h&]”Œentries”]”(j^!Œfutex_setup_timer (C function)”Œc.futex_setup_timer”hNt”auh1jQ!hj6h²hh³Nh´Nubjc!)�”}”(hhh]”(jh!)�”}”(hŒtstruct hrtimer_sleeper * futex_setup_timer (ktime_t *time, struct hrtimer_sleeper *timeout, int flags, u64 range_ns)”h]”jn!)�”}”(hŒrstruct hrtimer_sleeper *futex_setup_timer(ktime_t *time, struct hrtimer_sleeper *timeout, int flags, u64 range_ns)”h]”(jI$)�”}”(hjL$h]”hŒstruct”…”�”}”(hjH9h²hh³Nh´Nubah}”(h]”h ]”jU$ah"]”h$]”h&]”uh1jH$hjD9h²hh³Œ\/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1355: ./kernel/futex/core.c”h´Mžubj$)�”}”(hŒ ”h]”hŒ ”…”�”}”(hjV9h²hh³Nh´Nubah}”(h]”h ]”j $ah"]”h$]”h&]”uh1j$hjD9h²hh³jU9h´Mžubh)�”}”(hhh]”jz!)�”}”(hŒhrtimer_sleeper”h]”hŒhrtimer_sleeper”…”�”}”(hjg9h²hh³Nh´Nubah}”(h]”h ]”j…!ah"]”h$]”h&]”uh1jy!hjd9ubah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”jUŒreftype”j€$Œ reftarget”ji9Œmodname”NŒ classname”Nj„$j‡$)�”}”jŠ$]”j�$)�”}”j€$Œfutex_setup_timer”sbŒc.futex_setup_timer”†”asbuh1hhjD9h²hh³jU9h´Mžubj$)�”}”(hŒ ”h]”hŒ ”…”�”}”(hjˆ9h²hh³Nh´Nubah}”(h]”h ]”j $ah"]”h$]”h&]”uh1j$hjD9h²hh³jU9h´Mžubj¡$)�”}”(hj¤$h]”hŒ*”…”�”}”(hj–9h²hh³Nh´Nubah}”(h]”h ]”j­$ah"]”h$]”h&]”uh1j $hjD9h²hh³jU9h´Mžubjt!)�”}”(hŒfutex_setup_timer”h]”jz!)�”}”(hj…9h]”hŒfutex_setup_timer”…”�”}”(hj§9h²hh³Nh´Nubah}”(h]”h ]”j…!ah"]”h$]”h&]”uh1jy!hj£9ubah}”(h]”h ]”(jŒ!j�!eh"]”h$]”h&]”j�jŽuh1js!hjD9h²hh³jU9h´Mžubj=$)�”}”(hŒI(ktime_t *time, struct hrtimer_sleeper *timeout, int flags, u64 range_ns)”h]”(jC$)�”}”(hŒ ktime_t *time”h]”(h)�”}”(hhh]”jz!)�”}”(hŒktime_t”h]”hŒktime_t”…”�”}”(hjÅ9h²hh³Nh´Nubah}”(h]”h ]”j…!ah"]”h$]”h&]”uh1jy!hjÂ9ubah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”jUŒreftype”j€$Œ reftarget”jÇ9Œmodname”NŒ classname”Nj„$j‡$)�”}”jŠ$]”jƒ9Œc.futex_setup_timer”†”asbuh1hhj¾9ubj$)�”}”(hŒ ”h]”hŒ ”…”�”}”(hjã9h²hh³Nh´Nubah}”(h]”h ]”j $ah"]”h$]”h&]”uh1j$hj¾9ubj¡$)�”}”(hj¤$h]”hŒ*”…”�”}”(hjñ9h²hh³Nh´Nubah}”(h]”h ]”j­$ah"]”h$]”h&]”uh1j $hj¾9ubjz!)�”}”(hŒtime”h]”hŒtime”…”�”}”(hjþ9h²hh³Nh´Nubah}”(h]”h ]”j…!ah"]”h$]”h&]”uh1jy!hj¾9ubeh}”(h]”h ]”h"]”h$]”h&]”Œnoemph”ˆj�jŽuh1jB$hjº9ubjC$)�”}”(hŒstruct hrtimer_sleeper *timeout”h]”(jI$)�”}”(hjL$h]”hŒstruct”…”�”}”(hj:h²hh³Nh´Nubah}”(h]”h ]”jU$ah"]”h$]”h&]”uh1jH$hj:ubj$)�”}”(hŒ ”h]”hŒ ”…”�”}”(hj$:h²hh³Nh´Nubah}”(h]”h ]”j $ah"]”h$]”h&]”uh1j$hj:ubh)�”}”(hhh]”jz!)�”}”(hŒhrtimer_sleeper”h]”hŒhrtimer_sleeper”…”�”}”(hj5:h²hh³Nh´Nubah}”(h]”h ]”j…!ah"]”h$]”h&]”uh1jy!hj2:ubah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”jUŒreftype”j€$Œ reftarget”j7:Œmodname”NŒ classname”Nj„$j‡$)�”}”jŠ$]”jƒ9Œc.futex_setup_timer”†”asbuh1hhj:ubj$)�”}”(hŒ ”h]”hŒ ”…”�”}”(hjS:h²hh³Nh´Nubah}”(h]”h ]”j $ah"]”h$]”h&]”uh1j$hj:ubj¡$)�”}”(hj¤$h]”hŒ*”…”�”}”(hja:h²hh³Nh´Nubah}”(h]”h ]”j­$ah"]”h$]”h&]”uh1j $hj:ubjz!)�”}”(hŒtimeout”h]”hŒtimeout”…”�”}”(hjn:h²hh³Nh´Nubah}”(h]”h ]”j…!ah"]”h$]”h&]”uh1jy!hj:ubeh}”(h]”h ]”h"]”h$]”h&]”Œnoemph”ˆj�jŽuh1jB$hjº9ubjC$)�”}”(hŒ int flags”h]”(j$)�”}”(hŒint”h]”hŒint”…”�”}”(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ƒ:ubjz!)�”}”(hŒflags”h]”hŒflags”…”�”}”(hj£:h²hh³Nh´Nubah}”(h]”h ]”j…!ah"]”h$]”h&]”uh1jy!hjƒ:ubeh}”(h]”h ]”h"]”h$]”h&]”Œnoemph”ˆj�jŽuh1jB$hjº9ubjC$)�”}”(hŒ u64 range_ns”h]”(h)�”}”(hhh]”jz!)�”}”(hŒu64”h]”hŒu64”…”�”}”(hj¿:h²hh³Nh´Nubah}”(h]”h ]”j…!ah"]”h$]”h&]”uh1jy!hj¼:ubah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”jUŒreftype”j€$Œ reftarget”jÁ:Œmodname”NŒ classname”Nj„$j‡$)�”}”jŠ$]”jƒ9Œc.futex_setup_timer”†”asbuh1hhj¸:ubj$)�”}”(hŒ ”h]”hŒ ”…”�”}”(hjÝ:h²hh³Nh´Nubah}”(h]”h ]”j $ah"]”h$]”h&]”uh1j$hj¸:ubjz!)�”}”(hŒrange_ns”h]”hŒrange_ns”…”�”}”(hjë:h²hh³Nh´Nubah}”(h]”h ]”j…!ah"]”h$]”h&]”uh1jy!hj¸:ubeh}”(h]”h ]”h"]”h$]”h&]”Œnoemph”ˆj�jŽuh1jB$hjº9ubeh}”(h]”h ]”h"]”h$]”h&]”j�jŽuh1j<$hjD9h²hh³jU9h´Mžubeh}”(h]”h ]”h"]”h$]”h&]”j�jŽj˜!ˆuh1jm!j™!jš!hj@9h²hh³jU9h´Mžubah}”(h]”j;9ah ]”(jž!jŸ!eh"]”h$]”h&]”j£!ˆj¤!)j¥!huh1jg!h³jU9h´Mžhj=9h²hubj§!)�”}”(hhh]”hú)�”}”(hŒset up the sleeping hrtimer.”h]”hŒset up the sleeping hrtimer.”…”�”}”(hj;h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³Œ\/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1355: ./kernel/futex/core.c”h´Mžhj;h²hubah}”(h]”h ]”h"]”h$]”h&]”uh1j¦!hj=9h²hh³jU9h´Mžubeh}”(h]”h ]”(jUŒfunction”eh"]”h$]”h&]”j¸!jUj¹!j-;jº!j-;j»!‰j¼!‰j½!‰uh1jb!h²hhj6h³Nh´Nubjò!)�”}”(hX/**Parameters** ``ktime_t *time`` ptr to the given timeout value ``struct hrtimer_sleeper *timeout`` the hrtimer_sleeper structure to be set up ``int flags`` futex flags ``u64 range_ns`` optional range in ns **Return** Initialized hrtimer_sleeper structure or NULL if no timeout value given”h]”(hú)�”}”(hŒ**Parameters**”h]”j)�”}”(hj7;h]”hŒ Parameters”…”�”}”(hj9;h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhj5;ubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³Œ\/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1355: ./kernel/futex/core.c”h´M¢hj1;ubj")�”}”(hhh]”(j")�”}”(hŒ1``ktime_t *time`` ptr to the given timeout value ”h]”(j")�”}”(hŒ``ktime_t *time``”h]”jI)�”}”(hjV;h]”hŒ ktime_t *time”…”�”}”(hjX;h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jHhjT;ubah}”(h]”h ]”h"]”h$]”h&]”uh1j"h³Œ\/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1355: ./kernel/futex/core.c”h´MŸhjP;ubj5")�”}”(hhh]”hú)�”}”(hŒptr to the given timeout value”h]”hŒptr to the given timeout value”…”�”}”(hjo;h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³jk;h´MŸhjl;ubah}”(h]”h ]”h"]”h$]”h&]”uh1j4"hjP;ubeh}”(h]”h ]”h"]”h$]”h&]”uh1j"h³jk;h´MŸhjM;ubj")�”}”(hŒO``struct hrtimer_sleeper *timeout`` the hrtimer_sleeper structure to be set up ”h]”(j")�”}”(hŒ#``struct hrtimer_sleeper *timeout``”h]”jI)�”}”(hj�;h]”hŒstruct hrtimer_sleeper *timeout”…”�”}”(hj‘;h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jHhj�;ubah}”(h]”h ]”h"]”h$]”h&]”uh1j"h³Œ\/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1355: ./kernel/futex/core.c”h´M hj‰;ubj5")�”}”(hhh]”hú)�”}”(hŒ*the hrtimer_sleeper structure to be set up”h]”hŒ*the hrtimer_sleeper structure to be set up”…”�”}”(hj¨;h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³j¤;h´M hj¥;ubah}”(h]”h ]”h"]”h$]”h&]”uh1j4"hj‰;ubeh}”(h]”h ]”h"]”h$]”h&]”uh1j"h³j¤;h´M hjM;ubj")�”}”(hŒ``int flags`` futex flags ”h]”(j")�”}”(hŒ ``int flags``”h]”jI)�”}”(hjÈ;h]”hŒ int flags”…”�”}”(hjÊ;h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jHhjÆ;ubah}”(h]”h ]”h"]”h$]”h&]”uh1j"h³Œ\/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1355: ./kernel/futex/core.c”h´M¡hjÂ;ubj5")�”}”(hhh]”hú)�”}”(hŒ futex flags”h]”hŒ futex flags”…”�”}”(hjá;h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³jÝ;h´M¡hjÞ;ubah}”(h]”h ]”h"]”h$]”h&]”uh1j4"hjÂ;ubeh}”(h]”h ]”h"]”h$]”h&]”uh1j"h³jÝ;h´M¡hjM;ubj")�”}”(hŒ&``u64 range_ns`` optional range in ns ”h]”(j")�”}”(hŒ``u64 range_ns``”h]”jI)�”}”(hj<h]”hŒ u64 range_ns”…”�”}”(hj<h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jHhjÿ;ubah}”(h]”h ]”h"]”h$]”h&]”uh1j"h³Œ\/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1355: ./kernel/futex/core.c”h´M¢hjû;ubj5")�”}”(hhh]”hú)�”}”(hŒoptional range in ns”h]”hŒoptional range in ns”…”�”}”(hj<h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³j<h´M¢hj<ubah}”(h]”h ]”h"]”h$]”h&]”uh1j4"hjû;ubeh}”(h]”h ]”h"]”h$]”h&]”uh1j"h³j<h´M¢hjM;ubeh}”(h]”h ]”h"]”h$]”h&]”uh1j"hj1;ubhú)�”}”(hŒ **Return**”h]”j)�”}”(hj<<h]”hŒReturn”…”�”}”(hj><h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhj:<ubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³Œ\/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1355: ./kernel/futex/core.c”h´M¤hj1;ubhú)�”}”(hŒGInitialized hrtimer_sleeper structure or NULL if no timeout value given”h]”hŒGInitialized hrtimer_sleeper structure or NULL if no timeout value given”…”�”}”(hjR<h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³Œ\/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1355: ./kernel/futex/core.c”h´M¤hj1;ubeh}”(h]”h ]”Œ kernelindent”ah"]”h$]”h&]”uh1jñ!hj6h²hh³Nh´NubjR!)�”}”(hhh]”h}”(h]”h ]”h"]”h$]”h&]”Œentries”]”(j^!Œget_futex_key (C function)”Œc.get_futex_key”hNt”auh1jQ!hj6h²hh³Nh´Nubjc!)�”}”(hhh]”(jh!)�”}”(hŒeint get_futex_key (u32 __user *uaddr, unsigned int flags, union futex_key *key, enum futex_access rw)”h]”jn!)�”}”(hŒdint get_futex_key(u32 __user *uaddr, unsigned int flags, union futex_key *key, enum futex_access rw)”h]”(j$)�”}”(hŒint”h]”hŒint”…”�”}”(hj�<h²hh³Nh´Nubah}”(h]”h ]”j$ah"]”h$]”h&]”uh1j$hj}<h²hh³Œ\/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1355: ./kernel/futex/core.c”h´Mâubj$)�”}”(hŒ ”h]”hŒ ”…”�”}”(hj�<h²hh³Nh´Nubah}”(h]”h ]”j $ah"]”h$]”h&]”uh1j$hj}<h²hh³j�<h´Mâubjt!)�”}”(hŒ get_futex_key”h]”jz!)�”}”(hŒ get_futex_key”h]”hŒ get_futex_key”…”�”}”(hj¢<h²hh³Nh´Nubah}”(h]”h ]”j…!ah"]”h$]”h&]”uh1jy!hjž<ubah}”(h]”h ]”(jŒ!j�!eh"]”h$]”h&]”j�jŽuh1js!hj}<h²hh³j�<h´Mâubj=$)�”}”(hŒS(u32 __user *uaddr, unsigned int flags, union futex_key *key, enum futex_access rw)”h]”(jC$)�”}”(hŒu32 __user *uaddr”h]”(h)�”}”(hhh]”jz!)�”}”(hŒu32”h]”hŒu32”…”�”}”(hjÁ<h²hh³Nh´Nubah}”(h]”h ]”j…!ah"]”h$]”h&]”uh1jy!hj¾<ubah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”jUŒreftype”j€$Œ reftarget”jÃ<Œmodname”NŒ classname”Nj„$j‡$)�”}”jŠ$]”j�$)�”}”j€$j¤<sbŒc.get_futex_key”†”asbuh1hhjº<ubj$)�”}”(hŒ ”h]”hŒ ”…”�”}”(hjá<h²hh³Nh´Nubah}”(h]”h ]”j $ah"]”h$]”h&]”uh1j$hjº<ubhŒ__user”…”�”}”(hjº<h²hh³Nh´Nubj$)�”}”(hŒ ”h]”hŒ ”…”�”}”(hjó<h²hh³Nh´Nubah}”(h]”h ]”j $ah"]”h$]”h&]”uh1j$hjº<ubj¡$)�”}”(hj¤$h]”hŒ*”…”�”}”(hj=h²hh³Nh´Nubah}”(h]”h ]”j­$ah"]”h$]”h&]”uh1j $hjº<ubjz!)�”}”(hŒuaddr”h]”hŒuaddr”…”�”}”(hj=h²hh³Nh´Nubah}”(h]”h ]”j…!ah"]”h$]”h&]”uh1jy!hjº<ubeh}”(h]”h ]”h"]”h$]”h&]”Œnoemph”ˆj�jŽuh1jB$hj¶<ubjC$)�”}”(hŒunsigned int flags”h]”(j$)�”}”(hŒunsigned”h]”hŒunsigned”…”�”}”(hj'=h²hh³Nh´Nubah}”(h]”h ]”j$ah"]”h$]”h&]”uh1j$hj#=ubj$)�”}”(hŒ ”h]”hŒ ”…”�”}”(hj5=h²hh³Nh´Nubah}”(h]”h ]”j $ah"]”h$]”h&]”uh1j$hj#=ubj$)�”}”(hŒint”h]”hŒint”…”�”}”(hjC=h²hh³Nh´Nubah}”(h]”h ]”j$ah"]”h$]”h&]”uh1j$hj#=ubj$)�”}”(hŒ ”h]”hŒ ”…”�”}”(hjQ=h²hh³Nh´Nubah}”(h]”h ]”j $ah"]”h$]”h&]”uh1j$hj#=ubjz!)�”}”(hŒflags”h]”hŒflags”…”�”}”(hj_=h²hh³Nh´Nubah}”(h]”h ]”j…!ah"]”h$]”h&]”uh1jy!hj#=ubeh}”(h]”h ]”h"]”h$]”h&]”Œnoemph”ˆj�jŽuh1jB$hj¶<ubjC$)�”}”(hŒunion futex_key *key”h]”(jI$)�”}”(hj§6h]”hŒunion”…”�”}”(hjx=h²hh³Nh´Nubah}”(h]”h ]”jU$ah"]”h$]”h&]”uh1jH$hjt=ubj$)�”}”(hŒ ”h]”hŒ ”…”�”}”(hj…=h²hh³Nh´Nubah}”(h]”h ]”j $ah"]”h$]”h&]”uh1j$hjt=ubh)�”}”(hhh]”jz!)�”}”(hŒ futex_key”h]”hŒ futex_key”…”�”}”(hj–=h²hh³Nh´Nubah}”(h]”h ]”j…!ah"]”h$]”h&]”uh1jy!hj“=ubah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”jUŒreftype”j€$Œ reftarget”j˜=Œmodname”NŒ classname”Nj„$j‡$)�”}”jŠ$]”jÝ<Œc.get_futex_key”†”asbuh1hhjt=ubj$)�”}”(hŒ ”h]”hŒ ”…”�”}”(hj´=h²hh³Nh´Nubah}”(h]”h ]”j $ah"]”h$]”h&]”uh1j$hjt=ubj¡$)�”}”(hj¤$h]”hŒ*”…”�”}”(hjÂ=h²hh³Nh´Nubah}”(h]”h ]”j­$ah"]”h$]”h&]”uh1j $hjt=ubjz!)�”}”(hŒkey”h]”hŒkey”…”�”}”(hjÏ=h²hh³Nh´Nubah}”(h]”h ]”j…!ah"]”h$]”h&]”uh1jy!hjt=ubeh}”(h]”h ]”h"]”h$]”h&]”Œnoemph”ˆj�jŽuh1jB$hj¶<ubjC$)�”}”(hŒenum futex_access rw”h]”(jI$)�”}”(hŒenum”h]”hŒenum”…”�”}”(hjè=h²hh³Nh´Nubah}”(h]”h ]”jU$ah"]”h$]”h&]”uh1jH$hjä=ubj$)�”}”(hŒ ”h]”hŒ ”…”�”}”(hjö=h²hh³Nh´Nubah}”(h]”h ]”j $ah"]”h$]”h&]”uh1j$hjä=ubh)�”}”(hhh]”jz!)�”}”(hŒ futex_access”h]”hŒ futex_access”…”�”}”(hj>h²hh³Nh´Nubah}”(h]”h ]”j…!ah"]”h$]”h&]”uh1jy!hj>ubah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”jUŒreftype”j€$Œ reftarget”j >Œmodname”NŒ classname”Nj„$j‡$)�”}”jŠ$]”jÝ<Œc.get_futex_key”†”asbuh1hhjä=ubj$)�”}”(hŒ ”h]”hŒ ”…”�”}”(hj%>h²hh³Nh´Nubah}”(h]”h ]”j $ah"]”h$]”h&]”uh1j$hjä=ubjz!)�”}”(hŒrw”h]”hŒrw”…”�”}”(hj3>h²hh³Nh´Nubah}”(h]”h ]”j…!ah"]”h$]”h&]”uh1jy!hjä=ubeh}”(h]”h ]”h"]”h$]”h&]”Œnoemph”ˆj�jŽuh1jB$hj¶<ubeh}”(h]”h ]”h"]”h$]”h&]”j�jŽuh1j<$hj}<h²hh³j�<h´Mâubeh}”(h]”h ]”h"]”h$]”h&]”j�jŽj˜!ˆuh1jm!j™!jš!hjy<h²hh³j�<h´Mâubah}”(h]”jt<ah ]”(jž!jŸ!eh"]”h$]”h&]”j£!ˆj¤!)j¥!huh1jg!h³j�<h´Mâhjv<h²hubj§!)�”}”(hhh]”hú)�”}”(hŒ-Get parameters which are the keys for a futex”h]”hŒ-Get parameters which are the keys for a futex”…”�”}”(hj]>h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³Œ\/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1355: ./kernel/futex/core.c”h´MâhjZ>h²hubah}”(h]”h ]”h"]”h$]”h&]”uh1j¦!hjv<h²hh³j�<h´Mâubeh}”(h]”h ]”(jUŒfunction”eh"]”h$]”h&]”j¸!jUj¹!ju>jº!ju>j»!‰j¼!‰j½!‰uh1jb!h²hhj6h³Nh´Nubjò!)�”}”(hX<**Parameters** ``u32 __user *uaddr`` virtual address of the futex ``unsigned int flags`` FLAGS_* ``union futex_key *key`` address where result is stored. ``enum futex_access rw`` mapping needs to be read/write (values: FUTEX_READ, FUTEX_WRITE) **Return** a negative error code or 0 **Description** The key words are stored in **key** on success. For shared mappings (when **fshared**), the key is: ( inode->i_sequence, page offset within mapping, offset_within_page ) [ also see get_inode_sequence_number() ] For private mappings (or when **!fshared**), the key is: ( current->mm, address, 0 ) This allows (cross process, where applicable) identification of the futex without keeping the page pinned for the duration of the FUTEX_WAIT. lock_page() might sleep, the caller should not hold a spinlock.”h]”(hú)�”}”(hŒ**Parameters**”h]”j)�”}”(hj>h]”hŒ Parameters”…”�”}”(hj�>h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhj}>ubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³Œ\/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1355: ./kernel/futex/core.c”h´Mæhjy>ubj")�”}”(hhh]”(j")�”}”(hŒ3``u32 __user *uaddr`` virtual address of the futex ”h]”(j")�”}”(hŒ``u32 __user *uaddr``”h]”jI)�”}”(hjž>h]”hŒu32 __user *uaddr”…”�”}”(hj >h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jHhjœ>ubah}”(h]”h ]”h"]”h$]”h&]”uh1j"h³Œ\/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1355: ./kernel/futex/core.c”h´Mãhj˜>ubj5")�”}”(hhh]”hú)�”}”(hŒvirtual address of the futex”h]”hŒvirtual address of the futex”…”�”}”(hj·>h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³j³>h´Mãhj´>ubah}”(h]”h ]”h"]”h$]”h&]”uh1j4"hj˜>ubeh}”(h]”h ]”h"]”h$]”h&]”uh1j"h³j³>h´Mãhj•>ubj")�”}”(hŒ``unsigned int flags`` FLAGS_* ”h]”(j")�”}”(hŒ``unsigned int flags``”h]”jI)�”}”(hj×>h]”hŒunsigned int flags”…”�”}”(hjÙ>h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jHhjÕ>ubah}”(h]”h ]”h"]”h$]”h&]”uh1j"h³Œ\/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1355: ./kernel/futex/core.c”h´MähjÑ>ubj5")�”}”(hhh]”hú)�”}”(hŒFLAGS_*”h]”hŒFLAGS_*”…”�”}”(hjð>h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³jì>h´Mähjí>ubah}”(h]”h ]”h"]”h$]”h&]”uh1j4"hjÑ>ubeh}”(h]”h ]”h"]”h$]”h&]”uh1j"h³jì>h´Mähj•>ubj")�”}”(hŒ9``union futex_key *key`` address where result is stored. ”h]”(j")�”}”(hŒ``union futex_key *key``”h]”jI)�”}”(hj?h]”hŒunion futex_key *key”…”�”}”(hj?h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jHhj?ubah}”(h]”h ]”h"]”h$]”h&]”uh1j"h³Œ\/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1355: ./kernel/futex/core.c”h´Måhj ?ubj5")�”}”(hhh]”hú)�”}”(hŒaddress where result is stored.”h]”hŒaddress where result is stored.”…”�”}”(hj)?h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³j%?h´Måhj&?ubah}”(h]”h ]”h"]”h$]”h&]”uh1j4"hj ?ubeh}”(h]”h ]”h"]”h$]”h&]”uh1j"h³j%?h´Måhj•>ubj")�”}”(hŒZ``enum futex_access rw`` mapping needs to be read/write (values: FUTEX_READ, FUTEX_WRITE) ”h]”(j")�”}”(hŒ``enum futex_access rw``”h]”jI)�”}”(hjI?h]”hŒenum futex_access rw”…”�”}”(hjK?h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jHhjG?ubah}”(h]”h ]”h"]”h$]”h&]”uh1j"h³Œ\/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1355: ./kernel/futex/core.c”h´MçhjC?ubj5")�”}”(hhh]”hú)�”}”(hŒ@mapping needs to be read/write (values: FUTEX_READ, FUTEX_WRITE)”h]”hŒ@mapping needs to be read/write (values: FUTEX_READ, FUTEX_WRITE)”…”�”}”(hjb?h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³Œ\/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1355: ./kernel/futex/core.c”h´Mæhj_?ubah}”(h]”h ]”h"]”h$]”h&]”uh1j4"hjC?ubeh}”(h]”h ]”h"]”h$]”h&]”uh1j"h³j^?h´Mçhj•>ubeh}”(h]”h ]”h"]”h$]”h&]”uh1j"hjy>ubhú)�”}”(hŒ **Return**”h]”j)�”}”(hj…?h]”hŒReturn”…”�”}”(hj‡?h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhjƒ?ubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³Œ\/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1355: ./kernel/futex/core.c”h´Méhjy>ubhú)�”}”(hŒa negative error code or 0”h]”hŒa negative error code or 0”…”�”}”(hj›?h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³Œ\/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1355: ./kernel/futex/core.c”h´Méhjy>ubhú)�”}”(hŒ**Description**”h]”j)�”}”(hj¬?h]”hŒ Description”…”�”}”(hj®?h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhjª?ubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³Œ\/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1355: ./kernel/futex/core.c”h´Mëhjy>ubhú)�”}”(hŒ/The key words are stored in **key** on success.”h]”(hŒThe key words are stored in ”…”�”}”(hjÂ?h²hh³Nh´Nubj)�”}”(hŒ**key**”h]”hŒkey”…”�”}”(hjÊ?h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhjÂ?ubhŒ on success.”…”�”}”(hjÂ?h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hùh³Œ\/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1355: ./kernel/futex/core.c”h´Mêhjy>ubhú)�”}”(hŒ3For shared mappings (when **fshared**), the key is:”h]”(hŒFor shared mappings (when ”…”�”}”(hjã?h²hh³Nh´Nubj)�”}”(hŒ **fshared**”h]”hŒfshared”…”�”}”(hjë?h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhjã?ubhŒ), the key is:”…”�”}”(hjã?h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hùh³Œ\/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1355: ./kernel/futex/core.c”h´Mìhjy>ubj×!)�”}”(hŒF( inode->i_sequence, page offset within mapping, offset_within_page ) ”h]”hú)�”}”(hŒE( inode->i_sequence, page offset within mapping, offset_within_page )”h]”hŒE( inode->i_sequence, page offset within mapping, offset_within_page )”…”�”}”(hj@h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³Œ\/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1355: ./kernel/futex/core.c”h´Mîhj@ubah}”(h]”h ]”h"]”h$]”h&]”uh1jÖ!h³j@h´Mîhjy>ubhú)�”}”(hŒ([ also see get_inode_sequence_number() ]”h]”hŒ([ also see get_inode_sequence_number() ]”…”�”}”(hj@h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³Œ\/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1355: ./kernel/futex/core.c”h´Mðhjy>ubhú)�”}”(hŒ8For private mappings (or when **!fshared**), the key is:”h]”(hŒFor private mappings (or when ”…”�”}”(hj,@h²hh³Nh´Nubj)�”}”(hŒ **!fshared**”h]”hŒ!fshared”…”�”}”(hj4@h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhj,@ubhŒ), the key is:”…”�”}”(hj,@h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hùh³Œ\/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1355: ./kernel/futex/core.c”h´Mòhjy>ubj×!)�”}”(hŒ( current->mm, address, 0 ) ”h]”hú)�”}”(hŒ( current->mm, address, 0 )”h]”hŒ( current->mm, address, 0 )”…”�”}”(hjQ@h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³Œ\/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1355: ./kernel/futex/core.c”h´MôhjM@ubah}”(h]”h ]”h"]”h$]”h&]”uh1jÖ!h³j_@h´Môhjy>ubhú)�”}”(hŒ�This allows (cross process, where applicable) identification of the futex without keeping the page pinned for the duration of the FUTEX_WAIT.”h]”hŒ�This allows (cross process, where applicable) identification of the futex without keeping the page pinned for the duration of the FUTEX_WAIT.”…”�”}”(hjf@h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³Œ\/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1355: ./kernel/futex/core.c”h´Möhjy>ubhú)�”}”(hŒ?lock_page() might sleep, the caller should not hold a spinlock.”h]”hŒ?lock_page() might sleep, the caller should not hold a spinlock.”…”�”}”(hju@h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³Œ\/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1355: ./kernel/futex/core.c”h´Mùhjy>ubeh}”(h]”h ]”Œ kernelindent”ah"]”h$]”h&]”uh1jñ!hj6h²hh³Nh´NubjR!)�”}”(hhh]”h}”(h]”h ]”h"]”h$]”h&]”Œentries”]”(j^!Œ$fault_in_user_writeable (C function)”Œc.fault_in_user_writeable”hNt”auh1jQ!hj6h²hh³Nh´Nubjc!)�”}”(hhh]”(jh!)�”}”(hŒ/int fault_in_user_writeable (u32 __user *uaddr)”h]”jn!)�”}”(hŒ.int fault_in_user_writeable(u32 __user *uaddr)”h]”(j$)�”}”(hŒint”h]”hŒint”…”�”}”(hj¤@h²hh³Nh´Nubah}”(h]”h ]”j$ah"]”h$]”h&]”uh1j$hj @h²hh³Œ\/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1355: ./kernel/futex/core.c”h´MÝubj$)�”}”(hŒ ”h]”hŒ ”…”�”}”(hj³@h²hh³Nh´Nubah}”(h]”h ]”j $ah"]”h$]”h&]”uh1j$hj @h²hh³j²@h´MÝubjt!)�”}”(hŒfault_in_user_writeable”h]”jz!)�”}”(hŒfault_in_user_writeable”h]”hŒfault_in_user_writeable”…”�”}”(hjÅ@h²hh³Nh´Nubah}”(h]”h ]”j…!ah"]”h$]”h&]”uh1jy!hjÁ@ubah}”(h]”h ]”(jŒ!j�!eh"]”h$]”h&]”j�jŽuh1js!hj @h²hh³j²@h´MÝubj=$)�”}”(hŒ(u32 __user *uaddr)”h]”jC$)�”}”(hŒu32 __user *uaddr”h]”(h)�”}”(hhh]”jz!)�”}”(hŒu32”h]”hŒu32”…”�”}”(hjä@h²hh³Nh´Nubah}”(h]”h ]”j…!ah"]”h$]”h&]”uh1jy!hjá@ubah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”jUŒreftype”j€$Œ reftarget”jæ@Œmodname”NŒ classname”Nj„$j‡$)�”}”jŠ$]”j�$)�”}”j€$jÇ@sbŒc.fault_in_user_writeable”†”asbuh1hhjÝ@ubj$)�”}”(hŒ ”h]”hŒ ”…”�”}”(hjAh²hh³Nh´Nubah}”(h]”h ]”j $ah"]”h$]”h&]”uh1j$hjÝ@ubhŒ__user”…”�”}”(hjÝ@h²hh³Nh´Nubj$)�”}”(hŒ ”h]”hŒ ”…”�”}”(hjAh²hh³Nh´Nubah}”(h]”h ]”j $ah"]”h$]”h&]”uh1j$hjÝ@ubj¡$)�”}”(hj¤$h]”hŒ*”…”�”}”(hj$Ah²hh³Nh´Nubah}”(h]”h ]”j­$ah"]”h$]”h&]”uh1j $hjÝ@ubjz!)�”}”(hŒuaddr”h]”hŒuaddr”…”�”}”(hj1Ah²hh³Nh´Nubah}”(h]”h ]”j…!ah"]”h$]”h&]”uh1jy!hjÝ@ubeh}”(h]”h ]”h"]”h$]”h&]”Œnoemph”ˆj�jŽuh1jB$hjÙ@ubah}”(h]”h ]”h"]”h$]”h&]”j�jŽuh1j<$hj @h²hh³j²@h´MÝubeh}”(h]”h ]”h"]”h$]”h&]”j�jŽj˜!ˆuh1jm!j™!jš!hjœ@h²hh³j²@h´MÝubah}”(h]”j—@ah ]”(jž!jŸ!eh"]”h$]”h&]”j£!ˆj¤!)j¥!huh1jg!h³j²@h´MÝhj™@h²hubj§!)�”}”(hhh]”hú)�”}”(hŒ*Fault in user address and verify RW access”h]”hŒ*Fault in user address and verify RW access”…”�”}”(hj[Ah²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³Œ\/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1355: ./kernel/futex/core.c”h´MÝhjXAh²hubah}”(h]”h ]”h"]”h$]”h&]”uh1j¦!hj™@h²hh³j²@h´MÝubeh}”(h]”h ]”(jUŒfunction”eh"]”h$]”h&]”j¸!jUj¹!jsAjº!jsAj»!‰j¼!‰j½!‰uh1jb!h²hhj6h³Nh´Nubjò!)�”}”(hX˜**Parameters** ``u32 __user *uaddr`` pointer to faulting user space address **Description** Slow path to fixup the fault we just took in the atomic write access to **uaddr**. We have no generic implementation of a non-destructive write to the user address. We know that we faulted in the atomic pagefault disabled section so we can as well avoid the #PF overhead by calling get_user_pages() right away.”h]”(hú)�”}”(hŒ**Parameters**”h]”j)�”}”(hj}Ah]”hŒ Parameters”…”�”}”(hjAh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhj{Aubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³Œ\/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1355: ./kernel/futex/core.c”h´MáhjwAubj")�”}”(hhh]”j")�”}”(hŒ=``u32 __user *uaddr`` pointer to faulting user space address ”h]”(j")�”}”(hŒ``u32 __user *uaddr``”h]”jI)�”}”(hjœAh]”hŒu32 __user *uaddr”…”�”}”(hjžAh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jHhjšAubah}”(h]”h ]”h"]”h$]”h&]”uh1j"h³Œ\/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1355: ./kernel/futex/core.c”h´MÞhj–Aubj5")�”}”(hhh]”hú)�”}”(hŒ&pointer to faulting user space address”h]”hŒ&pointer to faulting user space address”…”�”}”(hjµAh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³j±Ah´MÞhj²Aubah}”(h]”h ]”h"]”h$]”h&]”uh1j4"hj–Aubeh}”(h]”h ]”h"]”h$]”h&]”uh1j"h³j±Ah´MÞhj“Aubah}”(h]”h ]”h"]”h$]”h&]”uh1j"hjwAubhú)�”}”(hŒ**Description**”h]”j)�”}”(hj×Ah]”hŒ Description”…”�”}”(hjÙAh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhjÕAubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³Œ\/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1355: ./kernel/futex/core.c”h´MàhjwAubhú)�”}”(hŒRSlow path to fixup the fault we just took in the atomic write access to **uaddr**.”h]”(hŒHSlow path to fixup the fault we just took in the atomic write access to ”…”�”}”(hjíAh²hh³Nh´Nubj)�”}”(hŒ **uaddr**”h]”hŒuaddr”…”�”}”(hjõAh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhjíAubhŒ.”…”�”}”(hjíAh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hùh³Œ\/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1355: ./kernel/futex/core.c”h´MßhjwAubhú)�”}”(hŒãWe have no generic implementation of a non-destructive write to the user address. We know that we faulted in the atomic pagefault disabled section so we can as well avoid the #PF overhead by calling get_user_pages() right away.”h]”hŒãWe have no generic implementation of a non-destructive write to the user address. We know that we faulted in the atomic pagefault disabled section so we can as well avoid the #PF overhead by calling get_user_pages() right away.”…”�”}”(hjBh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³Œ\/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1355: ./kernel/futex/core.c”h´MâhjwAubeh}”(h]”h ]”Œ kernelindent”ah"]”h$]”h&]”uh1jñ!hj6h²hh³Nh´NubjR!)�”}”(hhh]”h}”(h]”h ]”h"]”h$]”h&]”Œentries”]”(j^!Œfutex_top_waiter (C function)”Œc.futex_top_waiter”hNt”auh1jQ!hj6h²hh³Nh´Nubjc!)�”}”(hhh]”(jh!)�”}”(hŒVstruct futex_q * futex_top_waiter (struct futex_hash_bucket *hb, union futex_key *key)”h]”jn!)�”}”(hŒTstruct futex_q *futex_top_waiter(struct futex_hash_bucket *hb, union futex_key *key)”h]”(jI$)�”}”(hjL$h]”hŒstruct”…”�”}”(hj=Bh²hh³Nh´Nubah}”(h]”h ]”jU$ah"]”h$]”h&]”uh1jH$hj9Bh²hh³Œ\/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1355: ./kernel/futex/core.c”h´Möubj$)�”}”(hŒ ”h]”hŒ ”…”�”}”(hjKBh²hh³Nh´Nubah}”(h]”h ]”j $ah"]”h$]”h&]”uh1j$hj9Bh²hh³jJBh´Möubh)�”}”(hhh]”jz!)�”}”(hŒfutex_q”h]”hŒfutex_q”…”�”}”(hj\Bh²hh³Nh´Nubah}”(h]”h ]”j…!ah"]”h$]”h&]”uh1jy!hjYBubah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”jUŒreftype”j€$Œ reftarget”j^BŒmodname”NŒ classname”Nj„$j‡$)�”}”jŠ$]”j�$)�”}”j€$Œfutex_top_waiter”sbŒc.futex_top_waiter”†”asbuh1hhj9Bh²hh³jJBh´Möubj$)�”}”(hŒ ”h]”hŒ ”…”�”}”(hj}Bh²hh³Nh´Nubah}”(h]”h ]”j $ah"]”h$]”h&]”uh1j$hj9Bh²hh³jJBh´Möubj¡$)�”}”(hj¤$h]”hŒ*”…”�”}”(hj‹Bh²hh³Nh´Nubah}”(h]”h ]”j­$ah"]”h$]”h&]”uh1j $hj9Bh²hh³jJBh´Möubjt!)�”}”(hŒfutex_top_waiter”h]”jz!)�”}”(hjzBh]”hŒfutex_top_waiter”…”�”}”(hjœBh²hh³Nh´Nubah}”(h]”h ]”j…!ah"]”h$]”h&]”uh1jy!hj˜Bubah}”(h]”h ]”(jŒ!j�!eh"]”h$]”h&]”j�jŽuh1js!hj9Bh²hh³jJBh´Möubj=$)�”}”(hŒ4(struct futex_hash_bucket *hb, union futex_key *key)”h]”(jC$)�”}”(hŒstruct futex_hash_bucket *hb”h]”(jI$)�”}”(hjL$h]”hŒstruct”…”�”}”(hj·Bh²hh³Nh´Nubah}”(h]”h ]”jU$ah"]”h$]”h&]”uh1jH$hj³Bubj$)�”}”(hŒ ”h]”hŒ ”…”�”}”(hjÄBh²hh³Nh´Nubah}”(h]”h ]”j $ah"]”h$]”h&]”uh1j$hj³Bubh)�”}”(hhh]”jz!)�”}”(hŒfutex_hash_bucket”h]”hŒfutex_hash_bucket”…”�”}”(hjÕBh²hh³Nh´Nubah}”(h]”h ]”j…!ah"]”h$]”h&]”uh1jy!hjÒBubah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”jUŒreftype”j€$Œ reftarget”j×BŒmodname”NŒ classname”Nj„$j‡$)�”}”jŠ$]”jxBŒc.futex_top_waiter”†”asbuh1hhj³Bubj$)�”}”(hŒ ”h]”hŒ ”…”�”}”(hjóBh²hh³Nh´Nubah}”(h]”h ]”j $ah"]”h$]”h&]”uh1j$hj³Bubj¡$)�”}”(hj¤$h]”hŒ*”…”�”}”(hjCh²hh³Nh´Nubah}”(h]”h ]”j­$ah"]”h$]”h&]”uh1j $hj³Bubjz!)�”}”(hŒhb”h]”hŒhb”…”�”}”(hjCh²hh³Nh´Nubah}”(h]”h ]”j…!ah"]”h$]”h&]”uh1jy!hj³Bubeh}”(h]”h ]”h"]”h$]”h&]”Œnoemph”ˆj�jŽuh1jB$hj¯BubjC$)�”}”(hŒunion futex_key *key”h]”(jI$)�”}”(hj§6h]”hŒunion”…”�”}”(hj'Ch²hh³Nh´Nubah}”(h]”h ]”jU$ah"]”h$]”h&]”uh1jH$hj#Cubj$)�”}”(hŒ ”h]”hŒ ”…”�”}”(hj4Ch²hh³Nh´Nubah}”(h]”h ]”j $ah"]”h$]”h&]”uh1j$hj#Cubh)�”}”(hhh]”jz!)�”}”(hŒ futex_key”h]”hŒ futex_key”…”�”}”(hjECh²hh³Nh´Nubah}”(h]”h ]”j…!ah"]”h$]”h&]”uh1jy!hjBCubah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”jUŒreftype”j€$Œ reftarget”jGCŒmodname”NŒ classname”Nj„$j‡$)�”}”jŠ$]”jxBŒc.futex_top_waiter”†”asbuh1hhj#Cubj$)�”}”(hŒ ”h]”hŒ ”…”�”}”(hjcCh²hh³Nh´Nubah}”(h]”h ]”j $ah"]”h$]”h&]”uh1j$hj#Cubj¡$)�”}”(hj¤$h]”hŒ*”…”�”}”(hjqCh²hh³Nh´Nubah}”(h]”h ]”j­$ah"]”h$]”h&]”uh1j $hj#Cubjz!)�”}”(hŒkey”h]”hŒkey”…”�”}”(hj~Ch²hh³Nh´Nubah}”(h]”h ]”j…!ah"]”h$]”h&]”uh1jy!hj#Cubeh}”(h]”h ]”h"]”h$]”h&]”Œnoemph”ˆj�jŽuh1jB$hj¯Bubeh}”(h]”h ]”h"]”h$]”h&]”j�jŽuh1j<$hj9Bh²hh³jJBh´Möubeh}”(h]”h ]”h"]”h$]”h&]”j�jŽj˜!ˆuh1jm!j™!jš!hj5Bh²hh³jJBh´Möubah}”(h]”j0Bah ]”(jž!jŸ!eh"]”h$]”h&]”j£!ˆj¤!)j¥!huh1jg!h³jJBh´Möhj2Bh²hubj§!)�”}”(hhh]”hú)�”}”(hŒ-Return the highest priority waiter on a futex”h]”hŒ-Return the highest priority waiter on a futex”…”�”}”(hj¨Ch²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³Œ\/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1355: ./kernel/futex/core.c”h´Möhj¥Ch²hubah}”(h]”h ]”h"]”h$]”h&]”uh1j¦!hj2Bh²hh³jJBh´Möubeh}”(h]”h ]”(jUŒfunction”eh"]”h$]”h&]”j¸!jUj¹!jÀCjº!jÀCj»!‰j¼!‰j½!‰uh1jb!h²hhj6h³Nh´Nubjò!)�”}”(hŒë**Parameters** ``struct futex_hash_bucket *hb`` the hash bucket the futex_q's reside in ``union futex_key *key`` the futex key (to distinguish it from other futex futex_q's) **Description** Must be called with the hb lock held.”h]”(hú)�”}”(hŒ**Parameters**”h]”j)�”}”(hjÊCh]”hŒ Parameters”…”�”}”(hjÌCh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhjÈCubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³Œ\/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1355: ./kernel/futex/core.c”h´MúhjÄCubj")�”}”(hhh]”(j")�”}”(hŒI``struct futex_hash_bucket *hb`` the hash bucket the futex_q's reside in ”h]”(j")�”}”(hŒ ``struct futex_hash_bucket *hb``”h]”jI)�”}”(hjéCh]”hŒstruct futex_hash_bucket *hb”…”�”}”(hjëCh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jHhjçCubah}”(h]”h ]”h"]”h$]”h&]”uh1j"h³Œ\/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1355: ./kernel/futex/core.c”h´M÷hjãCubj5")�”}”(hhh]”hú)�”}”(hŒ'the hash bucket the futex_q's reside in”h]”hŒ)the hash bucket the futex_q’s reside in”…”�”}”(hjDh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³jþCh´M÷hjÿCubah}”(h]”h ]”h"]”h$]”h&]”uh1j4"hjãCubeh}”(h]”h ]”h"]”h$]”h&]”uh1j"h³jþCh´M÷hjàCubj")�”}”(hŒV``union futex_key *key`` the futex key (to distinguish it from other futex futex_q's) ”h]”(j")�”}”(hŒ``union futex_key *key``”h]”jI)�”}”(hj"Dh]”hŒunion futex_key *key”…”�”}”(hj$Dh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jHhj Dubah}”(h]”h ]”h"]”h$]”h&]”uh1j"h³Œ\/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1355: ./kernel/futex/core.c”h´MøhjDubj5")�”}”(hhh]”hú)�”}”(hŒthe futex key (to distinguish it from other futex futex_q’s)”…”�”}”(hj;Dh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³j7Dh´Møhj8Dubah}”(h]”h ]”h"]”h$]”h&]”uh1j4"hjDubeh}”(h]”h ]”h"]”h$]”h&]”uh1j"h³j7Dh´MøhjàCubeh}”(h]”h ]”h"]”h$]”h&]”uh1j"hjÄCubhú)�”}”(hŒ**Description**”h]”j)�”}”(hj]Dh]”hŒ Description”…”�”}”(hj_Dh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhj[Dubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³Œ\/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1355: ./kernel/futex/core.c”h´MúhjÄCubhú)�”}”(hŒ%Must be called with the hb lock held.”h]”hŒ%Must be called with the hb lock held.”…”�”}”(hjsDh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³Œ\/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1355: ./kernel/futex/core.c”h´MùhjÄCubeh}”(h]”h ]”Œ kernelindent”ah"]”h$]”h&]”uh1jñ!hj6h²hh³Nh´NubjR!)�”}”(hhh]”h}”(h]”h ]”h"]”h$]”h&]”Œentries”]”(j^!Œ#wait_for_owner_exiting (C function)”Œc.wait_for_owner_exiting”hNt”auh1jQ!hj6h²hh³Nh´Nubjc!)�”}”(hhh]”(jh!)�”}”(hŒBvoid wait_for_owner_exiting (int ret, struct task_struct *exiting)”h]”jn!)�”}”(hŒAvoid wait_for_owner_exiting(int ret, struct task_struct *exiting)”h]”(j$)�”}”(hŒvoid”h]”hŒvoid”…”�”}”(hj¢Dh²hh³Nh´Nubah}”(h]”h ]”j$ah"]”h$]”h&]”uh1j$hjžDh²hh³Œ\/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1355: ./kernel/futex/core.c”h´Mubj$)�”}”(hŒ ”h]”hŒ ”…”�”}”(hj±Dh²hh³Nh´Nubah}”(h]”h ]”j $ah"]”h$]”h&]”uh1j$hjžDh²hh³j°Dh´Mubjt!)�”}”(hŒwait_for_owner_exiting”h]”jz!)�”}”(hŒwait_for_owner_exiting”h]”hŒwait_for_owner_exiting”…”�”}”(hjÃDh²hh³Nh´Nubah}”(h]”h ]”j…!ah"]”h$]”h&]”uh1jy!hj¿Dubah}”(h]”h ]”(jŒ!j�!eh"]”h$]”h&]”j�jŽuh1js!hjžDh²hh³j°Dh´Mubj=$)�”}”(hŒ&(int ret, struct task_struct *exiting)”h]”(jC$)�”}”(hŒint ret”h]”(j$)�”}”(hŒint”h]”hŒint”…”�”}”(hjßDh²hh³Nh´Nubah}”(h]”h ]”j$ah"]”h$]”h&]”uh1j$hjÛDubj$)�”}”(hŒ ”h]”hŒ ”…”�”}”(hjíDh²hh³Nh´Nubah}”(h]”h ]”j $ah"]”h$]”h&]”uh1j$hjÛDubjz!)�”}”(hŒret”h]”hŒret”…”�”}”(hjûDh²hh³Nh´Nubah}”(h]”h ]”j…!ah"]”h$]”h&]”uh1jy!hjÛDubeh}”(h]”h ]”h"]”h$]”h&]”Œnoemph”ˆj�jŽuh1jB$hj×DubjC$)�”}”(hŒstruct task_struct *exiting”h]”(jI$)�”}”(hjL$h]”hŒstruct”…”�”}”(hjEh²hh³Nh´Nubah}”(h]”h ]”jU$ah"]”h$]”h&]”uh1jH$hjEubj$)�”}”(hŒ ”h]”hŒ ”…”�”}”(hj!Eh²hh³Nh´Nubah}”(h]”h ]”j $ah"]”h$]”h&]”uh1j$hjEubh)�”}”(hhh]”jz!)�”}”(hŒ task_struct”h]”hŒ task_struct”…”�”•}”(hj2Eh²hh³Nh´Nubah}”(h]”h ]”j…!ah"]”h$]”h&]”uh1jy!hj/Eubah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”jUŒreftype”j€$Œ reftarget”j4EŒmodname”NŒ classname”Nj„$j‡$)�”}”jŠ$]”j�$)�”}”j€$jÅDsbŒc.wait_for_owner_exiting”†”asbuh1hhjEubj$)�”}”(hŒ ”h]”hŒ ”…”�”}”(hjREh²hh³Nh´Nubah}”(h]”h ]”j $ah"]”h$]”h&]”uh1j$hjEubj¡$)�”}”(hj¤$h]”hŒ*”…”�”}”(hj`Eh²hh³Nh´Nubah}”(h]”h ]”j­$ah"]”h$]”h&]”uh1j $hjEubjz!)�”}”(hŒexiting”h]”hŒexiting”…”�”}”(hjmEh²hh³Nh´Nubah}”(h]”h ]”j…!ah"]”h$]”h&]”uh1jy!hjEubeh}”(h]”h ]”h"]”h$]”h&]”Œnoemph”ˆj�jŽuh1jB$hj×Dubeh}”(h]”h ]”h"]”h$]”h&]”j�jŽuh1j<$hjžDh²hh³j°Dh´Mubeh}”(h]”h ]”h"]”h$]”h&]”j�jŽj˜!ˆuh1jm!j™!jš!hjšDh²hh³j°Dh´Mubah}”(h]”j•Dah ]”(jž!jŸ!eh"]”h$]”h&]”j£!ˆj¤!)j¥!huh1jg!h³j°Dh´Mhj—Dh²hubj§!)�”}”(hhh]”hú)�”}”(hŒ Block until the owner has exited”h]”hŒ Block until the owner has exited”…”�”}”(hj—Eh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³Œ\/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1355: ./kernel/futex/core.c”h´Mhj”Eh²hubah}”(h]”h ]”h"]”h$]”h&]”uh1j¦!hj—Dh²hh³j°Dh´Mubeh}”(h]”h ]”(jUŒfunction”eh"]”h$]”h&]”j¸!jUj¹!j¯Ejº!j¯Ej»!‰j¼!‰j½!‰uh1jb!h²hhj6h³Nh´Nubjò!)�”}”(hŒ¼**Parameters** ``int ret`` owner's current futex lock status ``struct task_struct *exiting`` Pointer to the exiting task **Description** Caller must hold a refcount on **exiting**.”h]”(hú)�”}”(hŒ**Parameters**”h]”j)�”}”(hj¹Eh]”hŒ Parameters”…”�”}”(hj»Eh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhj·Eubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³Œ\/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1355: ./kernel/futex/core.c”h´M hj³Eubj")�”}”(hhh]”(j")�”}”(hŒ.``int ret`` owner's current futex lock status ”h]”(j")�”}”(hŒ ``int ret``”h]”jI)�”}”(hjØEh]”hŒint ret”…”�”}”(hjÚEh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jHhjÖEubah}”(h]”h ]”h"]”h$]”h&]”uh1j"h³Œ\/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1355: ./kernel/futex/core.c”h´M hjÒEubj5")�”}”(hhh]”hú)�”}”(hŒ!owner's current futex lock status”h]”hŒ#owner’s current futex lock status”…”�”}”(hjñEh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³jíEh´M hjîEubah}”(h]”h ]”h"]”h$]”h&]”uh1j4"hjÒEubeh}”(h]”h ]”h"]”h$]”h&]”uh1j"h³jíEh´M hjÏEubj")�”}”(hŒ<``struct task_struct *exiting`` Pointer to the exiting task ”h]”(j")�”}”(hŒ``struct task_struct *exiting``”h]”jI)�”}”(hjFh]”hŒstruct task_struct *exiting”…”�”}”(hjFh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jHhjFubah}”(h]”h ]”h"]”h$]”h&]”uh1j"h³Œ\/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1355: ./kernel/futex/core.c”h´M hj Fubj5")�”}”(hhh]”hú)�”}”(hŒPointer to the exiting task”h]”hŒPointer to the exiting task”…”�”}”(hj*Fh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³j&Fh´M hj'Fubah}”(h]”h ]”h"]”h$]”h&]”uh1j4"hj Fubeh}”(h]”h ]”h"]”h$]”h&]”uh1j"h³j&Fh´M hjÏEubeh}”(h]”h ]”h"]”h$]”h&]”uh1j"hj³Eubhú)�”}”(hŒ**Description**”h]”j)�”}”(hjLFh]”hŒ Description”…”�”}”(hjNFh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhjJFubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³Œ\/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1355: ./kernel/futex/core.c”h´M hj³Eubhú)�”}”(hŒ+Caller must hold a refcount on **exiting**.”h]”(hŒCaller must hold a refcount on ”…”�”}”(hjbFh²hh³Nh´Nubj)�”}”(hŒ **exiting**”h]”hŒexiting”…”�”}”(hjjFh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhjbFubhŒ.”…”�”}”(hjbFh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hùh³Œ\/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1355: ./kernel/futex/core.c”h´M hj³Eubeh}”(h]”h ]”Œ kernelindent”ah"]”h$]”h&]”uh1jñ!hj6h²hh³Nh´NubjR!)�”}”(hhh]”h}”(h]”h ]”h"]”h$]”h&]”Œentries”]”(j^!Œ__futex_unqueue (C function)”Œc.__futex_unqueue”hNt”auh1jQ!hj6h²hh³Nh´Nubjc!)�”}”(hhh]”(jh!)�”}”(hŒ(void __futex_unqueue (struct futex_q *q)”h]”jn!)�”}”(hŒ'void __futex_unqueue(struct futex_q *q)”h]”(j$)�”}”(hŒvoid”h]”hŒvoid”…”�”}”(hj£Fh²hh³Nh´Nubah}”(h]”h ]”j$ah"]”h$]”h&]”uh1j$hjŸFh²hh³Œ\/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1355: ./kernel/futex/core.c”h´M'ubj$)�”}”(hŒ ”h]”hŒ ”…”�”}”(hj²Fh²hh³Nh´Nubah}”(h]”h ]”j $ah"]”h$]”h&]”uh1j$hjŸFh²hh³j±Fh´M'ubjt!)�”}”(hŒ__futex_unqueue”h]”jz!)�”}”(hŒ__futex_unqueue”h]”hŒ__futex_unqueue”…”�”}”(hjÄFh²hh³Nh´Nubah}”(h]”h ]”j…!ah"]”h$]”h&]”uh1jy!hjÀFubah}”(h]”h ]”(jŒ!j�!eh"]”h$]”h&]”j�jŽuh1js!hjŸFh²hh³j±Fh´M'ubj=$)�”}”(hŒ(struct futex_q *q)”h]”jC$)�”}”(hŒstruct futex_q *q”h]”(jI$)�”}”(hjL$h]”hŒstruct”…”�”}”(hjàFh²hh³Nh´Nubah}”(h]”h ]”jU$ah"]”h$]”h&]”uh1jH$hjÜFubj$)�”}”(hŒ ”h]”hŒ ”…”�”}”(hjíFh²hh³Nh´Nubah}”(h]”h ]”j $ah"]”h$]”h&]”uh1j$hjÜFubh)�”}”(hhh]”jz!)�”}”(hŒfutex_q”h]”hŒfutex_q”…”�”}”(hjþFh²hh³Nh´Nubah}”(h]”h ]”j…!ah"]”h$]”h&]”uh1jy!hjûFubah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”jUŒreftype”j€$Œ reftarget”jGŒmodname”NŒ classname”Nj„$j‡$)�”}”jŠ$]”j�$)�”}”j€$jÆFsbŒc.__futex_unqueue”†”asbuh1hhjÜFubj$)�”}”(hŒ ”h]”hŒ ”…”�”}”(hjGh²hh³Nh´Nubah}”(h]”h ]”j $ah"]”h$]”h&]”uh1j$hjÜFubj¡$)�”}”(hj¤$h]”hŒ*”…”�”}”(hj,Gh²hh³Nh´Nubah}”(h]”h ]”j­$ah"]”h$]”h&]”uh1j $hjÜFubjz!)�”}”(hŒq”h]”hŒq”…”�”}”(hj9Gh²hh³Nh´Nubah}”(h]”h ]”j…!ah"]”h$]”h&]”uh1jy!hjÜFubeh}”(h]”h ]”h"]”h$]”h&]”Œnoemph”ˆj�jŽuh1jB$hjØFubah}”(h]”h ]”h"]”h$]”h&]”j�jŽuh1j<$hjŸFh²hh³j±Fh´M'ubeh}”(h]”h ]”h"]”h$]”h&]”j�jŽj˜!ˆuh1jm!j™!jš!hj›Fh²hh³j±Fh´M'ubah}”(h]”j–Fah ]”(jž!jŸ!eh"]”h$]”h&]”j£!ˆj¤!)j¥!huh1jg!h³j±Fh´M'hj˜Fh²hubj§!)�”}”(hhh]”hú)�”}”(hŒ-Remove the futex_q from its futex_hash_bucket”h]”hŒ-Remove the futex_q from its futex_hash_bucket”…”�”}”(hjcGh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³Œ\/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1355: ./kernel/futex/core.c”h´M'hj`Gh²hubah}”(h]”h ]”h"]”h$]”h&]”uh1j¦!hj˜Fh²hh³j±Fh´M'ubeh}”(h]”h ]”(jUŒfunction”eh"]”h$]”h&]”j¸!jUj¹!j{Gjº!j{Gj»!‰j¼!‰j½!‰uh1jb!h²hhj6h³Nh´Nubjò!)�”}”(hŒ‘**Parameters** ``struct futex_q *q`` The futex_q to unqueue **Description** The q->lock_ptr must not be NULL and must be held by the caller.”h]”(hú)�”}”(hŒ**Parameters**”h]”j)�”}”(hj…Gh]”hŒ Parameters”…”�”}”(hj‡Gh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhjƒGubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³Œ\/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1355: ./kernel/futex/core.c”h´M+hjGubj")�”}”(hhh]”j")�”}”(hŒ-``struct futex_q *q`` The futex_q to unqueue ”h]”(j")�”}”(hŒ``struct futex_q *q``”h]”jI)�”}”(hj¤Gh]”hŒstruct futex_q *q”…”�”}”(hj¦Gh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jHhj¢Gubah}”(h]”h ]”h"]”h$]”h&]”uh1j"h³Œ\/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1355: ./kernel/futex/core.c”h´M(hjžGubj5")�”}”(hhh]”hú)�”}”(hŒThe futex_q to unqueue”h]”hŒThe futex_q to unqueue”…”�”}”(hj½Gh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³j¹Gh´M(hjºGubah}”(h]”h ]”h"]”h$]”h&]”uh1j4"hjžGubeh}”(h]”h ]”h"]”h$]”h&]”uh1j"h³j¹Gh´M(hj›Gubah}”(h]”h ]”h"]”h$]”h&]”uh1j"hjGubhú)�”}”(hŒ**Description**”h]”j)�”}”(hjßGh]”hŒ Description”…”�”}”(hjáGh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhjÝGubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³Œ\/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1355: ./kernel/futex/core.c”h´M*hjGubhú)�”}”(hŒ@The q->lock_ptr must not be NULL and must be held by the caller.”h]”hŒ@The q->lock_ptr must not be NULL and must be held by the caller.”…”�”}”(hjõGh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³Œ\/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1355: ./kernel/futex/core.c”h´M)hjGubeh}”(h]”h ]”Œ kernelindent”ah"]”h$]”h&]”uh1jñ!hj6h²hh³Nh´NubjR!)�”}”(hhh]”h}”(h]”h ]”h"]”h$]”h&]”Œentries”]”(j^!Œfutex_unqueue (C function)”Œc.futex_unqueue”hNt”auh1jQ!hj6h²hh³Nh´Nubjc!)�”}”(hhh]”(jh!)�”}”(hŒ%int futex_unqueue (struct futex_q *q)”h]”jn!)�”}”(hŒ$int futex_unqueue(struct futex_q *q)”h]”(j$)�”}”(hŒint”h]”hŒint”…”�”}”(hj$Hh²hh³Nh´Nubah}”(h]”h ]”j$ah"]”h$]”h&]”uh1j$hj Hh²hh³Œ\/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1355: ./kernel/futex/core.c”h´Mgubj$)�”}”(hŒ ”h]”hŒ ”…”�”}”(hj3Hh²hh³Nh´Nubah}”(h]”h ]”j $ah"]”h$]”h&]”uh1j$hj Hh²hh³j2Hh´Mgubjt!)�”}”(hŒ futex_unqueue”h]”jz!)�”}”(hŒ futex_unqueue”h]”hŒ futex_unqueue”…”�”}”(hjEHh²hh³Nh´Nubah}”(h]”h ]”j…!ah"]”h$]”h&]”uh1jy!hjAHubah}”(h]”h ]”(jŒ!j�!eh"]”h$]”h&]”j�jŽuh1js!hj Hh²hh³j2Hh´Mgubj=$)�”}”(hŒ(struct futex_q *q)”h]”jC$)�”}”(hŒstruct futex_q *q”h]”(jI$)�”}”(hjL$h]”hŒstruct”…”�”}”(hjaHh²hh³Nh´Nubah}”(h]”h ]”jU$ah"]”h$]”h&]”uh1jH$hj]Hubj$)�”}”(hŒ ”h]”hŒ ”…”�”}”(hjnHh²hh³Nh´Nubah}”(h]”h ]”j $ah"]”h$]”h&]”uh1j$hj]Hubh)�”}”(hhh]”jz!)�”}”(hŒfutex_q”h]”hŒfutex_q”…”�”}”(hjHh²hh³Nh´Nubah}”(h]”h ]”j…!ah"]”h$]”h&]”uh1jy!hj|Hubah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”jUŒreftype”j€$Œ reftarget”j�HŒmodname”NŒ classname”Nj„$j‡$)�”}”jŠ$]”j�$)�”}”j€$jGHsbŒc.futex_unqueue”†”asbuh1hhj]Hubj$)�”}”(hŒ ”h]”hŒ ”…”�”}”(hjŸHh²hh³Nh´Nubah}”(h]”h ]”j $ah"]”h$]”h&]”uh1j$hj]Hubj¡$)�”}”(hj¤$h]”hŒ*”…”�”}”(hj­Hh²hh³Nh´Nubah}”(h]”h ]”j­$ah"]”h$]”h&]”uh1j $hj]Hubjz!)�”}”(hj;Gh]”hŒq”…”�”}”(hjºHh²hh³Nh´Nubah}”(h]”h ]”j…!ah"]”h$]”h&]”uh1jy!hj]Hubeh}”(h]”h ]”h"]”h$]”h&]”Œnoemph”ˆj�jŽuh1jB$hjYHubah}”(h]”h ]”h"]”h$]”h&]”j�jŽuh1j<$hj Hh²hh³j2Hh´Mgubeh}”(h]”h ]”h"]”h$]”h&]”j�jŽj˜!ˆuh1jm!j™!jš!hjHh²hh³j2Hh´Mgubah}”(h]”jHah ]”(jž!jŸ!eh"]”h$]”h&]”j£!ˆj¤!)j¥!huh1jg!h³j2Hh´MghjHh²hubj§!)�”}”(hhh]”hú)�”}”(hŒ-Remove the futex_q from its futex_hash_bucket”h]”hŒ-Remove the futex_q from its futex_hash_bucket”…”�”}”(hjãHh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³Œ\/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1355: ./kernel/futex/core.c”h´MghjàHh²hubah}”(h]”h ]”h"]”h$]”h&]”uh1j¦!hjHh²hh³j2Hh´Mgubeh}”(h]”h ]”(jUŒfunction”eh"]”h$]”h&]”j¸!jUj¹!jûHjº!jûHj»!‰j¼!‰j½!‰uh1jb!h²hhj6h³Nh´Nubjò!)�”}”(hXh**Parameters** ``struct futex_q *q`` The futex_q to unqueue **Description** The q->lock_ptr must not be held by the caller. A call to futex_unqueue() must be paired with exactly one earlier call to futex_queue(). **Return** - 1 - if the futex_q was still queued (and we removed unqueued it); - 0 - if the futex_q was already removed by the waking thread”h]”(hú)�”}”(hŒ**Parameters**”h]”j)�”}”(hjIh]”hŒ Parameters”…”�”}”(hjIh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhjIubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³Œ\/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1355: ./kernel/futex/core.c”h´MkhjÿHubj")�”}”(hhh]”j")�”}”(hŒ-``struct futex_q *q`` The futex_q to unqueue ”h]”(j")�”}”(hŒ``struct futex_q *q``”h]”jI)�”}”(hj$Ih]”hŒstruct futex_q *q”…”�”}”(hj&Ih²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jHhj"Iubah}”(h]”h ]”h"]”h$]”h&]”uh1j"h³Œ\/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1355: ./kernel/futex/core.c”h´MhhjIubj5")�”}”(hhh]”hú)�”}”(hŒThe futex_q to unqueue”h]”hŒThe futex_q to unqueue”…”�”}”(hj=Ih²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³j9Ih´Mhhj:Iubah}”(h]”h ]”h"]”h$]”h&]”uh1j4"hjIubeh}”(h]”h ]”h"]”h$]”h&]”uh1j"h³j9Ih´MhhjIubah}”(h]”h ]”h"]”h$]”h&]”uh1j"hjÿHubhú)�”}”(hŒ**Description**”h]”j)�”}”(hj_Ih]”hŒ Description”…”�”}”(hjaIh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhj]Iubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³Œ\/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1355: ./kernel/futex/core.c”h´MjhjÿHubhú)�”}”(hŒˆThe q->lock_ptr must not be held by the caller. A call to futex_unqueue() must be paired with exactly one earlier call to futex_queue().”h]”hŒˆThe q->lock_ptr must not be held by the caller. A call to futex_unqueue() must be paired with exactly one earlier call to futex_queue().”…”�”}”(hjuIh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³Œ\/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1355: ./kernel/futex/core.c”h´MihjÿHubhú)�”}”(hŒ **Return**”h]”j)�”}”(hj†Ih]”hŒReturn”…”�”}”(hjˆIh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhj„Iubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³Œ\/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1355: ./kernel/futex/core.c”h´MlhjÿHubj½ )�”}”(hhh]”(j )�”}”(hŒA1 - if the futex_q was still queued (and we removed unqueued it);”h]”hú)�”}”(hj¡Ih]”hŒA1 - if the futex_q was still queued (and we removed unqueued it);”…”�”}”(hj£Ih²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³Œ\/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1355: ./kernel/futex/core.c”h´MmhjŸIubah}”(h]”h ]”h"]”h$]”h&]”uh1jÁ hjœIubj )�”}”(hŒ;0 - if the futex_q was already removed by the waking thread”h]”hú)�”}”(hj¹Ih]”hŒ;0 - if the futex_q was already removed by the waking thread”…”�”}”(hj»Ih²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³Œ\/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1355: ./kernel/futex/core.c”h´Mnhj·Iubah}”(h]”h ]”h"]”h$]”h&]”uh1jÁ hjœIubeh}”(h]”h ]”h"]”h$]”h&]”j5 j6 uh1j¼ h³j°Ih´MmhjÿHubeh}”(h]”h ]”Œ kernelindent”ah"]”h$]”h&]”uh1jñ!hj6h²hh³Nh´NubjR!)�”}”(hhh]”h}”(h]”h ]”h"]”h$]”h&]”Œentries”]”(j^!Œ!futex_exit_recursive (C function)”Œc.futex_exit_recursive”hNt”auh1jQ!hj6h²hh³Nh´Nubjc!)�”}”(hhh]”(jh!)�”}”(hŒ3void futex_exit_recursive (struct task_struct *tsk)”h]”jn!)�”}”(hŒ2void futex_exit_recursive(struct task_struct *tsk)”h]”(j$)�”}”(hŒvoid”h]”hŒvoid”…”�”}”(hjõIh²hh³Nh´Nubah}”(h]”h ]”j$ah"]”h$]”h&]”uh1j$hjñIh²hh³Œ\/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1355: ./kernel/futex/core.c”h´MÈubj$)�”}”(hŒ ”h]”hŒ ”…”�”}”(hjJh²hh³Nh´Nubah}”(h]”h ]”j $ah"]”h$]”h&]”uh1j$hjñIh²hh³jJh´MÈubjt!)�”}”(hŒfutex_exit_recursive”h]”jz!)�”}”(hŒfutex_exit_recursive”h]”hŒfutex_exit_recursive”…”�”}”(hjJh²hh³Nh´Nubah}”(h]”h ]”j…!ah"]”h$]”h&]”uh1jy!hjJubah}”(h]”h ]”(jŒ!j�!eh"]”h$]”h&]”j�jŽuh1js!hjñIh²hh³jJh´MÈubj=$)�”}”(hŒ(struct task_struct *tsk)”h]”jC$)�”}”(hŒstruct task_struct *tsk”h]”(jI$)�”}”(hjL$h]”hŒstruct”…”�”}”(hj2Jh²hh³Nh´Nubah}”(h]”h ]”jU$ah"]”h$]”h&]”uh1jH$hj.Jubj$)�”}”(hŒ ”h]”hŒ ”…”�”}”(hj?Jh²hh³Nh´Nubah}”(h]”h ]”j $ah"]”h$]”h&]”uh1j$hj.Jubh)�”}”(hhh]”jz!)�”}”(hŒ task_struct”h]”hŒ task_struct”…”�”}”(hjPJh²hh³Nh´Nubah}”(h]”h ]”j…!ah"]”h$]”h&]”uh1jy!hjMJubah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”jUŒreftype”j€$Œ reftarget”jRJŒmodname”NŒ classname”Nj„$j‡$)�”}”jŠ$]”j�$)�”}”j€$jJsbŒc.futex_exit_recursive”†”asbuh1hhj.Jubj$)�”}”(hŒ ”h]”hŒ ”…”�”}”(hjpJh²hh³Nh´Nubah}”(h]”h ]”j $ah"]”h$]”h&]”uh1j$hj.Jubj¡$)�”}”(hj¤$h]”hŒ*”…”�”}”(hj~Jh²hh³Nh´Nubah}”(h]”h ]”j­$ah"]”h$]”h&]”uh1j $hj.Jubjz!)�”}”(hŒtsk”h]”hŒtsk”…”�”}”(hj‹Jh²hh³Nh´Nubah}”(h]”h ]”j…!ah"]”h$]”h&]”uh1jy!hj.Jubeh}”(h]”h ]”h"]”h$]”h&]”Œnoemph”ˆj�jŽuh1jB$hj*Jubah}”(h]”h ]”h"]”h$]”h&]”j�jŽuh1j<$hjñIh²hh³jJh´MÈubeh}”(h]”h ]”h"]”h$]”h&]”j�jŽj˜!ˆuh1jm!j™!jš!hjíIh²hh³jJh´MÈubah}”(h]”jèIah ]”(jž!jŸ!eh"]”h$]”h&]”j£!ˆj¤!)j¥!huh1jg!h³jJh´MÈhjêIh²hubj§!)�”}”(hhh]”hú)�”}”(hŒ-Set the tasks futex state to FUTEX_STATE_DEAD”h]”hŒ-Set the tasks futex state to FUTEX_STATE_DEAD”…”�”}”(hjµJh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³Œ\/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1355: ./kernel/futex/core.c”h´MÈhj²Jh²hubah}”(h]”h ]”h"]”h$]”h&]”uh1j¦!hjêIh²hh³jJh´MÈubeh}”(h]”h ]”(jUŒfunction”eh"]”h$]”h&]”j¸!jUj¹!jÍJjº!jÍJj»!‰j¼!‰j½!‰uh1jb!h²hhj6h³Nh´Nubjò!)�”}”(hX**Parameters** ``struct task_struct *tsk`` task to set the state on **Description** Set the futex exit state of the task lockless. The futex waiter code observes that state when a task is exiting and loops until the task has actually finished the futex cleanup. The worst case for this is that the waiter runs through the wait loop until the state becomes visible. This is called from the recursive fault handling path in make_task_dead(). This is best effort. Either the futex exit code has run already or not. If the OWNER_DIED bit has been set on the futex then the waiter can take it over. If not, the problem is pushed back to user space. If the futex exit code did not run yet, then an already queued waiter might block forever, but there is nothing which can be done about that.”h]”(hú)�”}”(hŒ**Parameters**”h]”j)�”}”(hj×Jh]”hŒ Parameters”…”�”}”(hjÙJh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhjÕJubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³Œ\/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1355: ./kernel/futex/core.c”h´MÌhjÑJubj")�”}”(hhh]”j")�”}”(hŒ5``struct task_struct *tsk`` task to set the state on ”h]”(j")�”}”(hŒ``struct task_struct *tsk``”h]”jI)�”}”(hjöJh]”hŒstruct task_struct *tsk”…”�”}”(hjøJh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jHhjôJubah}”(h]”h ]”h"]”h$]”h&]”uh1j"h³Œ\/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1355: ./kernel/futex/core.c”h´MÉhjðJubj5")�”}”(hhh]”hú)�”}”(hŒtask to set the state on”h]”hŒtask to set the state on”…”�”}”(hjKh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³j Kh´MÉhj Kubah}”(h]”h ]”h"]”h$]”h&]”uh1j4"hjðJubeh}”(h]”h ]”h"]”h$]”h&]”uh1j"h³j Kh´MÉhjíJubah}”(h]”h ]”h"]”h$]”h&]”uh1j"hjÑJubhú)�”}”(hŒ**Description**”h]”j)�”}”(hj1Kh]”hŒ Description”…”�”}”(hj3Kh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhj/Kubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³Œ\/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1355: ./kernel/futex/core.c”h´MËhjÑJubhú)�”}”(hXSet the futex exit state of the task lockless. The futex waiter code observes that state when a task is exiting and loops until the task has actually finished the futex cleanup. The worst case for this is that the waiter runs through the wait loop until the state becomes visible.”h]”hXSet the futex exit state of the task lockless. The futex waiter code observes that state when a task is exiting and loops until the task has actually finished the futex cleanup. The worst case for this is that the waiter runs through the wait loop until the state becomes visible.”…”�”}”(hjGKh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³Œ\/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1355: ./kernel/futex/core.c”h´MÊhjÑJubhú)�”}”(hŒJThis is called from the recursive fault handling path in make_task_dead().”h]”hŒJThis is called from the recursive fault handling path in make_task_dead().”…”�”}”(hjVKh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³Œ\/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1355: ./kernel/futex/core.c”h´MÏhjÑJubhú)�”}”(hXYThis is best effort. Either the futex exit code has run already or not. If the OWNER_DIED bit has been set on the futex then the waiter can take it over. If not, the problem is pushed back to user space. If the futex exit code did not run yet, then an already queued waiter might block forever, but there is nothing which can be done about that.”h]”hXYThis is best effort. Either the futex exit code has run already or not. If the OWNER_DIED bit has been set on the futex then the waiter can take it over. If not, the problem is pushed back to user space. If the futex exit code did not run yet, then an already queued waiter might block forever, but there is nothing which can be done about that.”…”�”}”(hjeKh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³Œ\/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1355: ./kernel/futex/core.c”h´MÑhjÑJubeh}”(h]”h ]”Œ kernelindent”ah"]”h$]”h&]”uh1jñ!hj6h²hh³Nh´NubjR!)�”}”(hhh]”h}”(h]”h ]”h"]”h$]”h&]”Œentries”]”(j^!Œfutex_q (C struct)”Œ c.futex_q”hNt”auh1jQ!hj6h²hh³Œ]/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1358: ./kernel/futex/futex.h”h´Nubjc!)�”}”(hhh]”(jh!)�”}”(hŒfutex_q”h]”jn!)�”}”(hŒstruct futex_q”h]”(jI$)�”}”(hjL$h]”hŒstruct”…”�”}”(hj•Kh²hh³Nh´Nubah}”(h]”h ]”jU$ah"]”h$]”h&]”uh1jH$hj‘Kh²hh³Œ]/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1358: ./kernel/futex/futex.h”h´Kubj$)�”}”(hŒ ”h]”hŒ ”…”�”}”(hj£Kh²hh³Nh´Nubah}”(h]”h ]”j $ah"]”h$]”h&]”uh1j$hj‘Kh²hh³j¢Kh´Kubjt!)�”}”(hŒfutex_q”h]”jz!)�”}”(hj�Kh]”hŒfutex_q”…”�”}”(hjµKh²hh³Nh´Nubah}”(h]”h ]”j…!ah"]”h$]”h&]”uh1jy!hj±Kubah}”(h]”h ]”(jŒ!j�!eh"]”h$]”h&]”j�jŽuh1js!hj‘Kh²hh³j¢Kh´Kubeh}”(h]”h ]”h"]”h$]”h&]”j�jŽj˜!ˆuh1jm!j™!jš!hj�Kh²hh³j¢Kh´Kubah}”(h]”j‡Kah ]”(jž!jŸ!eh"]”h$]”h&]”j£!ˆj¤!)j¥!huh1jg!h³j¢Kh´KhjŠKh²hubj§!)�”}”(hhh]”hú)�”}”(hŒ2The hashed futex queue entry, one per waiting task”h]”hŒ2The hashed futex queue entry, one per waiting task”…”�”}”(hj×Kh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³Œ]/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1358: ./kernel/futex/futex.h”h´K¶hjÔKh²hubah}”(h]”h ]”h"]”h$]”h&]”uh1j¦!hjŠKh²hh³j¢Kh´Kubeh}”(h]”h ]”(jUŒstruct”eh"]”h$]”h&]”j¸!jUj¹!jïKjº!jïKj»!‰j¼!‰j½!‰uh1jb!h²hhj6h³j‰Kh´Nubjò!)�”}”(hX³**Definition**:: struct futex_q { struct plist_node list; struct task_struct *task; spinlock_t *lock_ptr; futex_wake_fn *wake; void *wake_data; union futex_key key; struct futex_pi_state *pi_state; struct rt_mutex_waiter *rt_waiter; union futex_key *requeue_pi_key; u32 bitset; atomic_t requeue_state; struct futex_private_hash *drop_fph; #ifdef CONFIG_PREEMPT_RT; struct rcuwait requeue_wait; #endif; }; **Members** ``list`` priority-sorted list of tasks waiting on this futex ``task`` the task waiting on the futex ``lock_ptr`` the hash bucket lock ``wake`` the wake handler for this queue ``wake_data`` data associated with the wake handler ``key`` the key the futex is hashed on ``pi_state`` optional priority inheritance state ``rt_waiter`` rt_waiter storage for use with requeue_pi ``requeue_pi_key`` the requeue_pi target futex key ``bitset`` bitset for the optional bitmasked wakeup ``requeue_state`` State field for futex_requeue_pi() ``drop_fph`` Waiter should drop the extra private hash reference when set ``requeue_wait`` RCU wait for futex_requeue_pi() (RT only)”h]”(hú)�”}”(hŒ**Definition**::”h]”(j)�”}”(hŒ**Definition**”h]”hŒ Definition”…”�”}”(hjûKh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhj÷KubhŒ:”…”�”}”(hj÷Kh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hùh³Œ]/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1358: ./kernel/futex/futex.h”h´KºhjóKubj~)�”}”(hX·struct futex_q { struct plist_node list; struct task_struct *task; spinlock_t *lock_ptr; futex_wake_fn *wake; void *wake_data; union futex_key key; struct futex_pi_state *pi_state; struct rt_mutex_waiter *rt_waiter; union futex_key *requeue_pi_key; u32 bitset; atomic_t requeue_state; struct futex_private_hash *drop_fph; #ifdef CONFIG_PREEMPT_RT; struct rcuwait requeue_wait; #endif; };”h]”hX·struct futex_q { struct plist_node list; struct task_struct *task; spinlock_t *lock_ptr; futex_wake_fn *wake; void *wake_data; union futex_key key; struct futex_pi_state *pi_state; struct rt_mutex_waiter *rt_waiter; union futex_key *requeue_pi_key; u32 bitset; atomic_t requeue_state; struct futex_private_hash *drop_fph; #ifdef CONFIG_PREEMPT_RT; struct rcuwait requeue_wait; #endif; };”…”�”}”hjLsbah}”(h]”h ]”h"]”h$]”h&]”j�jŽuh1j}h³Œ]/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1358: ./kernel/futex/futex.h”h´K¼hjóKubhú)�”}”(hŒ **Members**”h]”j)�”}”(hj%Lh]”hŒMembers”…”�”}”(hj'Lh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhj#Lubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³Œ]/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1358: ./kernel/futex/futex.h”h´KÎhjóKubj")�”}”(hhh]”(j")�”}”(hŒ=``list`` priority-sorted list of tasks waiting on this futex ”h]”(j")�”}”(hŒ``list``”h]”jI)�”}”(hjDLh]”hŒlist”…”�”}”(hjFLh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jHhjBLubah}”(h]”h ]”h"]”h$]”h&]”uh1j"h³Œ]/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1358: ./kernel/futex/futex.h”h´K¸hj>Lubj5")�”}”(hhh]”hú)�”}”(hŒ3priority-sorted list of tasks waiting on this futex”h]”hŒ3priority-sorted list of tasks waiting on this futex”…”�”}”(hj]Lh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³jYLh´K¸hjZLubah}”(h]”h ]”h"]”h$]”h&]”uh1j4"hj>Lubeh}”(h]”h ]”h"]”h$]”h&]”uh1j"h³jYLh´K¸hj;Lubj")�”}”(hŒ'``task`` the task waiting on the futex ”h]”(j")�”}”(hŒ``task``”h]”jI)�”}”(hj}Lh]”hŒtask”…”�”}”(hjLh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jHhj{Lubah}”(h]”h ]”h"]”h$]”h&]”uh1j"h³Œ]/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1358: ./kernel/futex/futex.h”h´K¹hjwLubj5")�”}”(hhh]”hú)�”}”(hŒthe task waiting on the futex”h]”hŒthe task waiting on the futex”…”�”}”(hj–Lh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³j’Lh´K¹hj“Lubah}”(h]”h ]”h"]”h$]”h&]”uh1j4"hjwLubeh}”(h]”h ]”h"]”h$]”h&]”uh1j"h³j’Lh´K¹hj;Lubj")�”}”(hŒ"``lock_ptr`` the hash bucket lock ”h]”(j")�”}”(hŒ ``lock_ptr``”h]”jI)�”}”(hj¶Lh]”hŒlock_ptr”…”�”}”(hj¸Lh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jHhj´Lubah}”(h]”h ]”h"]”h$]”h&]”uh1j"h³Œ]/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1358: ./kernel/futex/futex.h”h´Kºhj°Lubj5")�”}”(hhh]”hú)�”}”(hŒthe hash bucket lock”h]”hŒthe hash bucket lock”…”�”}”(hjÏLh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³jËLh´KºhjÌLubah}”(h]”h ]”h"]”h$]”h&]”uh1j4"hj°Lubeh}”(h]”h ]”h"]”h$]”h&]”uh1j"h³jËLh´Kºhj;Lubj")�”}”(hŒ)``wake`` the wake handler for this queue ”h]”(j")�”}”(hŒ``wake``”h]”jI)�”}”(hjïLh]”hŒwake”…”�”}”(hjñLh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jHhjíLubah}”(h]”h ]”h"]”h$]”h&]”uh1j"h³Œ]/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1358: ./kernel/futex/futex.h”h´K»hjéLubj5")�”}”(hhh]”hú)�”}”(hŒthe wake handler for this queue”h]”hŒthe wake handler for this queue”…”�”}”(hjMh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³jMh´K»hjMubah}”(h]”h ]”h"]”h$]”h&]”uh1j4"hjéLubeh}”(h]”h ]”h"]”h$]”h&]”uh1j"h³jMh´K»hj;Lubj")�”}”(hŒ4``wake_data`` data associated with the wake handler ”h]”(j")�”}”(hŒ ``wake_data``”h]”jI)�”}”(hj(Mh]”hŒ wake_data”…”�”}”(hj*Mh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jHhj&Mubah}”(h]”h ]”h"]”h$]”h&]”uh1j"h³Œ]/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1358: ./kernel/futex/futex.h”h´K¼hj"Mubj5")�”}”(hhh]”hú)�”}”(hŒ%data associated with the wake handler”h]”hŒ%data associated with the wake handler”…”�”}”(hjAMh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³j=Mh´K¼hj>Mubah}”(h]”h ]”h"]”h$]”h&]”uh1j4"hj"Mubeh}”(h]”h ]”h"]”h$]”h&]”uh1j"h³j=Mh´K¼hj;Lubj")�”}”(hŒ'``key`` the key the futex is hashed on ”h]”(j")�”}”(hŒ``key``”h]”jI)�”}”(hjaMh]”hŒkey”…”�”}”(hjcMh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jHhj_Mubah}”(h]”h ]”h"]”h$]”h&]”uh1j"h³Œ]/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1358: ./kernel/futex/futex.h”h´K½hj[Mubj5")�”}”(hhh]”hú)�”}”(hŒthe key the futex is hashed on”h]”hŒthe key the futex is hashed on”…”�”}”(hjzMh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³jvMh´K½hjwMubah}”(h]”h ]”h"]”h$]”h&]”uh1j4"hj[Mubeh}”(h]”h ]”h"]”h$]”h&]”uh1j"h³jvMh´K½hj;Lubj")�”}”(hŒ1``pi_state`` optional priority inheritance state ”h]”(j")�”}”(hŒ ``pi_state``”h]”jI)�”}”(hjšMh]”hŒpi_state”…”�”}”(hjœMh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jHhj˜Mubah}”(h]”h ]”h"]”h$]”h&]”uh1j"h³Œ]/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1358: ./kernel/futex/futex.h”h´K¾hj”Mubj5")�”}”(hhh]”hú)�”}”(hŒ#optional priority inheritance state”h]”hŒ#optional priority inheritance state”…”�”}”(hj³Mh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³j¯Mh´K¾hj°Mubah}”(h]”h ]”h"]”h$]”h&]”uh1j4"hj”Mubeh}”(h]”h ]”h"]”h$]”h&]”uh1j"h³j¯Mh´K¾hj;Lubj")�”}”(hŒ8``rt_waiter`` rt_waiter storage for use with requeue_pi ”h]”(j")�”}”(hŒ ``rt_waiter``”h]”jI)�”}”(hjÓMh]”hŒ rt_waiter”…”�”}”(hjÕMh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jHhjÑMubah}”(h]”h ]”h"]”h$]”h&]”uh1j"h³Œ]/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1358: ./kernel/futex/futex.h”h´K¿hjÍMubj5")�”}”(hhh]”hú)�”}”(hŒ)rt_waiter storage for use with requeue_pi”h]”hŒ)rt_waiter storage for use with requeue_pi”…”�”}”(hjìMh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³jèMh´K¿hjéMubah}”(h]”h ]”h"]”h$]”h&]”uh1j4"hjÍMubeh}”(h]”h ]”h"]”h$]”h&]”uh1j"h³jèMh´K¿hj;Lubj")�”}”(hŒ3``requeue_pi_key`` the requeue_pi target futex key ”h]”(j")�”}”(hŒ``requeue_pi_key``”h]”jI)�”}”(hj Nh]”hŒrequeue_pi_key”…”�”}”(hjNh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jHhj Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j"h³Œ]/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1358: ./kernel/futex/futex.h”h´KÀhjNubj5")�”}”(hhh]”hú)�”}”(hŒthe requeue_pi target futex key”h]”hŒthe requeue_pi target futex key”…”�”}”(hj%Nh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³j!Nh´KÀhj"Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j4"hjNubeh}”(h]”h ]”h"]”h$]”h&]”uh1j"h³j!Nh´KÀhj;Lubj")�”}”(hŒ4``bitset`` bitset for the optional bitmasked wakeup ”h]”(j")�”}”(hŒ ``bitset``”h]”jI)�”}”(hjENh]”hŒbitset”…”�”}”(hjGNh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jHhjCNubah}”(h]”h ]”h"]”h$]”h&]”uh1j"h³Œ]/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1358: ./kernel/futex/futex.h”h´KÁhj?Nubj5")�”}”(hhh]”hú)�”}”(hŒ(bitset for the optional bitmasked wakeup”h]”hŒ(bitset for the optional bitmasked wakeup”…”�”}”(hj^Nh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³jZNh´KÁhj[Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j4"hj?Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1j"h³jZNh´KÁhj;Lubj")�”}”(hŒ5``requeue_state`` State field for futex_requeue_pi() ”h]”(j")�”}”(hŒ``requeue_state``”h]”jI)�”}”(hj~Nh]”hŒ requeue_state”…”�”}”(hj€Nh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jHhj|Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j"h³Œ]/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1358: ./kernel/futex/futex.h”h´KÂhjxNubj5")�”}”(hhh]”hú)�”}”(hŒ"State field for futex_requeue_pi()”h]”hŒ"State field for futex_requeue_pi()”…”�”}”(hj—Nh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³j“Nh´KÂhj”Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j4"hjxNubeh}”(h]”h ]”h"]”h$]”h&]”uh1j"h³j“Nh´KÂhj;Lubj")�”}”(hŒJ``drop_fph`` Waiter should drop the extra private hash reference when set ”h]”(j")�”}”(hŒ ``drop_fph``”h]”jI)�”}”(hj·Nh]”hŒdrop_fph”…”�”}”(hj¹Nh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jHhjµNubah}”(h]”h ]”h"]”h$]”h&]”uh1j"h³Œ]/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1358: ./kernel/futex/futex.h”h´KÃhj±Nubj5")�”}”(hhh]”hú)�”}”(hŒlist `) || q->lock_ptr == 0. The order of wakeup is always to make the first condition true, then the second.”h]”(hŒmA futex_q has a woken state, just like tasks have TASK_RUNNING. It is considered woken when plist_node_empty(”…”�”}”(hjXOh²hh³Nh´Nubh)�”}”(hŒ:c:type:`q->list `”h]”jI)�”}”(hjbOh]”hŒq->list”…”�”}”(hjdOh²hh³Nh´Nubah}”(h]”h ]”(jTjUŒc-type”eh"]”h$]”h&]”uh1jHhj`Oubah}”(h]”h ]”h"]”h$]”h&]”Œrefdoc”jaŒ refdomain”jUŒreftype”Œtype”Œ refexplicit”ˆŒrefwarn”‰j„$j‡$)�”}”jŠ$]”sbjgj;Guh1hh³Œ]/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1358: ./kernel/futex/futex.h”h´KÇhjXOubhŒg) || q->lock_ptr == 0. The order of wakeup is always to make the first condition true, then the second.”…”�”}”(hjXOh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hùh³j�Oh´KÇhj6h²hubhú)�”}”(hŒxPI futexes are typically woken before they are removed from the hash list via the rt_mutex code. See futex_unqueue_pi().”h]”hŒxPI futexes are typically woken before they are removed from the hash list via the rt_mutex code. See futex_unqueue_pi().”…”�”}”(hjŒOh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³Œ]/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1358: ./kernel/futex/futex.h”h´KÌhj6h²hubjR!)�”}”(hhh]”h}”(h]”h ]”h"]”h$]”h&]”Œentries”]”(j^!Œfutex_match (C function)”Œ c.futex_match”hNt”auh1jQ!hj6h²hh³j‰Kh´Nubjc!)�”}”(hhh]”(jh!)�”}”(hŒ>int futex_match (union futex_key *key1, union futex_key *key2)”h]”jn!)�”}”(hŒ=int futex_match(union futex_key *key1, union futex_key *key2)”h]”(j$)�”}”(hŒint”h]”hŒint”…”�”}”(hj´Oh²hh³Nh´Nubah}”(h]”h ]”j$ah"]”h$]”h&]”uh1j$hj°Oh²hh³Œ]/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1358: ./kernel/futex/futex.h”h´M ubj$)�”}”(hŒ ”h]”hŒ ”…”�”}”(hjÃOh²hh³Nh´Nubah}”(h]”h ]”j $ah"]”h$]”h&]”uh1j$hj°Oh²hh³jÂOh´M ubjt!)�”}”(hŒ futex_match”h]”jz!)�”}”(hŒ futex_match”h]”hŒ futex_match”…”�”}”(hjÕOh²hh³Nh´Nubah}”(h]”h ]”j…!ah"]”h$]”h&]”uh1jy!hjÑOubah}”(h]”h ]”(jŒ!j�!eh"]”h$]”h&]”j�jŽuh1js!hj°Oh²hh³jÂOh´M ubj=$)�”}”(hŒ.(union futex_key *key1, union futex_key *key2)”h]”(jC$)�”}”(hŒunion futex_key *key1”h]”(jI$)�”}”(hj§6h]”hŒunion”…”�”}”(hjñOh²hh³Nh´Nubah}”(h]”h ]”jU$ah"]”h$]”h&]”uh1jH$hjíOubj$)�”}”(hŒ ”h]”hŒ ”…”�”}”(hjþOh²hh³Nh´Nubah}”(h]”h ]”j $ah"]”h$]”h&]”uh1j$hjíOubh)�”}”(hhh]”jz!)�”}”(hŒ futex_key”h]”hŒ futex_key”…”�”}”(hjPh²hh³Nh´Nubah}”(h]”h ]”j…!ah"]”h$]”h&]”uh1jy!hj Pubah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”jUŒreftype”j€$Œ reftarget”jPŒmodname”NŒ classname”Nj„$j‡$)�”}”jŠ$]”j�$)�”}”j€$j×OsbŒ c.futex_match”†”asbuh1hhjíOubj$)�”}”(hŒ ”h]”hŒ ”…”�”}”(hj/Ph²hh³Nh´Nubah}”(h]”h ]”j $ah"]”h$]”h&]”uh1j$hjíOubj¡$)�”}”(hj¤$h]”hŒ*”…”�”}”(hj=Ph²hh³Nh´Nubah}”(h]”h ]”j­$ah"]”h$]”h&]”uh1j $hjíOubjz!)�”}”(hŒkey1”h]”hŒkey1”…”�”}”(hjJPh²hh³Nh´Nubah}”(h]”h ]”j…!ah"]”h$]”h&]”uh1jy!hjíOubeh}”(h]”h ]”h"]”h$]”h&]”Œnoemph”ˆj�jŽuh1jB$hjéOubjC$)�”}”(hŒunion futex_key *key2”h]”(jI$)�”}”(hj§6h]”hŒunion”…”�”}”(hjcPh²hh³Nh´Nubah}”(h]”h ]”jU$ah"]”h$]”h&]”uh1jH$hj_Pubj$)�”}”(hŒ ”h]”hŒ ”…”�”}”(hjpPh²hh³Nh´Nubah}”(h]”h ]”j $ah"]”h$]”h&]”uh1j$hj_Pubh)�”}”(hhh]”jz!)�”}”(hŒ futex_key”h]”hŒ futex_key”…”�”}”(hj�Ph²hh³Nh´Nubah}”(h]”h ]”j…!ah"]”h$]”h&]”uh1jy!hj~Pubah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”jUŒreftype”j€$Œ reftarget”jƒPŒmodname”NŒ classname”Nj„$j‡$)�”}”jŠ$]”j+PŒ c.futex_match”†”asbuh1hhj_Pubj$)�”}”(hŒ ”h]”hŒ ”…”�”}”(hjŸPh²hh³Nh´Nubah}”(h]”h ]”j $ah"]”h$]”h&]”uh1j$hj_Pubj¡$)�”}”(hj¤$h]”hŒ*”…”�”}”(hj­Ph²hh³Nh´Nubah}”(h]”h ]”j­$ah"]”h$]”h&]”uh1j $hj_Pubjz!)�”}”(hŒkey2”h]”hŒkey2”…”�”}”(hjºPh²hh³Nh´Nubah}”(h]”h ]”j…!ah"]”h$]”h&]”uh1jy!hj_Pubeh}”(h]”h ]”h"]”h$]”h&]”Œnoemph”ˆj�jŽuh1jB$hjéOubeh}”(h]”h ]”h"]”h$]”h&]”j�jŽuh1j<$hj°Oh²hh³jÂOh´M ubeh}”(h]”h ]”h"]”h$]”h&]”j�jŽj˜!ˆuh1jm!j™!jš!hj¬Oh²hh³jÂOh´M ubah}”(h]”j§Oah ]”(jž!jŸ!eh"]”h$]”h&]”j£!ˆj¤!)j¥!huh1jg!h³jÂOh´M hj©Oh²hubj§!)�”}”(hhh]”hú)�”}”(hŒ&Check whether two futex keys are equal”h]”hŒ&Check whether two futex keys are equal”…”�”}”(hjäPh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³Œ]/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1358: ./kernel/futex/futex.h”h´M hjáPh²hubah}”(h]”h ]”h"]”h$]”h&]”uh1j¦!hj©Oh²hh³jÂOh´M ubeh}”(h]”h ]”(jUŒfunction”eh"]”h$]”h&]”j¸!jUj¹!jüPjº!jüPj»!‰j¼!‰j½!‰uh1jb!h²hhj6h³j‰Kh´Nubjò!)�”}”(hŒ­**Parameters** ``union futex_key *key1`` Pointer to key1 ``union futex_key *key2`` Pointer to key2 **Description** Return 1 if two futex_keys are equal, 0 otherwise.”h]”(hú)�”}”(hŒ**Parameters**”h]”j)�”}”(hjQh]”hŒ Parameters”…”�”}”(hjQh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhjQubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³Œ]/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1358: ./kernel/futex/futex.h”h´MhjQubj")�”}”(hhh]”(j")�”}”(hŒ*``union futex_key *key1`` Pointer to key1 ”h]”(j")�”}”(hŒ``union futex_key *key1``”h]”jI)�”}”(hj%Qh]”hŒunion futex_key *key1”…”�”}”(hj'Qh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jHhj#Qubah}”(h]”h ]”h"]”h$]”h&]”uh1j"h³Œ]/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1358: ./kernel/futex/futex.h”h´M hjQubj5")�”}”(hhh]”hú)�”}”(hŒPointer to key1”h]”hŒPointer to key1”…”�”}”(hj>Qh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³j:Qh´M hj;Qubah}”(h]”h ]”h"]”h$]”h&]”uh1j4"hjQubeh}”(h]”h ]”h"]”h$]”h&]”uh1j"h³j:Qh´M hjQubj")�”}”(hŒ*``union futex_key *key2`` Pointer to key2 ”h]”(j")�”}”(hŒ``union futex_key *key2``”h]”jI)�”}”(hj^Qh]”hŒunion futex_key *key2”…”�”}”(hj`Qh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jHhj\Qubah}”(h]”h ]”h"]”h$]”h&]”uh1j"h³Œ]/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1358: ./kernel/futex/futex.h”h´M hjXQubj5")�”}”(hhh]”hú)�”}”(hŒPointer to key2”h]”hŒPointer to key2”…”�”}”(hjwQh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³jsQh´M hjtQubah}”(h]”h ]”h"]”h$]”h&]”uh1j4"hjXQubeh}”(h]”h ]”h"]”h$]”h&]”uh1j"h³jsQh´M hjQubeh}”(h]”h ]”h"]”h$]”h&]”uh1j"hjQubhú)�”}”(hŒ**Description**”h]”j)�”}”(hj™Qh]”hŒ Description”…”�”}”(hj›Qh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhj—Qubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³Œ]/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1358: ./kernel/futex/futex.h”h´MhjQubhú)�”}”(hŒ2Return 1 if two futex_keys are equal, 0 otherwise.”h]”hŒ2Return 1 if two futex_keys are equal, 0 otherwise.”…”�”}”(hj¯Qh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³Œ]/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1358: ./kernel/futex/futex.h”h´M hjQubeh}”(h]”h ]”Œ kernelindent”ah"]”h$]”h&]”uh1jñ!hj6h²hh³j‰Kh´NubjR!)�”}”(hhh]”h}”(h]”h ]”h"]”h$]”h&]”Œentries”]”(j^!Œfutex_queue (C function)”Œ c.futex_queue”hNt”auh1jQ!hj6h²hh³j‰Kh´Nubjc!)�”}”(hhh]”(jh!)�”}”(hŒ\void futex_queue (struct futex_q *q, struct futex_hash_bucket *hb, struct task_struct *task)”h]”jn!)�”}”(hŒ[void futex_queue(struct futex_q *q, struct futex_hash_bucket *hb, struct task_struct *task)”h]”(j$)�”}”(hŒvoid”h]”hŒvoid”…”�”}”(hjÞQh²hh³Nh´Nubah}”(h]”h ]”j$ah"]”h$]”h&]”uh1j$hjÚQh²hh³Œ]/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1358: ./kernel/futex/futex.h”h´M:ubj$)�”}”(hŒ ”h]”hŒ ”…”�”}”(hjíQh²hh³Nh´Nubah}”(h]”h ]”j $ah"]”h$]”h&]”uh1j$hjÚQh²hh³jìQh´M:ubjt!)�”}”(hŒ futex_queue”h]”jz!)�”}”(hŒ futex_queue”h]”hŒ futex_queue”…”�”}”(hjÿQh²hh³Nh´Nubah}”(h]”h ]”j…!ah"]”h$]”h&]”uh1jy!hjûQubah}”(h]”h ]”(jŒ!j�!eh"]”h$]”h&]”j�jŽuh1js!hjÚQh²hh³jìQh´M:ubj=$)�”}”(hŒK(struct futex_q *q, struct futex_hash_bucket *hb, struct task_struct *task)”h]”(jC$)�”}”(hŒstruct futex_q *q”h]”(jI$)�”}”(hjL$h]”hŒstruct”…”�”}”(hjRh²hh³Nh´Nubah}”(h]”h ]”jU$ah"]”h$]”h&]”uh1jH$hjRubj$)�”}”(hŒ ”h]”hŒ ”…”�”}”(hj(Rh²hh³Nh´Nubah}”(h]”h ]”j $ah"]”h$]”h&]”uh1j$hjRubh)�”}”(hhh]”jz!)�”}”(hŒfutex_q”h]”hŒfutex_q”…”�”}”(hj9Rh²hh³Nh´Nubah}”(h]”h ]”j…!ah"]”h$]”h&]”uh1jy!hj6Rubah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”jUŒreftype”j€$Œ reftarget”j;RŒmodname”NŒ classname”Nj„$j‡$)�”}”jŠ$]”j�$)�”}”j€$jRsbŒ c.futex_queue”†”asbuh1hhjRubj$)�”}”(hŒ ”h]”hŒ ”…”�”}”(hjYRh²hh³Nh´Nubah}”(h]”h ]”j $ah"]”h$]”h&]”uh1j$hjRubj¡$)�”}”(hj¤$h]”hŒ*”…”�”}”(hjgRh²hh³Nh´Nubah}”(h]”h ]”j­$ah"]”h$]”h&]”uh1j $hjRubjz!)�”}”(hj;Gh]”hŒq”…”�”}”(hjtRh²hh³Nh´Nubah}”(h]”h ]”j…!ah"]”h$]”h&]”uh1jy!hjRubeh}”(h]”h ]”h"]”h$]”h&]”Œnoemph”ˆj�jŽuh1jB$hjRubjC$)�”}”(hŒstruct futex_hash_bucket *hb”h]”(jI$)�”}”(hjL$h]”hŒstruct”…”�”}”(hjŒRh²hh³Nh´Nubah}”(h]”h ]”jU$ah"]”h$]”h&]”uh1jH$hjˆRubj$)�”}”(hŒ ”h]”hŒ ”…”�”}”(hj™Rh²hh³Nh´Nubah}”(h]”h ]”j $ah"]”h$]”h&]”uh1j$hjˆRubh)�”}”(hhh]”jz!)�”}”(hŒfutex_hash_bucket”h]”hŒfutex_hash_bucket”…”�”}”(hjªRh²hh³Nh´Nubah}”(h]”h ]”j…!ah"]”h$]”h&]”uh1jy!hj§Rubah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”jUŒreftype”j€$Œ reftarget”j¬RŒmodname”NŒ classname”Nj„$j‡$)�”}”jŠ$]”jURŒ c.futex_queue”†”asbuh1hhjˆRubj$)�”}”(hŒ ”h]”hŒ ”…”�”}”(hjÈRh²hh³Nh´Nubah}”(h]”h ]”j $ah"]”h$]”h&]”uh1j$hjˆRubj¡$)�”}”(hj¤$h]”hŒ*”…”�”}”(hjÖRh²hh³Nh´Nubah}”(h]”h ]”j­$ah"]”h$]”h&]”uh1j $hjˆRubjz!)�”}”(hŒhb”h]”hŒhb”…”�”}”(hjãRh²hh³Nh´Nubah}”(h]”h ]”j…!ah"]”h$]”h&]”uh1jy!hjˆRubeh}”(h]”h ]”h"]”h$]”h&]”Œnoemph”ˆj�jŽuh1jB$hjRubjC$)�”}”(hŒstruct task_struct *task”h]”(jI$)�”}”(hjL$h]”hŒstruct”…”�”}”(hjüRh²hh³Nh´Nubah}”(h]”h ]”jU$ah"]”h$]”h&]”uh1jH$hjøRubj$)�”}”(hŒ ”h]”hŒ ”…”�”}”(hj Sh²hh³Nh´Nubah}”(h]”h ]”j $ah"]”h$]”h&]”uh1j$hjøRubh)�”}”(hhh]”jz!)�”}”(hŒ task_struct”h]”hŒ task_struct”…”�”}”(hjSh²hh³Nh´Nubah}”(h]”h ]”j…!ah"]”h$]”h&]”uh1jy!hjSubah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”jUŒreftype”j€$Œ reftarget”jSŒmodname”NŒ classname”Nj„$j‡$)�”}”jŠ$]”jURŒ c.futex_queue”†”asbuh1hhjøRubj$)�”}”(hŒ ”h]”hŒ ”…”�”}”(hj8Sh²hh³Nh´Nubah}”(h]”h ]”j $ah"]”h$]”h&]”uh1j$hjøRubj¡$)�”}”(hj¤$h]”hŒ*”…”�”}”(hjFSh²hh³Nh´Nubah}”(h]”h ]”j­$ah"]”h$]”h&]”uh1j $hjøRubjz!)�”}”(hŒtask”h]”hŒtask”…”�”}”(hjSSh²hh³Nh´Nubah}”(h]”h ]”j…!ah"]”h$]”h&]”uh1jy!hjøRubeh}”(h]”h ]”h"]”h$]”h&]”Œnoemph”ˆj�jŽuh1jB$hjRubeh}”(h]”h ]”h"]”h$]”h&]”j�jŽuh1j<$hjÚQh²hh³jìQh´M:ubeh}”(h]”h ]”h"]”h$]”h&]”j�jŽj˜!ˆuh1jm!j™!jš!hjÖQh²hh³jìQh´M:ubah}”(h]”jÑQah ]”(jž!jŸ!eh"]”h$]”h&]”j£!ˆj¤!)j¥!huh1jg!h³jìQh´M:hjÓQh²hubj§!)�”}”(hhh]”hú)�”}”(hŒ,Enqueue the futex_q on the futex_hash_bucket”h]”hŒ,Enqueue the futex_q on the futex_hash_bucket”…”�”}”(hj}Sh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³Œ]/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1358: ./kernel/futex/futex.h”h´M:hjzSh²hubah}”(h]”h ]”h"]”h$]”h&]”uh1j¦!hjÓQh²hh³jìQh´M:ubeh}”(h]”h ]”(jUŒfunction”eh"]”h$]”h&]”j¸!jUj¹!j•Sjº!j•Sj»!‰j¼!‰j½!‰uh1jb!h²hhj6h³j‰Kh´Nubjò!)�”}”(hX˜**Parameters** ``struct futex_q *q`` The futex_q to enqueue ``struct futex_hash_bucket *hb`` The destination hash bucket ``struct task_struct *task`` Task queueing this futex **Description** The hb->lock must be held by the caller, and is released here. A call to futex_queue() is typically paired with exactly one call to futex_unqueue(). The exceptions involve the PI related operations, which may use futex_unqueue_pi() or nothing if the unqueue is done as part of the wake process and the unqueue state is implicit in the state of woken task (see futex_wait_requeue_pi() for an example). Note that **task** may be NULL, for async usage of futexes.”h]”(hú)�”}”(hŒ**Parameters**”h]”j)�”}”(hjŸSh]”hŒ Parameters”…”�”}”(hj¡Sh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhj�Subah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³Œ]/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1358: ./kernel/futex/futex.h”h´M>hj™Subj")�”}”(hhh]”(j")�”}”(hŒ-``struct futex_q *q`` The futex_q to enqueue ”h]”(j")�”}”(hŒ``struct futex_q *q``”h]”jI)�”}”(hj¾Sh]”hŒstruct futex_q *q”…”�”}”(hjÀSh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jHhj¼Subah}”(h]”h ]”h"]”h$]”h&]”uh1j"h³Œ]/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1358: ./kernel/futex/futex.h”h´M;hj¸Subj5")�”}”(hhh]”hú)�”}”(hŒThe futex_q to enqueue”h]”hŒThe futex_q to enqueue”…”�”}”(hj×Sh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³jÓSh´M;hjÔSubah}”(h]”h ]”h"]”h$]”h&]”uh1j4"hj¸Subeh}”(h]”h ]”h"]”h$]”h&]”uh1j"h³jÓSh´M;hjµSubj")�”}”(hŒ=``struct futex_hash_bucket *hb`` The destination hash bucket ”h]”(j")�”}”(hŒ ``struct futex_hash_bucket *hb``”h]”jI)�”}”(hj÷Sh]”hŒstruct futex_hash_bucket *hb”…”�”}”(hjùSh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jHhjõSubah}”(h]”h ]”h"]”h$]”h&]”uh1j"h³Œ]/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1358: ./kernel/futex/futex.h”h´M<hjñSubj5")�”}”(hhh]”hú)�”}”(hŒThe destination hash bucket”h]”hŒThe destination hash bucket”…”�”}”(hjTh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³j Th´M<hj Tubah}”(h]”h ]”h"]”h$]”h&]”uh1j4"hjñSubeh}”(h]”h ]”h"]”h$]”h&]”uh1j"h³j Th´M<hjµSubj")�”}”(hŒ6``struct task_struct *task`` Task queueing this futex ”h]”(j")�”}”(hŒ``struct task_struct *task``”h]”jI)�”}”(hj0Th]”hŒstruct task_struct *task”…”�”}”(hj2Th²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jHhj.Tubah}”(h]”h ]”h"]”h$]”h&]”uh1j"h³Œ]/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1358: ./kernel/futex/futex.h”h´M=hj*Tubj5")�”}”(hhh]”hú)�”}”(hŒTask queueing this futex”h]”hŒTask queueing this futex”…”�”}”(hjITh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³jETh´M=hjFTubah}”(h]”h ]”h"]”h$]”h&]”uh1j4"hj*Tubeh}”(h]”h ]”h"]”h$]”h&]”uh1j"h³jETh´M=hjµSubeh}”(h]”h ]”h"]”h$]”h&]”uh1j"hj™Subhú)�”}”(hŒ**Description**”h]”j)�”}”(hjkTh]”hŒ Description”…”�”}”(hjmTh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhjiTubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³Œ]/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1358: ./kernel/futex/futex.h”h´M?hj™Subhú)�”}”(hX‘The hb->lock must be held by the caller, and is released here. A call to futex_queue() is typically paired with exactly one call to futex_unqueue(). The exceptions involve the PI related operations, which may use futex_unqueue_pi() or nothing if the unqueue is done as part of the wake process and the unqueue state is implicit in the state of woken task (see futex_wait_requeue_pi() for an example).”h]”hX‘The hb->lock must be held by the caller, and is released here. A call to futex_queue() is typically paired with exactly one call to futex_unqueue(). The exceptions involve the PI related operations, which may use futex_unqueue_pi() or nothing if the unqueue is done as part of the wake process and the unqueue state is implicit in the state of woken task (see futex_wait_requeue_pi() for an example).”…”�”}”(hj�Th²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³Œ]/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1358: ./kernel/futex/futex.h”h´M>hj™Subhú)�”}”(hŒ;Note that **task** may be NULL, for async usage of futexes.”h]”(hŒ Note that ”…”�”}”(hj�Th²hh³Nh´Nubj)�”}”(hŒ**task**”h]”hŒtask”…”�”}”(hj˜Th²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhj�TubhŒ) may be NULL, for async usage of futexes.”…”�”}”(hj�Th²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hùh³Œ]/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1358: ./kernel/futex/futex.h”h´MEhj™Subeh}”(h]”h ]”Œ kernelindent”ah"]”h$]”h&]”uh1jñ!hj6h²hh³j‰Kh´NubjR!)�”}”(hhh]”h}”(h]”h ]”h"]”h$]”h&]”Œentries”]”(j^!Œfutex_vector (C struct)”Œc.futex_vector”hNt”auh1jQ!hj6h²hh³j‰Kh´Nubjc!)�”}”(hhh]”(jh!)�”}”(hŒ futex_vector”h]”jn!)�”}”(hŒstruct futex_vector”h]”(jI$)�”}”(hjL$h]”hŒstruct”…”�”}”(hjÑTh²hh³Nh´Nubah}”(h]”h ]”jU$ah"]”h$]”h&]”uh1jH$hjÍTh²hh³Œ]/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1358: ./kernel/futex/futex.h”h´MJubj$)�”}”(hŒ ”h]”hŒ ”…”�”}”(hjßTh²hh³Nh´Nubah}”(h]”h ]”j $ah"]”h$]”h&]”uh1j$hjÍTh²hh³jÞTh´MJubjt!)�”}”(hŒ futex_vector”h]”jz!)�”}”(hjËTh]”hŒ futex_vector”…”�”}”(hjñTh²hh³Nh´Nubah}”(h]”h ]”j…!ah"]”h$]”h&]”uh1jy!hjíTubah}”(h]”h ]”(jŒ!j�!eh"]”h$]”h&]”j�jŽuh1js!hjÍTh²hh³jÞTh´MJubeh}”(h]”h ]”h"]”h$]”h&]”j�jŽj˜!ˆuh1jm!j™!jš!hjÉTh²hh³jÞTh´MJubah}”(h]”jÄTah ]”(jž!jŸ!eh"]”h$]”h&]”j£!ˆj¤!)j¥!huh1jg!h³jÞTh´MJhjÆTh²hubj§!)�”}”(hhh]”hú)�”}”(hŒ"Auxiliary struct for futex_waitv()”h]”hŒ"Auxiliary struct for futex_waitv()”…”�”}”(hjUh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³Œ]/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1358: ./kernel/futex/futex.h”h´M½hjUh²hubah}”(h]”h ]”h"]”h$]”h&]”uh1j¦!hjÆTh²hh³jÞTh´MJubeh}”(h]”h ]”(jUŒstruct”eh"]”h$]”h&]”j¸!jUj¹!j+Ujº!j+Uj»!‰j¼!‰j½!‰uh1jb!h²hhj6h³j‰Kh´Nubjò!)�”}”(hŒª**Definition**:: struct futex_vector { struct futex_waitv w; struct futex_q q; }; **Members** ``w`` Userspace provided data ``q`` Kernel side data”h]”(hú)�”}”(hŒ**Definition**::”h]”(j)�”}”(hŒ**Definition**”h]”hŒ Definition”…”�”}”(hj7Uh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhj3UubhŒ:”…”�”}”(hj3Uh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hùh³Œ]/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1358: ./kernel/futex/futex.h”h´MÁhj/Uubj~)�”}”(hŒHstruct futex_vector { struct futex_waitv w; struct futex_q q; };”h]”hŒHstruct futex_vector { struct futex_waitv w; struct futex_q q; };”…”�”}”hjPUsbah}”(h]”h ]”h"]”h$]”h&]”j�jŽuh1j}h³Œ]/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1358: ./kernel/futex/futex.h”h´MÃhj/Uubhú)�”}”(hŒ **Members**”h]”j)�”}”(hjaUh]”hŒMembers”…”�”}”(hjcUh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhj_Uubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³Œ]/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1358: ./kernel/futex/futex.h”h´MÈhj/Uubj")�”}”(hhh]”(j")�”}”(hŒ``w`` Userspace provided data ”h]”(j")�”}”(hŒ``w``”h]”jI)�”}”(hj€Uh]”hŒw”…”�”}”(hj‚Uh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jHhj~Uubah}”(h]”h ]”h"]”h$]”h&]”uh1j"h³Œ]/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1358: ./kernel/futex/futex.h”h´M¿hjzUubj5")�”}”(hhh]”hú)�”}”(hŒUserspace provided data”h]”hŒUserspace provided data”…”�”}”(hj™Uh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³j•Uh´M¿hj–Uubah}”(h]”h ]”h"]”h$]”h&]”uh1j4"hjzUubeh}”(h]”h ]”h"]”h$]”h&]”uh1j"h³j•Uh´M¿hjwUubj")�”}”(hŒ``q`` Kernel side data”h]”(j")�”}”(hŒ``q``”h]”jI)�”}”(hj¹Uh]”hŒq”…”�”}”(hj»Uh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jHhj·Uubah}”(h]”h ]”h"]”h$]”h&]”uh1j"h³Œ]/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1358: ./kernel/futex/futex.h”h´M¿hj³Uubj5")�”}”(hhh]”hú)�”}”(hŒKernel side data”h]”hŒKernel side data”…”�”}”(hjÒUh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³Œ]/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1358: ./kernel/futex/futex.h”h´MÀhjÏUubah}”(h]”h ]”h"]”h$]”h&]”uh1j4"hj³Uubeh}”(h]”h ]”h"]”h$]”h&]”uh1j"h³jÎUh´M¿hjwUubeh}”(h]”h ]”h"]”h$]”h&]”uh1j"hj/Uubeh}”(h]”h ]”Œ kernelindent”ah"]”h$]”h&]”uh1jñ!hj6h²hh³j‰Kh´Nubhú)�”}”(hŒ**Description**”h]”j)�”}”(hjüUh]”hŒ Description”…”�”}”(hjþUh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhjúUubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³Œ]/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1358: ./kernel/futex/futex.h”h´MÃhj6h²hubhú)�”}”(hŒBStruct used to build an array with all data need for futex_waitv()”h]”hŒBStruct used to build an array with all data need for futex_waitv()”…”�”}”(hjVh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³Œ]/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1358: ./kernel/futex/futex.h”h´MÀhj6h²hubjR!)�”}”(hhh]”h}”(h]”h ]”h"]”h$]”h&]”Œentries”]”(j^!Œ!futex_lock_pi_atomic (C function)”Œc.futex_lock_pi_atomic”hNt”auh1jQ!hj6h²hh³Nh´Nubjc!)�”}”(hhh]”(jh!)�”}”(hŒÅint futex_lock_pi_atomic (u32 __user *uaddr, struct futex_hash_bucket *hb, union futex_key *key, struct futex_pi_state **ps, struct task_struct *task, struct task_struct **exiting, int set_waiters)”h]”jn!)�”}”(hŒÄint futex_lock_pi_atomic(u32 __user *uaddr, struct futex_hash_bucket *hb, union futex_key *key, struct futex_pi_state **ps, struct task_struct *task, struct task_struct **exiting, int set_waiters)”h]”(j$)�”}”(hŒint”h]”hŒint”…”�”}”(hj:Vh²hh³Nh´Nubah}”(h]”h ]”j$ah"]”h$]”h&]”uh1j$hj6Vh²hh³ŒZ/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1361: ./kernel/futex/pi.c”h´M.ubj$)�”}”(hŒ ”h]”hŒ ”…”�”}”(hjIVh²hh³Nh´Nubah}”(h]”h ]”j $ah"]”h$]”h&]”uh1j$hj6Vh²hh³jHVh´M.ubjt!)�”}”(hŒfutex_lock_pi_atomic”h]”jz!)�”}”(hŒfutex_lock_pi_atomic”h]”hŒfutex_lock_pi_atomic”…”�”}”(hj[Vh²hh³Nh´Nubah}”(h]”h ]”j…!ah"]”h$]”h&]”uh1jy!hjWVubah}”(h]”h ]”(jŒ!j�!eh"]”h$]”h&]”j�jŽuh1js!hj6Vh²hh³jHVh´M.ubj=$)�”}”(hŒ¬(u32 __user *uaddr, struct futex_hash_bucket *hb, union futex_key *key, struct futex_pi_state **ps, struct task_struct *task, struct task_struct **exiting, int set_waiters)”h]”(jC$)�”}”(hŒu32 __user *uaddr”h]”(h)�”}”(hhh]”jz!)�”}”(hŒu32”h]”hŒu32”…”�”}”(hjzVh²hh³Nh´Nubah}”(h]”h ]”j…!ah"]”h$]”h&]”uh1jy!hjwVubah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”jUŒreftype”j€$Œ reftarget”j|VŒmodname”NŒ classname”Nj„$j‡$)�”}”jŠ$]”j�$)�”}”j€$j]VsbŒc.futex_lock_pi_atomic”†”asbuh1hhjsVubj$)�”}”(hŒ ”h]”hŒ ”…”�”}”(hjšVh²hh³Nh´Nubah}”(h]”h ]”j $ah"]”h$]”h&]”uh1j$hjsVubhŒ__user”…”�”}”(hjsVh²hh³Nh´Nubj$)�”}”(hŒ ”h]”hŒ ”…”�”}”(hj¬Vh²hh³Nh´Nubah}”(h]”h ]”j $ah"]”h$]”h&]”uh1j$hjsVubj¡$)�”}”(hj¤$h]”hŒ*”…”�”}”(hjºVh²hh³Nh´Nubah}”(h]”h ]”j­$ah"]”h$]”h&]”uh1j $hjsVubjz!)�”}”(hŒuaddr”h]”hŒuaddr”…”�”}”(hjÇVh²hh³Nh´Nubah}”(h]”h ]”j…!ah"]”h$]”h&]”uh1jy!hjsVubeh}”(h]”h ]”h"]”h$]”h&]”Œnoemph”ˆj�jŽuh1jB$hjoVubjC$)�”}”(hŒstruct futex_hash_bucket *hb”h]”(jI$)�”}”(hjL$h]”hŒstruct”…”�”}”(hjàVh²hh³Nh´Nubah}”(h]”h ]”jU$ah"]”h$]”h&]”uh1jH$hjÜVubj$)�”}”(hŒ ”h]”hŒ ”…”�”}”(hjíVh²hh³Nh´Nubah}”(h]”h ]”j $ah"]”h$]”h&]”uh1j$hjÜVubh)�”}”(hhh]”jz!)�”}”(hŒfutex_hash_bucket”h]”hŒfutex_hash_bucket”…”�”}”(hjþVh²hh³Nh´Nubah}”(h]”h ]”j…!ah"]”h$]”h&]”uh1jy!hjûVubah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”jUŒreftype”j€$Œ reftarget”jWŒmodname”NŒ classname”Nj„$j‡$)�”}”jŠ$]”j–VŒc.futex_lock_pi_atomic”†”asbuh1hhjÜVubj$)�”}”(hŒ ”h]”hŒ ”…”�”}”(hjWh²hh³Nh´Nubah}”(h]”h ]”j $ah"]”h$]”h&]”uh1j$hjÜVubj¡$)�”}”(hj¤$h]”hŒ*”…”�”}”(hj*Wh²hh³Nh´Nubah}”(h]”h ]”j­$ah"]”h$]”h&]”uh1j $hjÜVubjz!)�”}”(hŒhb”h]”hŒhb”…”�”}”(hj7Wh²hh³Nh´Nubah}”(h]”h ]”j…!ah"]”h$]”h&]”uh1jy!hjÜVubeh}”(h]”h ]”h"]”h$]”h&]”Œnoemph”ˆj�jŽuh1jB$hjoVubjC$)�”}”(hŒunion futex_key *key”h]”(jI$)�”}”(hj§6h]”hŒunion”…”�”}”(hjPWh²hh³Nh´Nubah}”(h]”h ]”jU$ah"]”h$]”h&]”uh1jH$hjLWubj$)�”}”(hŒ ”h]”hŒ ”…”�”}”(hj]Wh²hh³Nh´Nubah}”(h]”h ]”j $ah"]”h$]”h&]”uh1j$hjLWubh)�”}”(hhh]”jz!)�”}”(hŒ futex_key”h]”hŒ futex_key”…”�”}”(hjnWh²hh³Nh´Nubah}”(h]”h ]”j…!ah"]”h$]”h&]”uh1jy!hjkWubah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”jUŒreftype”j€$Œ reftarget”jpWŒmodname”NŒ classname”Nj„$j‡$)�”}”jŠ$]”j–VŒc.futex_lock_pi_atomic”†”asbuh1hhjLWubj$)�”}”(hŒ ”h]”hŒ ”…”�”}”(hjŒWh²hh³Nh´Nubah}”(h]”h ]”j $ah"]”h$]”h&]”uh1j$hjLWubj¡$)�”}”(hj¤$h]”hŒ*”…”�”}”(hjšWh²hh³Nh´Nubah}”(h]”h ]”j­$ah"]”h$]”h&]”uh1j $hjLWubjz!)�”}”(hŒkey”h]”hŒkey”…”�”}”(hj§Wh²hh³Nh´Nubah}”(h]”h ]”j…!ah"]”h$]”h&]”uh1jy!hjLWubeh}”(h]”h ]”h"]”h$]”h&]”Œnoemph”ˆj�jŽuh1jB$hjoVubjC$)�”}”(hŒstruct futex_pi_state **ps”h]”(jI$)�”}”(hjL$h]”hŒstruct”…”�”}”(hjÀWh²hh³Nh´Nubah}”(h]”h ]”jU$ah"]”h$]”h&]”uh1jH$hj¼Wubj$)�”}”(hŒ ”h]”hŒ ”…”�”}”(hjÍWh²hh³Nh´Nubah}”(h]”h ]”j $ah"]”h$]”h&]”uh1j$hj¼Wubh)�”}”(hhh]”jz!)�”}”(hŒfutex_pi_state”h]”hŒfutex_pi_state”…”�”}”(hjÞWh²hh³Nh´Nubah}”(h]”h ]”j…!ah"]”h$]”h&]”uh1jy!hjÛWubah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”jUŒreftype”j€$Œ reftarget”jàWŒmodname”NŒ classname”Nj„$j‡$)�”}”jŠ$]”j–VŒc.futex_lock_pi_atomic”†”asbuh1hhj¼Wubj$)�”}”(hŒ ”h]”hŒ ”…”�”}”(hjüWh²hh³Nh´Nubah}”(h]”h ]”j $ah"]”h$]”h&]”uh1j$hj¼Wubj¡$)�”}”(hj¤$h]”hŒ*”…”�”}”(hj Xh²hh³Nh´Nubah}”(h]”h ]”j­$ah"]”h$]”h&]”uh1j $hj¼Wubj¡$)�”}”(hj¤$h]”hŒ*”…”�”}”(hjXh²hh³Nh´Nubah}”(h]”h ]”j­$ah"]”h$]”h&]”uh1j $hj¼Wubjz!)�”}”(hŒps”h]”hŒps”…”�”}”(hj$Xh²hh³Nh´Nubah}”(h]”h ]”j…!ah"]”h$]”h&]”uh1jy!hj¼Wubeh}”(h]”h ]”h"]”h$]”h&]”Œnoemph”ˆj�jŽuh1jB$hjoVubjC$)�”}”(hŒstruct task_struct *task”h]”(jI$)�”}”(hjL$h]”hŒstruct”…”�”}”(hj=Xh²hh³Nh´Nubah}”(h]”h ]”jU$ah"]”h$]”h&]”uh1jH$hj9Xubj$)�”}”(hŒ ”h]”hŒ ”…”�”}”(hjJXh²hh³Nh´Nubah}”(h]”h ]”j $ah"]”h$]”h&]”uh1j$hj9Xubh)�”}”(hhh]”jz!)�”}”(hŒ task_struct”h]”hŒ task_struct”…”�”}”(hj[Xh²hh³Nh´Nubah}”(h]”h ]”j…!ah"]”h$]”h&]”uh1jy!hjXXubah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”jUŒreftype”j€$Œ reftarget”j]XŒmodname”NŒ classname”Nj„$j‡$)�”}”jŠ$]”j–VŒc.futex_lock_pi_atomic”†”asbuh1hhj9Xubj$)�”}”(hŒ ”h]”hŒ ”…”�”}”(hjyXh²hh³Nh´Nubah}”(h]”h ]”j $ah"]”h$]”h&]”uh1j$hj9Xubj¡$)�”}”(hj¤$h]”hŒ*”…”�”}”(hj‡Xh²hh³Nh´Nubah}”(h]”h ]”j­$ah"]”h$]”h&]”uh1j $hj9Xubjz!)�”}”(hŒtask”h]”hŒtask”…”�”}”(hj”Xh²hh³Nh´Nubah}”(h]”h ]”j…!ah"]”h$]”h&]”uh1jy!hj9Xubeh}”(h]”h ]”h"]”h$]”h&]”Œnoemph”ˆj�jŽuh1jB$hjoVubjC$)�”}”(hŒstruct task_struct **exiting”h]”(jI$)�”}”(hjL$h]”hŒstruct”…”�”}”(hj­Xh²hh³Nh´Nubah}”(h]”h ]”jU$ah"]”h$]”h&]”uh1jH$hj©Xubj$)�”}”(hŒ ”h]”hŒ ”…”�”}”(hjºXh²hh³Nh´Nubah}”(h]”h ]”j $ah"]”h$]”h&]”uh1j$hj©Xubh)�”}”(hhh]”jz!)�”}”(hŒ task_struct”h]”hŒ task_struct”…”�”}”(hjËXh²hh³Nh´Nubah}”(h]”h ]”j…!ah"]”h$]”h&]”uh1jy!hjÈXubah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”jUŒreftype”j€$Œ reftarget”jÍXŒmodname”NŒ classname”Nj„$j‡$)�”}”jŠ$]”j–VŒc.futex_lock_pi_atomic”†”asbuh1hhj©Xubj$)�”}”(hŒ ”h]”hŒ ”…”�”}”(hjéXh²hh³Nh´Nubah}”(h]”h ]”j $ah"]”h$]”h&]”uh1j$hj©Xubj¡$)�”}”(hj¤$h]”hŒ*”…”�”}”(hj÷Xh²hh³Nh´Nubah}”(h]”h ]”j­$ah"]”h$]”h&]”uh1j $hj©Xubj¡$)�”}”(hj¤$h]”hŒ*”…”�”}”(hjYh²hh³Nh´Nubah}”(h]”h ]”j­$ah"]”h$]”h&]”uh1j $hj©Xubjz!)�”}”(hŒexiting”h]”hŒexiting”…”�”}”(hjYh²hh³Nh´Nubah}”(h]”h ]”j…!ah"]”h$]”h&]”uh1jy!hj©Xubeh}”(h]”h ]”h"]”h$]”h&]”Œnoemph”ˆj�jŽuh1jB$hjoVubjC$)�”}”(hŒint set_waiters”h]”(j$)�”}”(hŒint”h]”hŒint”…”�”}”(hj*Yh²hh³Nh´Nubah}”(h]”h ]”j$ah"]”h$]”h&]”uh1j$hj&Yubj$)�”}”(hŒ ”h]”hŒ ”…”�”}”(hj8Yh²hh³Nh´Nubah}”(h]”h ]”j $ah"]”h$]”h&]”uh1j$hj&Yubjz!)�”}”(hŒ set_waiters”h]”hŒ set_waiters”…”�”}”(hjFYh²hh³Nh´Nubah}”(h]”h ]”j…!ah"]”h$]”h&]”uh1jy!hj&Yubeh}”(h]”h ]”h"]”h$]”h&]”Œnoemph”ˆj�jŽuh1jB$hjoVubeh}”(h]”h ]”h"]”h$]”h&]”j�jŽuh1j<$hj6Vh²hh³jHVh´M.ubeh}”(h]”h ]”h"]”h$]”h&]”j�jŽj˜!ˆuh1jm!j™!jš!hj2Vh²hh³jHVh´M.ubah}”(h]”j-Vah ]”(jž!jŸ!eh"]”h$]”h&]”j£!ˆj¤!)j¥!huh1jg!h³jHVh´M.hj/Vh²hubj§!)�”}”(hhh]”hú)�”}”(hŒ0Atomic work required to acquire a pi aware futex”h]”hŒ0Atomic work required to acquire a pi aware futex”…”�”}”(hjpYh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³ŒZ/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1361: ./kernel/futex/pi.c”h´M.hjmYh²hubah}”(h]”h ]”h"]”h$]”h&]”uh1j¦!hj/Vh²hh³jHVh´M.ubeh}”(h]”h ]”(jUŒfunction”eh"]”h$]”h&]”j¸!jUj¹!jˆYjº!jˆYj»!‰j¼!‰j½!‰uh1jb!h²hhj6h³Nh´Nubjò!)�”}”(hX¸**Parameters** ``u32 __user *uaddr`` the pi futex user address ``struct futex_hash_bucket *hb`` the pi futex hash bucket ``union futex_key *key`` the futex key associated with uaddr and hb ``struct futex_pi_state **ps`` the pi_state pointer where we store the result of the lookup ``struct task_struct *task`` the task to perform the atomic lock work for. This will be "current" except in the case of requeue pi. ``struct task_struct **exiting`` Pointer to store the task pointer of the owner task which is in the middle of exiting ``int set_waiters`` force setting the FUTEX_WAITERS bit (1) or not (0) **Return** - 0 - ready to wait; - 1 - acquired the lock; - <0 - error **Description** The hb->lock must be held by the caller. **exiting** is only set when the return value is -EBUSY. If so, this holds a refcount on the exiting task on return and the caller needs to drop it after waiting for the exit to complete.”h]”(hú)�”}”(hŒ**Parameters**”h]”j)�”}”(hj’Yh]”hŒ Parameters”…”�”}”(hj”Yh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhj�Yubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³ŒZ/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1361: ./kernel/futex/pi.c”•'h´M2hjŒYubj")�”}”(hhh]”(j")�”}”(hŒ0``u32 __user *uaddr`` the pi futex user address ”h]”(j")�”}”(hŒ``u32 __user *uaddr``”h]”jI)�”}”(hj±Yh]”hŒu32 __user *uaddr”…”�”}”(hj³Yh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jHhj¯Yubah}”(h]”h ]”h"]”h$]”h&]”uh1j"h³ŒZ/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1361: ./kernel/futex/pi.c”h´M/hj«Yubj5")�”}”(hhh]”hú)�”}”(hŒthe pi futex user address”h]”hŒthe pi futex user address”…”�”}”(hjÊYh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³jÆYh´M/hjÇYubah}”(h]”h ]”h"]”h$]”h&]”uh1j4"hj«Yubeh}”(h]”h ]”h"]”h$]”h&]”uh1j"h³jÆYh´M/hj¨Yubj")�”}”(hŒ:``struct futex_hash_bucket *hb`` the pi futex hash bucket ”h]”(j")�”}”(hŒ ``struct futex_hash_bucket *hb``”h]”jI)�”}”(hjêYh]”hŒstruct futex_hash_bucket *hb”…”�”}”(hjìYh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jHhjèYubah}”(h]”h ]”h"]”h$]”h&]”uh1j"h³ŒZ/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1361: ./kernel/futex/pi.c”h´M0hjäYubj5")�”}”(hhh]”hú)�”}”(hŒthe pi futex hash bucket”h]”hŒthe pi futex hash bucket”…”�”}”(hjZh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³jÿYh´M0hjZubah}”(h]”h ]”h"]”h$]”h&]”uh1j4"hjäYubeh}”(h]”h ]”h"]”h$]”h&]”uh1j"h³jÿYh´M0hj¨Yubj")�”}”(hŒD``union futex_key *key`` the futex key associated with uaddr and hb ”h]”(j")�”}”(hŒ``union futex_key *key``”h]”jI)�”}”(hj#Zh]”hŒunion futex_key *key”…”�”}”(hj%Zh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jHhj!Zubah}”(h]”h ]”h"]”h$]”h&]”uh1j"h³ŒZ/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1361: ./kernel/futex/pi.c”h´M1hjZubj5")�”}”(hhh]”hú)�”}”(hŒ*the futex key associated with uaddr and hb”h]”hŒ*the futex key associated with uaddr and hb”…”�”}”(hjhjŒYubhú)�”}”(hŒ(The hb->lock must be held by the caller.”h]”hŒ(The hb->lock must be held by the caller.”…”�”}”(hjÅ[h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³ŒZ/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1361: ./kernel/futex/pi.c”h´M>hjŒYubhú)�”}”(hŒ»**exiting** is only set when the return value is -EBUSY. If so, this holds a refcount on the exiting task on return and the caller needs to drop it after waiting for the exit to complete.”h]”(j)�”}”(hŒ **exiting**”h]”hŒexiting”…”�”}”(hjØ[h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhjÔ[ubhŒ° is only set when the return value is -EBUSY. If so, this holds a refcount on the exiting task on return and the caller needs to drop it after waiting for the exit to complete.”…”�”}”(hjÔ[h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hùh³ŒZ/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1361: ./kernel/futex/pi.c”h´M@hjŒYubeh}”(h]”h ]”Œ kernelindent”ah"]”h$]”h&]”uh1jñ!hj6h²hh³Nh´NubjR!)�”}”(hhh]”h}”(h]”h ]”h"]”h$]”h&]”Œentries”]”(j^!Œfixup_pi_owner (C function)”Œc.fixup_pi_owner”hNt”auh1jQ!hj6h²hh³Nh´Nubjc!)�”}”(hhh]”(jh!)�”}”(hŒEint fixup_pi_owner (u32 __user *uaddr, struct futex_q *q, int locked)”h]”jn!)�”}”(hŒDint fixup_pi_owner(u32 __user *uaddr, struct futex_q *q, int locked)”h]”(j$)�”}”(hŒint”h]”hŒint”…”�”}”(hj\h²hh³Nh´Nubah}”(h]”h ]”j$ah"]”h$]”h&]”uh1j$hj \h²hh³ŒZ/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1361: ./kernel/futex/pi.c”h´M ubj$)�”}”(hŒ ”h]”hŒ ”…”�”}”(hj \h²hh³Nh´Nubah}”(h]”h ]”j $ah"]”h$]”h&]”uh1j$hj \h²hh³j\h´M ubjt!)�”}”(hŒfixup_pi_owner”h]”jz!)�”}”(hŒfixup_pi_owner”h]”hŒfixup_pi_owner”…”�”}”(hj2\h²hh³Nh´Nubah}”(h]”h ]”j…!ah"]”h$]”h&]”uh1jy!hj.\ubah}”(h]”h ]”(jŒ!j�!eh"]”h$]”h&]”j�jŽuh1js!hj \h²hh³j\h´M ubj=$)�”}”(hŒ2(u32 __user *uaddr, struct futex_q *q, int locked)”h]”(jC$)�”}”(hŒu32 __user *uaddr”h]”(h)�”}”(hhh]”jz!)�”}”(hŒu32”h]”hŒu32”…”�”}”(hjQ\h²hh³Nh´Nubah}”(h]”h ]”j…!ah"]”h$]”h&]”uh1jy!hjN\ubah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”jUŒreftype”j€$Œ reftarget”jS\Œmodname”NŒ classname”Nj„$j‡$)�”}”jŠ$]”j�$)�”}”j€$j4\sbŒc.fixup_pi_owner”†”asbuh1hhjJ\ubj$)�”}”(hŒ ”h]”hŒ ”…”�”}”(hjq\h²hh³Nh´Nubah}”(h]”h ]”j $ah"]”h$]”h&]”uh1j$hjJ\ubhŒ__user”…”�”}”(hjJ\h²hh³Nh´Nubj$)�”}”(hŒ ”h]”hŒ ”…”�”}”(hjƒ\h²hh³Nh´Nubah}”(h]”h ]”j $ah"]”h$]”h&]”uh1j$hjJ\ubj¡$)�”}”(hj¤$h]”hŒ*”…”�”}”(hj‘\h²hh³Nh´Nubah}”(h]”h ]”j­$ah"]”h$]”h&]”uh1j $hjJ\ubjz!)�”}”(hŒuaddr”h]”hŒuaddr”…”�”}”(hjž\h²hh³Nh´Nubah}”(h]”h ]”j…!ah"]”h$]”h&]”uh1jy!hjJ\ubeh}”(h]”h ]”h"]”h$]”h&]”Œnoemph”ˆj�jŽuh1jB$hjF\ubjC$)�”}”(hŒstruct futex_q *q”h]”(jI$)�”}”(hjL$h]”hŒstruct”…”�”}”(hj·\h²hh³Nh´Nubah}”(h]”h ]”jU$ah"]”h$]”h&]”uh1jH$hj³\ubj$)�”}”(hŒ ”h]”hŒ ”…”�”}”(hjÄ\h²hh³Nh´Nubah}”(h]”h ]”j $ah"]”h$]”h&]”uh1j$hj³\ubh)�”}”(hhh]”jz!)�”}”(hŒfutex_q”h]”hŒfutex_q”…”�”}”(hjÕ\h²hh³Nh´Nubah}”(h]”h ]”j…!ah"]”h$]”h&]”uh1jy!hjÒ\ubah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”jUŒreftype”j€$Œ reftarget”j×\Œmodname”NŒ classname”Nj„$j‡$)�”}”jŠ$]”jm\Œc.fixup_pi_owner”†”asbuh1hhj³\ubj$)�”}”(hŒ ”h]”hŒ ”…”�”}”(hjó\h²hh³Nh´Nubah}”(h]”h ]”j $ah"]”h$]”h&]”uh1j$hj³\ubj¡$)�”}”(hj¤$h]”hŒ*”…”�”}”(hj]h²hh³Nh´Nubah}”(h]”h ]”j­$ah"]”h$]”h&]”uh1j $hj³\ubjz!)�”}”(hj;Gh]”hŒq”…”�”}”(hj]h²hh³Nh´Nubah}”(h]”h ]”j…!ah"]”h$]”h&]”uh1jy!hj³\ubeh}”(h]”h ]”h"]”h$]”h&]”Œnoemph”ˆj�jŽuh1jB$hjF\ubjC$)�”}”(hŒ int locked”h]”(j$)�”}”(hŒint”h]”hŒint”…”�”}”(hj&]h²hh³Nh´Nubah}”(h]”h ]”j$ah"]”h$]”h&]”uh1j$hj"]ubj$)�”}”(hŒ ”h]”hŒ ”…”�”}”(hj4]h²hh³Nh´Nubah}”(h]”h ]”j $ah"]”h$]”h&]”uh1j$hj"]ubjz!)�”}”(hŒlocked”h]”hŒlocked”…”�”}”(hjB]h²hh³Nh´Nubah}”(h]”h ]”j…!ah"]”h$]”h&]”uh1jy!hj"]ubeh}”(h]”h ]”h"]”h$]”h&]”Œnoemph”ˆj�jŽuh1jB$hjF\ubeh}”(h]”h ]”h"]”h$]”h&]”j�jŽuh1j<$hj \h²hh³j\h´M ubeh}”(h]”h ]”h"]”h$]”h&]”j�jŽj˜!ˆuh1jm!j™!jš!hj \h²hh³j\h´M ubah}”(h]”j\ah ]”(jž!jŸ!eh"]”h$]”h&]”j£!ˆj¤!)j¥!huh1jg!h³j\h´M hj\h²hubj§!)�”}”(hhh]”hú)�”}”(hŒ-Post lock pi_state and corner case management”h]”hŒ-Post lock pi_state and corner case management”…”�”}”(hjl]h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³ŒZ/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1361: ./kernel/futex/pi.c”h´M hji]h²hubah}”(h]”h ]”h"]”h$]”h&]”uh1j¦!hj\h²hh³j\h´M ubeh}”(h]”h ]”(jUŒfunction”eh"]”h$]”h&]”j¸!jUj¹!j„]jº!j„]j»!‰j¼!‰j½!‰uh1jb!h²hhj6h³Nh´Nubjò!)�”}”(hX **Parameters** ``u32 __user *uaddr`` user address of the futex ``struct futex_q *q`` futex_q (contains pi_state and access to the rt_mutex) ``int locked`` if the attempt to take the rt_mutex succeeded (1) or not (0) **Description** After attempting to lock an rt_mutex, this function is called to cleanup the pi_state owner as well as handle race conditions that may allow us to acquire the lock. Must be called with the hb lock held. **Return** - 1 - success, lock taken; - 0 - success, lock not taken; - <0 - on error (-EFAULT)”h]”(hú)�”}”(hŒ**Parameters**”h]”j)�”}”(hjŽ]h]”hŒ Parameters”…”�”}”(hj�]h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhjŒ]ubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³ŒZ/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1361: ./kernel/futex/pi.c”h´M¤hjˆ]ubj")�”}”(hhh]”(j")�”}”(hŒ0``u32 __user *uaddr`` user address of the futex ”h]”(j")�”}”(hŒ``u32 __user *uaddr``”h]”jI)�”}”(hj­]h]”hŒu32 __user *uaddr”…”�”}”(hj¯]h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jHhj«]ubah}”(h]”h ]”h"]”h$]”h&]”uh1j"h³ŒZ/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1361: ./kernel/futex/pi.c”h´M¡hj§]ubj5")�”}”(hhh]”hú)�”}”(hŒuser address of the futex”h]”hŒuser address of the futex”…”�”}”(hjÆ]h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³jÂ]h´M¡hjÃ]ubah}”(h]”h ]”h"]”h$]”h&]”uh1j4"hj§]ubeh}”(h]”h ]”h"]”h$]”h&]”uh1j"h³jÂ]h´M¡hj¤]ubj")�”}”(hŒM``struct futex_q *q`` futex_q (contains pi_state and access to the rt_mutex) ”h]”(j")�”}”(hŒ``struct futex_q *q``”h]”jI)�”}”(hjæ]h]”hŒstruct futex_q *q”…”�”}”(hjè]h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jHhjä]ubah}”(h]”h ]”h"]”h$]”h&]”uh1j"h³ŒZ/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1361: ./kernel/futex/pi.c”h´M¢hjà]ubj5")�”}”(hhh]”hú)�”}”(hŒ6futex_q (contains pi_state and access to the rt_mutex)”h]”hŒ6futex_q (contains pi_state and access to the rt_mutex)”…”�”}”(hjÿ]h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³jû]h´M¢hjü]ubah}”(h]”h ]”h"]”h$]”h&]”uh1j4"hjà]ubeh}”(h]”h ]”h"]”h$]”h&]”uh1j"h³jû]h´M¢hj¤]ubj")�”}”(hŒL``int locked`` if the attempt to take the rt_mutex succeeded (1) or not (0) ”h]”(j")�”}”(hŒ``int locked``”h]”jI)�”}”(hj^h]”hŒ int locked”…”�”}”(hj!^h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jHhj^ubah}”(h]”h ]”h"]”h$]”h&]”uh1j"h³ŒZ/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1361: ./kernel/futex/pi.c”h´M£hj^ubj5")�”}”(hhh]”hú)�”}”(hŒ``union futex_key *key2`` the new key for the requeued futex_q”h]”(j")�”}”(hŒ``union futex_key *key2``”h]”jI)�”}”(hjbh]”hŒunion futex_key *key2”…”�”}”(hjbh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jHhjbubah}”(h]”h ]”h"]”h$]”h&]”uh1j"h³Œ_/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1364: ./kernel/futex/requeue.c”h´KJhjýaubj5")�”}”(hhh]”hú)�”}”(hŒ$the new key for the requeued futex_q”h]”hŒ$the new key for the requeued futex_q”…”�”}”(hjbh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³Œ_/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1364: ./kernel/futex/requeue.c”h´KIhjbubah}”(h]”h ]”h"]”h$]”h&]”uh1j4"hjýaubeh}”(h]”h ]”h"]”h$]”h&]”uh1j"h³jbh´KJhjOaubeh}”(h]”h ]”h"]”h$]”h&]”uh1j"hj3aubeh}”(h]”h ]”Œ kernelindent”ah"]”h$]”h&]”uh1jñ!hj6h²hh³Nh´NubjR!)�”}”(hhh]”h}”(h]”h ]”h"]”h$]”h&]”Œentries”]”(j^!Œ"requeue_pi_wake_futex (C function)”Œc.requeue_pi_wake_futex”hNt”auh1jQ!hj6h²hh³Nh´Nubjc!)�”}”(hhh]”(jh!)�”}”(hŒbvoid requeue_pi_wake_futex (struct futex_q *q, union futex_key *key, struct futex_hash_bucket *hb)”h]”jn!)�”}”(hŒavoid requeue_pi_wake_futex(struct futex_q *q, union futex_key *key, struct futex_hash_bucket *hb)”h]”(j$)�”}”(hŒvoid”h]”hŒvoid”…”�”}”(hj]bh²hh³Nh´Nubah}”(h]”h ]”j$ah"]”h$]”h&]”uh1j$hjYbh²hh³Œ_/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1364: ./kernel/futex/requeue.c”h´KÒubj$)�”}”(hŒ ”h]”hŒ ”…”�”}”(hjlbh²hh³Nh´Nubah}”(h]”h ]”j $ah"]”h$]”h&]”uh1j$hjYbh²hh³jkbh´KÒubjt!)�”}”(hŒrequeue_pi_wake_futex”h]”jz!)�”}”(hŒrequeue_pi_wake_futex”h]”hŒrequeue_pi_wake_futex”…”�”}”(hj~bh²hh³Nh´Nubah}”(h]”h ]”j…!ah"]”h$]”h&]”uh1jy!hjzbubah}”(h]”h ]”(jŒ!j�!eh"]”h$]”h&]”j�jŽuh1js!hjYbh²hh³jkbh´KÒubj=$)�”}”(hŒG(struct futex_q *q, union futex_key *key, struct futex_hash_bucket *hb)”h]”(jC$)�”}”(hŒstruct futex_q *q”h]”(jI$)�”}”(hjL$h]”hŒstruct”…”�”}”(hjšbh²hh³Nh´Nubah}”(h]”h ]”jU$ah"]”h$]”h&]”uh1jH$hj–bubj$)�”}”(hŒ ”h]”hŒ ”…”�”}”(hj§bh²hh³Nh´Nubah}”(h]”h ]”j $ah"]”h$]”h&]”uh1j$hj–bubh)�”}”(hhh]”jz!)�”}”(hŒfutex_q”h]”hŒfutex_q”…”�”}”(hj¸bh²hh³Nh´Nubah}”(h]”h ]”j…!ah"]”h$]”h&]”uh1jy!hjµbubah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”jUŒreftype”j€$Œ reftarget”jºbŒmodname”NŒ classname”Nj„$j‡$)�”}”jŠ$]”j�$)�”}”j€$j€bsbŒc.requeue_pi_wake_futex”†”asbuh1hhj–bubj$)�”}”(hŒ ”h]”hŒ ”…”�”}”(hjØbh²hh³Nh´Nubah}”(h]”h ]”j $ah"]”h$]”h&]”uh1j$hj–bubj¡$)�”}”(hj¤$h]”hŒ*”…”�”}”(hjæbh²hh³Nh´Nubah}”(h]”h ]”j­$ah"]”h$]”h&]”uh1j $hj–bubjz!)�”}”(hj;Gh]”hŒq”…”�”}”(hjóbh²hh³Nh´Nubah}”(h]”h ]”j…!ah"]”h$]”h&]”uh1jy!hj–bubeh}”(h]”h ]”h"]”h$]”h&]”Œnoemph”ˆj�jŽuh1jB$hj’bubjC$)�”}”(hŒunion futex_key *key”h]”(jI$)�”}”(hj§6h]”hŒunion”…”�”}”(hj ch²hh³Nh´Nubah}”(h]”h ]”jU$ah"]”h$]”h&]”uh1jH$hjcubj$)�”}”(hŒ ”h]”hŒ ”…”�”}”(hjch²hh³Nh´Nubah}”(h]”h ]”j $ah"]”h$]”h&]”uh1j$hjcubh)�”}”(hhh]”jz!)�”}”(hŒ futex_key”h]”hŒ futex_key”…”�”}”(hj)ch²hh³Nh´Nubah}”(h]”h ]”j…!ah"]”h$]”h&]”uh1jy!hj&cubah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”jUŒreftype”j€$Œ reftarget”j+cŒmodname”NŒ classname”Nj„$j‡$)�”}”jŠ$]”jÔbŒc.requeue_pi_wake_futex”†”asbuh1hhjcubj$)�”}”(hŒ ”h]”hŒ ”…”�”}”(hjGch²hh³Nh´Nubah}”(h]”h ]”j $ah"]”h$]”h&]”uh1j$hjcubj¡$)�”}”(hj¤$h]”hŒ*”…”�”}”(hjUch²hh³Nh´Nubah}”(h]”h ]”j­$ah"]”h$]”h&]”uh1j $hjcubjz!)�”}”(hŒkey”h]”hŒkey”…”�”}”(hjbch²hh³Nh´Nubah}”(h]”h ]”j…!ah"]”h$]”h&]”uh1jy!hjcubeh}”(h]”h ]”h"]”h$]”h&]”Œnoemph”ˆj�jŽuh1jB$hj’bubjC$)�”}”(hŒstruct futex_hash_bucket *hb”h]”(jI$)�”}”(hjL$h]”hŒstruct”…”�”}”(hj{ch²hh³Nh´Nubah}”(h]”h ]”jU$ah"]”h$]”h&]”uh1jH$hjwcubj$)�”}”(hŒ ”h]”hŒ ”…”�”}”(hjˆch²hh³Nh´Nubah}”(h]”h ]”j $ah"]”h$]”h&]”uh1j$hjwcubh)�”}”(hhh]”jz!)�”}”(hŒfutex_hash_bucket”h]”hŒfutex_hash_bucket”…”�”}”(hj™ch²hh³Nh´Nubah}”(h]”h ]”j…!ah"]”h$]”h&]”uh1jy!hj–cubah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”jUŒreftype”j€$Œ reftarget”j›cŒmodname”NŒ classname”Nj„$j‡$)�”}”jŠ$]”jÔbŒc.requeue_pi_wake_futex”†”asbuh1hhjwcubj$)�”}”(hŒ ”h]”hŒ ”…”�”}”(hj·ch²hh³Nh´Nubah}”(h]”h ]”j $ah"]”h$]”h&]”uh1j$hjwcubj¡$)�”}”(hj¤$h]”hŒ*”…”�”}”(hjÅch²hh³Nh´Nubah}”(h]”h ]”j­$ah"]”h$]”h&]”uh1j $hjwcubjz!)�”}”(hŒhb”h]”hŒhb”…”�”}”(hjÒch²hh³Nh´Nubah}”(h]”h ]”j…!ah"]”h$]”h&]”uh1jy!hjwcubeh}”(h]”h ]”h"]”h$]”h&]”Œnoemph”ˆj�jŽuh1jB$hj’bubeh}”(h]”h ]”h"]”h$]”h&]”j�jŽuh1j<$hjYbh²hh³jkbh´KÒubeh}”(h]”h ]”h"]”h$]”h&]”j�jŽj˜!ˆuh1jm!j™!jš!hjUbh²hh³jkbh´KÒubah}”(h]”jPbah ]”(jž!jŸ!eh"]”h$]”h&]”j£!ˆj¤!)j¥!huh1jg!h³jkbh´KÒhjRbh²hubj§!)�”}”(hhh]”hú)�”}”(hŒ1Wake a task that acquired the lock during requeue”h]”hŒ1Wake a task that acquired the lock during requeue”…”�”}”(hjüch²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³Œ_/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1364: ./kernel/futex/requeue.c”h´KÒhjùch²hubah}”(h]”h ]”h"]”h$]”h&]”uh1j¦!hjRbh²hh³jkbh´KÒubeh}”(h]”h ]”(jUŒfunction”eh"]”h$]”h&]”j¸!jUj¹!jdjº!jdj»!‰j¼!‰j½!‰uh1jb!h²hhj6h³Nh´Nubjò!)�”}”(hXÒ**Parameters** ``struct futex_q *q`` the futex_q ``union futex_key *key`` the key of the requeue target futex ``struct futex_hash_bucket *hb`` the hash_bucket of the requeue target futex **Description** During futex_requeue, with requeue_pi=1, it is possible to acquire the target futex if it is uncontended or via a lock steal. 1) Set **q**::key to the requeue target futex key so the waiter can detect the wakeup on the right futex. 2) Dequeue **q** from the hash bucket. 3) Set **q**::rt_waiter to NULL so the woken up task can detect atomic lock acquisition. 4) Set the q->lock_ptr to the requeue target hb->lock for the case that the waiter has to fixup the pi state. 5) Complete the requeue state so the waiter can make progress. After this point the waiter task can return from the syscall immediately in case that the pi state does not have to be fixed up. 6) Wake the waiter task. Must be called with both q->lock_ptr and hb->lock held.”h]”(hú)�”}”(hŒ**Parameters**”h]”j)�”}”(hjdh]”hŒ Parameters”…”�”}”(hj dh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhjdubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³Œ_/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1364: ./kernel/futex/requeue.c”h´KÖhjdubj")�”}”(hhh]”(j")�”}”(hŒ"``struct futex_q *q`` the futex_q ”h]”(j")�”}”(hŒ``struct futex_q *q``”h]”jI)�”}”(hj=dh]”hŒstruct futex_q *q”…”�”}”(hj?dh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jHhj;dubah}”(h]”h ]”h"]”h$]”h&]”uh1j"h³Œ_/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1364: ./kernel/futex/requeue.c”h´KÓhj7dubj5")�”}”(hhh]”hú)�”}”(hŒ the futex_q”h]”hŒ the futex_q”…”�”}”(hjVdh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³jRdh´KÓhjSdubah}”(h]”h ]”h"]”h$]”h&]”uh1j4"hj7dubeh}”(h]”h ]”h"]”h$]”h&]”uh1j"h³jRdh´KÓhj4dubj")�”}”(hŒ=``union futex_key *key`` the key of the requeue target futex ”h]”(j")�”}”(hŒ``union futex_key *key``”h]”jI)�”}”(hjvdh]”hŒunion futex_key *key”…”�”}”(hjxdh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jHhjtdubah}”(h]”h ]”h"]”h$]”h&]”uh1j"h³Œ_/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1364: ./kernel/futex/requeue.c”h´KÔhjpdubj5")�”}”(hhh]”hú)�”}”(hŒ#the key of the requeue target futex”h]”hŒ#the key of the requeue target futex”…”�”}”(hj�dh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³j‹dh´KÔhjŒdubah}”(h]”h ]”h"]”h$]”h&]”uh1j4"hjpdubeh}”(h]”h ]”h"]”h$]”h&]”uh1j"h³j‹dh´KÔhj4dubj")�”}”(hŒM``struct futex_hash_bucket *hb`` the hash_bucket of the requeue target futex ”h]”(j")�”}”(hŒ ``struct futex_hash_bucket *hb``”h]”jI)�”}”(hj¯dh]”hŒstruct futex_hash_bucket *hb”…”�”}”(hj±dh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jHhj­dubah}”(h]”h ]”h"]”h$]”h&]”uh1j"h³Œ_/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1364: ./kernel/futex/requeue.c”h´KÕhj©dubj5")�”}”(hhh]”hú)�”}”(hŒ+the hash_bucket of the requeue target futex”h]”hŒ+the hash_bucket of the requeue target futex”…”�”}”(hjÈdh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³jÄdh´KÕhjÅdubah}”(h]”h ]”h"]”h$]”h&]”uh1j4"hj©dubeh}”(h]”h ]”h"]”h$]”h&]”uh1j"h³jÄdh´KÕhj4dubeh}”(h]”h ]”h"]”h$]”h&]”uh1j"hjdubhú)�”}”(hŒ**Description**”h]”j)�”}”(hjêdh]”hŒ Description”…”�”}”(hjìdh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhjèdubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³Œ_/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1364: ./kernel/futex/requeue.c”h´K×hjdubhú)�”}”(hŒ}During futex_requeue, with requeue_pi=1, it is possible to acquire the target futex if it is uncontended or via a lock steal.”h]”hŒ}During futex_requeue, with requeue_pi=1, it is possible to acquire the target futex if it is uncontended or via a lock steal.”…”�”}”(hjeh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³Œ_/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1364: ./kernel/futex/requeue.c”h´KÖhjdubhŒenumerated_list”“”)�”}”(hhh]”(j )�”}”(hŒgSet **q**::key to the requeue target futex key so the waiter can detect the wakeup on the right futex. ”h]”hú)�”}”(hŒfSet **q**::key to the requeue target futex key so the waiter can detect the wakeup on the right futex.”h]”(hŒSet ”…”�”}”(hjeh²hh³Nh´Nubj)�”}”(hŒ**q**”h]”hŒq”…”�”}”(hj eh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhjeubhŒ]::key to the requeue target futex key so the waiter can detect the wakeup on the right futex.”…”�”}”(hjeh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hùh³Œ_/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1364: ./kernel/futex/requeue.c”h´KÙhjeubah}”(h]”h ]”h"]”h$]”h&]”uh1jÁ hjeubj )�”}”(hŒ$Dequeue **q** from the hash bucket. ”h]”hú)�”}”(hŒ#Dequeue **q** from the hash bucket.”h]”(hŒDequeue ”…”�”}”(hjCeh²hh³Nh´Nubj)�”}”(hŒ**q**”h]”hŒq”…”�”}”(hjKeh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhjCeubhŒ from the hash bucket.”…”�”}”(hjCeh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hùh³Œ_/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1364: ./kernel/futex/requeue.c”h´KÜhj?eubah}”(h]”h ]”h"]”h$]”h&]”uh1jÁ hjeubj )�”}”(hŒVSet **q**::rt_waiter to NULL so the woken up task can detect atomic lock acquisition. ”h]”hú)�”}”(hŒUSet **q**::rt_waiter to NULL so the woken up task can detect atomic lock acquisition.”h]”(hŒSet ”…”�”}”(hjneh²hh³Nh´Nubj)�”}”(hŒ**q**”h]”hŒq”…”�”}”(hjveh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhjneubhŒL::rt_waiter to NULL so the woken up task can detect atomic lock acquisition.”…”�”}”(hjneh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hùh³Œ_/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1364: ./kernel/futex/requeue.c”h´KÞhjjeubah}”(h]”h ]”h"]”h$]”h&]”uh1jÁ hjeubj )�”}”(hŒkSet the q->lock_ptr to the requeue target hb->lock for the case that the waiter has to fixup the pi state. ”h]”hú)�”}”(hŒjSet the q->lock_ptr to the requeue target hb->lock for the case that the waiter has to fixup the pi state.”h]”hŒjSet the q->lock_ptr to the requeue target hb->lock for the case that the waiter has to fixup the pi state.”…”�”}”(hj™eh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³Œ_/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1364: ./kernel/futex/requeue.c”h´Káhj•eubah}”(h]”h ]”h"]”h$]”h&]”uh1jÁ hjeubj )�”}”(hŒ½Complete the requeue state so the waiter can make progress. After this point the waiter task can return from the syscall immediately in case that the pi state does not have to be fixed up. ”h]”hú)�”}”(hŒ¼Complete the requeue state so the waiter can make progress. After this point the waiter task can return from the syscall immediately in case that the pi state does not have to be fixed up.”h]”hŒ¼Complete the requeue state so the waiter can make progress. After this point the waiter task can return from the syscall immediately in case that the pi state does not have to be fixed up.”…”�”}”(hj²eh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³Œ_/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1364: ./kernel/futex/requeue.c”h´Kähj®eubah}”(h]”h ]”h"]”h$]”h&]”uh1jÁ hjeubj )�”}”(hŒWake the waiter task. ”h]”hú)�”}”(hŒWake the waiter task.”h]”hŒWake the waiter task.”…”�”}”(hjËeh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³Œ_/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1364: ./kernel/futex/requeue.c”h´KèhjÇeubah}”(h]”h ]”h"]”h$]”h&]”uh1jÁ hjeubeh}”(h]”h ]”h"]”h$]”h&]”Œenumtype”Œarabic”Œprefix”hŒsuffix”Œ)”uh1jehjdubhú)�”}”(hŒ7Must be called with both q->lock_ptr and hb->lock held.”h]”hŒ7Must be called with both q->lock_ptr and hb->lock held.”…”�”}”(hjëeh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³Œ_/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1364: ./kernel/futex/requeue.c”h´Kêhjdubeh}”(h]”h ]”Œ kernelindent”ah"]”h$]”h&]”uh1jñ!hj6h²hh³Nh´NubjR!)�”}”(hhh]”h}”(h]”h ]”h"]”h$]”h&]”Œentries”]”(j^!Œ'futex_proxy_trylock_atomic (C function)”Œc.futex_proxy_trylock_atomic”hNt”auh1jQ!hj6h²hh³Nh´Nubjc!)�”}”(hhh]”(jh!)�”}”(hŒëint futex_proxy_trylock_atomic (u32 __user *pifutex, struct futex_hash_bucket *hb1, struct futex_hash_bucket *hb2, union futex_key *key1, union futex_key *key2, struct futex_pi_state **ps, struct task_struct **exiting, int set_waiters)”h]”jn!)�”}”(hŒêint futex_proxy_trylock_atomic(u32 __user *pifutex, struct futex_hash_bucket *hb1, struct futex_hash_bucket *hb2, union futex_key *key1, union futex_key *key2, struct futex_pi_state **ps, struct task_struct **exiting, int set_waiters)”h]”(j$)�”}”(hŒint”h]”hŒint”…”�”}”(hjfh²hh³Nh´Nubah}”(h]”h ]”j$ah"]”h$]”h&]”uh1j$hjfh²hh³Œ_/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1364: ./kernel/futex/requeue.c”h´Mubj$)�”}”(hŒ ”h]”hŒ ”…”�”}”(hj)fh²hh³Nh´Nubah}”(h]”h ]”j $ah"]”h$]”h&]”uh1j$hjfh²hh³j(fh´Mubjt!)�”}”(hŒfutex_proxy_trylock_atomic”h]”jz!)�”}”(hŒfutex_proxy_trylock_atomic”h]”hŒfutex_proxy_trylock_atomic”…”�”}”(hj;fh²hh³Nh´Nubah}”(h]”h ]”j…!ah"]”h$]”h&]”uh1jy!hj7fubah}”(h]”h ]”(jŒ!j�!eh"]”h$]”h&]”j�jŽuh1js!hjfh²hh³j(fh´Mubj=$)�”}”(hŒÌ(u32 __user *pifutex, struct futex_hash_bucket *hb1, struct futex_hash_bucket *hb2, union futex_key *key1, union futex_key *key2, struct futex_pi_state **ps, struct task_struct **exiting, int set_waiters)”h]”(jC$)�”}”(hŒu32 __user *pifutex”h]”(h)�”}”(hhh]”jz!)�”}”(hŒu32”h]”hŒu32”…”�”}”(hjZfh²hh³Nh´Nubah}”(h]”h ]”j…!ah"]”h$]”h&]”uh1jy!hjWfubah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”jUŒreftype”j€$Œ reftarget”j\fŒmodname”NŒ classname”Nj„$j‡$)�”}”jŠ$]”j�$)�”}”j€$j=fsbŒc.futex_proxy_trylock_atomic”†”asbuh1hhjSfubj$)�”}”(hŒ ”h]”hŒ ”…”�”}”(hjzfh²hh³Nh´Nubah}”(h]”h ]”j $ah"]”h$]”h&]”uh1j$hjSfubhŒ__user”…”�”}”(hjSfh²hh³Nh´Nubj$)�”}”(hŒ ”h]”hŒ ”…”�”}”(hjŒfh²hh³Nh´Nubah}”(h]”h ]”j $ah"]”h$]”h&]”uh1j$hjSfubj¡$)�”}”(hj¤$h]”hŒ*”…”�”}”(hjšfh²hh³Nh´Nubah}”(h]”h ]”j­$ah"]”h$]”h&]”uh1j $hjSfubjz!)�”}”(hŒpifutex”h]”hŒpifutex”…”�”}”(hj§fh²hh³Nh´Nubah}”(h]”h ]”j…!ah"]”h$]”h&]”uh1jy!hjSfubeh}”(h]”h ]”h"]”h$]”h&]”Œnoemph”ˆj�jŽuh1jB$hjOfubjC$)�”}”(hŒstruct futex_hash_bucket *hb1”h]”(jI$)�”}”(hjL$h]”hŒstruct”…”�”}”(hjÀfh²hh³Nh´Nubah}”(h]”h ]”jU$ah"]”h$]”h&]”uh1jH$hj¼fubj$)�”}”(hŒ ”h]”hŒ ”…”�”}”(hjÍfh²hh³Nh´Nubah}”(h]”h ]”j $ah"]”h$]”h&]”uh1j$hj¼fubh)�”}”(hhh]”jz!)�”}”(hŒfutex_hash_bucket”h]”hŒfutex_hash_bucket”…”�”}”(hjÞfh²hh³Nh´Nubah}”(h]”h ]”j…!ah"]”h$]”h&]”uh1jy!hjÛfubah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”jUŒreftype”j€$Œ reftarget”jàfŒmodname”NŒ classname”Nj„$j‡$)�”}”jŠ$]”jvfŒc.futex_proxy_trylock_atomic”†”asbuh1hhj¼fubj$)�”}”(hŒ ”h]”hŒ ”…”�”}”(hjüfh²hh³Nh´Nubah}”(h]”h ]”j $ah"]”h$]”h&]”uh1j$hj¼fubj¡$)�”}”(hj¤$h]”hŒ*”…”�”}”(hj gh²hh³Nh´Nubah}”(h]”h ]”j­$ah"]”h$]”h&]”uh1j $hj¼fubjz!)�”}”(hŒhb1”h]”hŒhb1”…”�”}”(hjgh²hh³Nh´Nubah}”(h]”h ]”j…!ah"]”h$]”h&]”uh1jy!hj¼fubeh}”(h]”h ]”h"]”h$]”h&]”Œnoemph”ˆj�jŽuh1jB$hjOfubjC$)�”}”(hŒstruct futex_hash_bucket *hb2”h]”(jI$)�”}”(hjL$h]”hŒstruct”…”�”}”(hj0gh²hh³Nh´Nubah}”(h]”h ]”jU$ah"]”h$]”h&]”uh1jH$hj,gubj$)�”}”(hŒ ”h]”hŒ ”…”�”}”(hj=gh²hh³Nh´Nubah}”(h]”h ]”j $ah"]”h$]”h&]”uh1j$hj,gubh)�”}”(hhh]”jz!)�”}”(hŒfutex_hash_bucket”h]”hŒfutex_hash_bucket”…”�”}”(hjNgh²hh³Nh´Nubah}”(h]”h ]”j…!ah"]”h$]”h&]”uh1jy!hjKgubah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”jUŒreftype”j€$Œ reftarget”jPgŒmodname”NŒ classname”Nj„$j‡$)�”}”jŠ$]”jvfŒc.futex_proxy_trylock_atomic”†”asbuh1hhj,gubj$)�”}”(hŒ ”h]”hŒ ”…”�”}”(hjlgh²hh³Nh´Nubah}”(h]”h ]”j $ah"]”h$]”h&]”uh1j$hj,gubj¡$)�”}”(hj¤$h]”hŒ*”…”�”}”(hjzgh²hh³Nh´Nubah}”(h]”h ]”j­$ah"]”h$]”h&]”uh1j $hj,gubjz!)�”}”(hŒhb2”h]”hŒhb2”…”�”}”(hj‡gh²hh³Nh´Nubah}”(h]”h ]”j…!ah"]”h$]”h&]”uh1jy!hj,gubeh}”(h]”h ]”h"]”h$]”h&]”Œnoemph”ˆj�jŽuh1jB$hjOfubjC$)�”}”(hŒunion futex_key *key1”h]”(jI$)�”}”(hj§6h]”hŒunion”…”�”}”(hj gh²hh³Nh´Nubah}”(h]”h ]”jU$ah"]”h$]”h&]”uh1jH$hjœgubj$)�”}”(hŒ ”h]”hŒ ”…”�”}”(hj­gh²hh³Nh´Nubah}”(h]”h ]”j $ah"]”h$]”h&]”uh1j$hjœgubh)�”}”(hhh]”jz!)�”}”(hŒ futex_key”h]”hŒ futex_key”…”�”}”(hj¾gh²hh³Nh´Nubah}”(h]”h ]”j…!ah"]”h$]”h&]”uh1jy!hj»gubah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”jUŒreftype”j€$Œ reftarget”jÀgŒmodname”NŒ classname”Nj„$j‡$)�”}”jŠ$]”jvfŒc.futex_proxy_trylock_atomic”†”asbuh1hhjœgubj$)�”}”(hŒ ”h]”hŒ ”…”�”}”(hjÜgh²hh³Nh´Nubah}”(h]”h ]”j $ah"]”h$]”h&]”uh1j$hjœgubj¡$)�”}”(hj¤$h]”hŒ*”…”�”}”(hjêgh²hh³Nh´Nubah}”(h]”h ]”j­$ah"]”h$]”h&]”uh1j $hjœgubjz!)�”}”(hŒkey1”h]”hŒkey1”…”�”}”(hj÷gh²hh³Nh´Nubah}”(h]”h ]”j…!ah"]”h$]”h&]”uh1jy!hjœgubeh}”(h]”h ]”h"]”h$]”h&]”Œnoemph”ˆj�jŽuh1jB$hjOfubjC$)�”}”(hŒunion futex_key *key2”h]”(jI$)�”}”(hj§6h]”hŒunion”…”�”}”(hjhh²hh³Nh´Nubah}”(h]”h ]”jU$ah"]”h$]”h&]”uh1jH$hj hubj$)�”}”(hŒ ”h]”hŒ ”…”�”}”(hjhh²hh³Nh´Nubah}”(h]”h ]”j $ah"]”h$]”h&]”uh1j$hj hubh)�”}”(hhh]”jz!)�”}”(hŒ futex_key”h]”hŒ futex_key”…”�”}”(hj.hh²hh³Nh´Nubah}”(h]”h ]”j…!ah"]”h$]”h&]”uh1jy!hj+hubah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”jUŒreftype”j€$Œ reftarget”j0hŒmodname”NŒ classname”Nj„$j‡$)�”}”jŠ$]”jvfŒc.futex_proxy_trylock_atomic”†”asbuh1hhj hubj$)�”}”(hŒ ”h]”hŒ ”…”�”}”(hjLhh²hh³Nh´Nubah}”(h]”h ]”j $ah"]”h$]”h&]”uh1j$hj hubj¡$)�”}”(hj¤$h]”hŒ*”…”�”}”(hjZhh²hh³Nh´Nubah}”(h]”h ]”j­$ah"]”h$]”h&]”uh1j $hj hubjz!)�”}”(hŒkey2”h]”hŒkey2”…”�”}”(hjghh²hh³Nh´Nubah}”(h]”h ]”j…!ah"]”h$]”h&]”uh1jy!hj hubeh}”(h]”h ]”h"]”h$]”h&]”Œnoemph”ˆj�jŽuh1jB$hjOfubjC$)�”}”(hŒstruct futex_pi_state **ps”h]”(jI$)�”}”(hjL$h]”hŒstruct”…”�”}”(hj€hh²hh³Nh´Nubah}”(h]”h ]”jU$ah"]”h$]”h&]”uh1jH$hj|hubj$)�”}”(hŒ ”h]”hŒ ”…”�”}”(hj�hh²hh³Nh´Nubah}”(h]”h ]”j $ah"]”h$]”h&]”uh1j$hj|hubh)�”}”(hhh]”jz!)�”}”(hŒfutex_pi_state”h]”hŒfutex_pi_state”…”�”}”(hjžhh²hh³Nh´Nubah}”(h]”h ]”j…!ah"]”h$]”h&]”uh1jy!hj›hubah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”jUŒreftype”j€$Œ reftarget”j hŒmodname”NŒ classname”Nj„$j‡$)�”}”jŠ$]”jvfŒc.futex_proxy_trylock_atomic”†”asbuh1hhj|hubj$)�”}”(hŒ ”h]”hŒ ”…”�”}”(hj¼hh²hh³Nh´Nubah}”(h]”h ]”j $ah"]”h$]”h&]”uh1j$hj|hubj¡$)�”}”(hj¤$h]”hŒ*”…”�”}”(hjÊhh²hh³Nh´Nubah}”(h]”h ]”j­$ah"]”h$]”h&]”uh1j $hj|hubj¡$)�”}”(hj¤$h]”hŒ*”…”�”}”(hj×hh²hh³Nh´Nubah}”(h]”h ]”j­$ah"]”h$]”h&]”uh1j $hj|hubjz!)�”}”(hŒps”h]”hŒps”…”�”}”(hjähh²hh³Nh´Nubah}”(h]”h ]”j…!ah"]”h$]”h&]”uh1jy!hj|hubeh}”(h]”h ]”h"]”h$]”h&]”Œnoemph”ˆj�jŽuh1jB$hjOfubjC$)�”}”(hŒstruct task_struct **exiting”h]”(jI$)�”}”(hjL$h]”hŒstruct”…”�”}”(hjýhh²hh³Nh´Nubah}”(h]”h ]”jU$ah"]”h$]”h&]”uh1jH$hjùhubj$)�”}”(hŒ ”h]”hŒ ”…”�”}”(hj ih²hh³Nh´Nubah}”(h]”h ]”j $ah"]”h$]”h&]”uh1j$hjùhubh)�”}”(hhh]”jz!)�”}”(hŒ task_struct”h]”hŒ task_struct”…”�”}”(hjih²hh³Nh´Nubah}”(h]”h ]”j…!ah"]”h$]”h&]”uh1jy!hjiubah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”jUŒreftype”j€$Œ reftarget”jiŒmodname”NŒ classname”Nj„$j‡$)�”}”jŠ$]”jvfŒc.futex_proxy_trylock_atomic”†”asbuh1hhjùhubj$)�”}”(hŒ ”h]”hŒ ”…”�”}”(hj9ih²hh³Nh´Nubah}”(h]”h ]”j $ah"]”h$]”h&]”uh1j$hjùhubj¡$)�”}”(hj¤$h]”hŒ*”…”�”}”(hjGih²hh³Nh´Nubah}”(h]”h ]”j­$ah"]”h$]”h&]”uh1j $hjùhubj¡$)�”}”(hj¤$h]”hŒ*”…”�”}”(hjTih²hh³Nh´Nubah}”(h]”h ]”j­$ah"]”h$]”h&]”uh1j $hjùhubjz!)�”}”(hŒexiting”h]”hŒexiting”…”�”}”(hjaih²hh³Nh´Nubah}”(h]”h ]”j…!ah"]”h$]”h&]”uh1jy!hjùhubeh}”(h]”h ]”h"]”h$]”h&]”Œnoemph”ˆj�jŽuh1jB$hjOfubjC$)�”}”(hŒint set_waiters”h]”(j$)�”}”(hŒint”h]”hŒint”…”�”}”(hjzih²hh³Nh´Nubah}”(h]”h ]”j$ah"]”h$]”h&]”uh1j$hjviubj$)�”}”(hŒ ”h]”hŒ ”…”�”}”(hjˆih²hh³Nh´Nubah}”(h]”h ]”j $ah"]”h$]”h&]”uh1j$hjviubjz!)�”}”(hŒ set_waiters”h]”hŒ set_waiters”…”�”}”(hj–ih²hh³Nh´Nubah}”(h]”h ]”j…!ah"]”h$]”h&]”uh1jy!hjviubeh}”(h]”h ]”h"]”h$]”h&]”Œnoemph”ˆj�jŽuh1jB$hjOfubeh}”(h]”h ]”h"]”h$]”h&]”j�jŽuh1j<$hjfh²hh³j(fh´Mubeh}”(h]”h ]”h"]”h$]”h&]”j�jŽj˜!ˆuh1jm!j™!jš!hjfh²hh³j(fh´Mubah}”(h]”j fah ]”(jž!jŸ!eh"]”h$]”h&]”j£!ˆj¤!)j¥!huh1jg!h³j(fh´Mhjfh²hubj§!)�”}”(hhh]”hú)�”}”(hŒ)Attempt an atomic lock for the top waiter”h]”hŒ)Attempt an atomic lock for the top waiter”…”�”}”(hjÀih²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³Œ_/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1364: ./kernel/futex/requeue.c”h´Mhj½ih²hubah}”(h]”h ]”h"]”h$]”h&]”uh1j¦!hjfh²hh³j(fh´Mubeh}”(h]”h ]”(jUŒfunction”eh"]”h$]”h&]”j¸!jUj¹!jØijº!jØij»!‰j¼!‰j½!‰uh1jb!h²hhj6h³Nh´Nubjò!)�”}”(hXÑ**Parameters** ``u32 __user *pifutex`` the user address of the to futex ``struct futex_hash_bucket *hb1`` the from futex hash bucket, must be locked by the caller ``struct futex_hash_bucket *hb2`` the to futex hash bucket, must be locked by the caller ``union futex_key *key1`` the from futex key ``union futex_key *key2`` the to futex key ``struct futex_pi_state **ps`` address to store the pi_state pointer ``struct task_struct **exiting`` Pointer to store the task pointer of the owner task which is in the middle of exiting ``int set_waiters`` force setting the FUTEX_WAITERS bit (1) or not (0) **Description** Try and get the lock on behalf of the top waiter if we can do it atomically. Wake the top waiter if we succeed. If the caller specified set_waiters, then direct futex_lock_pi_atomic() to force setting the FUTEX_WAITERS bit. hb1 and hb2 must be held by the caller. **exiting** is only set when the return value is -EBUSY. If so, this holds a refcount on the exiting task on return and the caller needs to drop it after waiting for the exit to complete. **Return** - 0 - failed to acquire the lock atomically; - >0 - acquired the lock, return value is vpid of the top_waiter - <0 - error”h]”(hú)�”}”(hŒ**Parameters**”h]”j)�”}”(hjâih]”hŒ Parameters”…”�”}”(hjäih²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhjàiubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³Œ_/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1364: ./kernel/futex/requeue.c”h´M hjÜiubj")�”}”(hhh]”(j")�”}”(hŒ9``u32 __user *pifutex`` the user address of the to futex ”h]”(j")�”}”(hŒ``u32 __user *pifutex``”h]”jI)�”}”(hjjh]”hŒu32 __user *pifutex”…”�”}”(hjjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jHhjÿiubah}”(h]”h ]”h"]”h$]”h&]”uh1j"h³Œ_/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1364: ./kernel/futex/requeue.c”h´Mhjûiubj5")�”}”(hhh]”hú)�”}”(hŒ the user address of the to futex”h]”hŒ the user address of the to futex”…”�”}”(hjjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³jjh´Mhjjubah}”(h]”h ]”h"]”h$]”h&]”uh1j4"hjûiubeh}”(h]”h ]”h"]”h$]”h&]”uh1j"h³jjh´Mhjøiubj")�”}”(hŒ[``struct futex_hash_bucket *hb1`` the from futex hash bucket, must be locked by the caller ”h]”(j")�”}”(hŒ!``struct futex_hash_bucket *hb1``”h]”jI)�”}”(hj:jh]”hŒstruct futex_hash_bucket *hb1”…”�”}”(hj>0 - acquired the lock, return value is vpid of the top_waiter”h]”hú)�”}”(hjClh]”hŒ>>0 - acquired the lock, return value is vpid of the top_waiter”…”�”}”(hjElh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³Œ_/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1364: ./kernel/futex/requeue.c”h´MhjAlubah}”(h]”h ]”h"]”h$]”h&]”uh1jÁ hj&lubj )�”}”(hŒ <0 - error”h]”hú)�”}”(hj[lh]”hŒ <0 - error”…”�”}”(hj]lh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³Œ_/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1364: ./kernel/futex/requeue.c”h´MhjYlubah}”(h]”h ]”h"]”h$]”h&]”uh1jÁ hj&lubeh}”(h]”h ]”h"]”h$]”h&]”j5 j6 uh1j¼ h³j:lh´MhjÜiubeh}”(h]”h ]”Œ kernelindent”ah"]”h$]”h&]”uh1jñ!hj6h²hh³Nh´NubjR!)�”}”(hhh]”h}”(h]”h ]”h"]”h$]”h&]”Œentries”]”(j^!Œfutex_requeue (C function)”Œc.futex_requeue”hNt”auh1jQ!hj6h²hh³Nh´Nubjc!)�”}”(hhh]”(jh!)�”}”(hŒžint futex_requeue (u32 __user *uaddr1, unsigned int flags1, u32 __user *uaddr2, unsigned int flags2, int nr_wake, int nr_requeue, u32 *cmpval, int requeue_pi)”h]”jn!)�”}”(hŒ�int futex_requeue(u32 __user *uaddr1, unsigned int flags1, u32 __user *uaddr2, unsigned int flags2, int nr_wake, int nr_requeue, u32 *cmpval, int requeue_pi)”h]”(j$)�”}”(hŒint”h]”hŒint”…”�”}”(hj—lh²hh³Nh´Nubah}”(h]”h ]”j$ah"]”h$]”h&]”uh1j$hj“lh²hh³Œ_/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1364: ./kernel/futex/requeue.c”h´Mtubj$)�”}”(hŒ ”h]”hŒ ”…”�”}”(hj¦lh²hh³Nh´Nubah}”(h]”h ]”j $ah"]”h$]”h&]”uh1j$hj“lh²hh³j¥lh´Mtubjt!)�”}”(hŒ futex_requeue”h]”jz!)�”}”(hŒ futex_requeue”h]”hŒ futex_requeue”…”�”}”(hj¸lh²hh³Nh´Nubah}”(h]”h ]”j…!ah"]”h$]”h&]”uh1jy!hj´lubah}”(h]”h ]”(jŒ!j�!eh"]”h$]”h&]”j�jŽuh1js!hj“lh²hh³j¥lh´Mtubj=$)�”}”(hŒŒ(u32 __user *uaddr1, unsigned int flags1, u32 __user *uaddr2, unsigned int flags2, int nr_wake, int nr_requeue, u32 *cmpval, int requeue_pi)”h]”(jC$)�”}”(hŒu32 __user *uaddr1”h]”(h)�”}”(hhh]”jz!)�”}”(hŒu32”h]”hŒu32”…”�”}”(hj×lh²hh³Nh´Nubah}”(h]”h ]”j…!ah"]”h$]”h&]”uh1jy!hjÔlubah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”jUŒreftype”j€$Œ reftarget”jÙlŒmodname”NŒ classname”Nj„$j‡$)�”}”jŠ$]”j�$)�”}”j€$jºlsbŒc.futex_requeue”†”asbuh1hhjÐlubj$)�”}”(hŒ ”h]”hŒ ”…”�”}”(hj÷lh²hh³Nh´Nubah}”(h]”h ]”j $ah"]”h$]”h&]”uh1j$hjÐlubhŒ__user”…”�”}”(hjÐlh²hh³Nh´Nubj$)�”}”(hŒ ”h]”hŒ ”…”�”}”(hj mh²hh³Nh´Nubah}”(h]”h ]”j $ah"]”h$]”h&]”uh1j$hjÐlubj¡$)�”}”(hj¤$h]”hŒ*”…”�”}”(hjmh²hh³Nh´Nubah}”(h]”h ]”j­$ah"]”h$]”h&]”uh1j $hjÐlubjz!)�”}”(hŒuaddr1”h]”hŒuaddr1”…”�”}”(hj$mh²hh³Nh´Nubah}”(h]”h ]”j…!ah"]”h$]”h&]”uh1jy!hjÐlubeh}”(h]”h ]”h"]”h$]”h&]”Œnoemph”ˆj�jŽuh1jB$hjÌlubjC$)�”}”(hŒunsigned int flags1”h]”(j$)�”}”(hŒunsigned”h]”hŒunsigned”…”�”}”(hj=mh²hh³Nh´Nubah}”(h]”h ]”j$ah"]”h$]”h&]”uh1j$hj9mubj$)�”}”(hŒ ”h]”hŒ ”…”�”}”(hjKmh²hh³Nh´Nubah}”(h]”h ]”j $ah"]”h$]”h&]”uh1j$hj9mubj$)�”}”(hŒint”h]”hŒint”…”�”}”(hjYmh²hh³Nh´Nubah}”(h]”h ]”j$ah"]”h$]”h&]”uh1j$hj9mubj$)�”}”(hŒ ”h]”hŒ ”…”�”}”(hjgmh²hh³Nh´Nubah}”(h]”h ]”j $ah"]”h$]”h&]”uh1j$hj9mubjz!)�”}”(hŒflags1”h]”hŒflags1”…”�”}”(hjumh²hh³Nh´Nubah}”(h]”h ]”j…!ah"]”h$]”h&]”uh1jy!hj9mubeh}”(h]”h ]”h"]”h$]”h&]”Œnoemph”ˆj�jŽuh1jB$hjÌlubjC$)�”}”(hŒu32 __user *uaddr2”h]”(h)�”}”(hhh]”jz!)�”}”(hŒu32”h]”hŒu32”…”�”}”(hj‘mh²hh³Nh´Nubah}”(h]”h ]”j…!ah"]”h$]”h&]”uh1jy!hjŽmubah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”jUŒreftype”j€$Œ reftarget”j“mŒmodname”NŒ classname”Nj„$j‡$)�”}”jŠ$]”jólŒc.futex_requeue”†”asbuh1hhjŠmubj$)�”}”(hŒ ”h]”hŒ ”…”�”}”(hj¯mh²hh³Nh´Nubah}”(h]”h ]”j $ah"]”h$]”h&]”uh1j$hjŠmubhŒ__user”…”�”}”(hjŠmh²hh³Nh´Nubj$)�”}”(hŒ ”h]”hŒ ”…”�”}”(hjÁmh²hh³Nh´Nubah}”(h]”h ]”j $ah"]”h$]”h&]”uh1j$hjŠmubj¡$)�”}”(hj¤$h]”hŒ*”…”�”}”(hjÏmh²hh³Nh´Nubah}”(h]”h ]”j­$ah"]”h$]”h&]”uh1j $hjŠmubjz!)�”}”(hŒuaddr2”h]”hŒuaddr2”…”�”}”(hjÜmh²hh³Nh´Nubah}”(h]”h ]”j…!ah"]”h$]”h&]”uh1jy!hjŠmubeh}”(h]”h ]”h"]”h$]”h&]”Œnoemph”ˆj�jŽuh1jB$hjÌlubjC$)�”}”(hŒunsigned int flags2”h]”(j$)�”}”(hŒunsigned”h]”hŒunsigned”…”�”}”(hjõmh²hh³Nh´Nubah}”(h]”h ]”j$ah"]”h$]”h&]”uh1j$hjñmubj$)�”}”(hŒ ”h]”hŒ ”…”�”}”(hjnh²hh³Nh´Nubah}”(h]”h ]”j $ah"]”h$]”h&]”uh1j$hjñmubj$)�”}”(hŒint”h]”hŒint”…”�”}”(hjnh²hh³Nh´Nubah}”(h]”h ]”j$ah"]”h$]”h&]”uh1j$hjñmubj$)�”}”(hŒ ”h]”hŒ ”…”�”}”(hjnh²hh³Nh´Nubah}”(h]”h ]”j $ah"]”h$]”h&]”uh1j$hjñmubjz!)�”}”(hŒflags2”h]”hŒflags2”…”�”}”(hj-nh²hh³Nh´Nubah}”(h]”h ]”j…!ah"]”h$]”h&]”uh1jy!hjñmubeh}”(h]”h ]”h"]”h$]”h&]”Œnoemph”ˆj�jŽuh1jB$hjÌlubjC$)�”}”(hŒ int nr_wake”h]”(j$)�”}”(hŒint”h]”hŒint”…”�”}”(hjFnh²hh³Nh´Nubah}”(h]”h ]”j$ah"]”h$]”h&]”uh1j$hjBnubj$)�”}”(hŒ ”h]”hŒ ”…”�”}”(hjTnh²hh³Nh´Nubah}”(h]”h ]”j $ah"]”h$]”h&]”uh1j$hjBnubjz!)�”}”(hŒnr_wake”h]”hŒnr_wake”…”�”}”(hjbnh²hh³Nh´Nubah}”(h]”h ]”j…!ah"]”h$]”h&]”uh1jy!hjBnubeh}”(h]”h ]”h"]”h$]”h&]”Œnoemph”ˆj�jŽuh1jB$hjÌlubjC$)�”}”(hŒint nr_requeue”h]”(j$)�”}”(hŒint”h]”hŒint”…”�”}”(hj{nh²hh³Nh´Nubah}”(h]”h ]”j$ah"]”h$]”h&]”uh1j$hjwnubj$)�”}”(hŒ ”h]”hŒ ”…”�”}”(hj‰nh²hh³Nh´Nubah}”(h]”h ]”j $ah"]”h$]”h&]”uh1j$hjwnubjz!)�”}”(hŒ nr_requeue”h]”hŒ nr_requeue”…”�”}”(hj—nh²hh³Nh´Nubah}”(h]”h ]”j…!ah"]”h$]”h&]”uh1jy!hjwnubeh}”(h]”h ]”h"]”h$]”h&]”Œnoemph”ˆj�jŽuh1jB$hjÌlubjC$)�”}”(hŒ u32 *cmpval”h]”(h)�”}”(hhh]”jz!)�”}”(hŒu32”h]”hŒu32”…”�”}”(hj³nh²hh³Nh´Nubah}”(h]”h ]”j…!ah"]”h$]”h&]”uh1jy!hj°nubah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”jUŒreftype”j€$Œ reftarget”jµnŒmodname”NŒ classname”Nj„$j‡$)�”}”jŠ$]”jólŒc.futex_requeue”†”asbuh1hhj¬nubj$)�”}”(hŒ ”h]”hŒ ”…”�”}”(hjÑnh²hh³Nh´Nubah}”(h]”h ]”j $ah"]”h$]”h&]”uh1j$hj¬nubj¡$)�”}”(hj¤$h]”hŒ*”…”�”}”(hjßnh²hh³Nh´Nubah}”(h]”h ]”j­$ah"]”h$]”h&]”uh1j $hj¬nubjz!)�”}”(hŒcmpval”h]”hŒcmpval”…”�”}”(hjình²hh³Nh´Nubah}”(h]”h ]”j…!ah"]”h$]”h&]”uh1jy!hj¬nubeh}”(h]”h ]”h"]”h$]”h&]”Œnoemph”ˆj�jŽuh1jB$hjÌlubjC$)�”}”(hŒint requeue_pi”h]”(j$)�”}”(hŒint”h]”hŒint”…”�”}”(hjoh²hh³Nh´Nubah}”(h]”h ]”j$ah"]”h$]”h&]”uh1j$hjoubj$)�”}”(hŒ ”h]”hŒ ”…”�”}”(hjoh²hh³Nh´Nubah}”(h]”h ]”j $ah"]”h$]”h&]”uh1j$hjoubjz!)�”}”(hŒ requeue_pi”h]”hŒ requeue_pi”…”�”}”(hj!oh²hh³Nh´Nubah}”(h]”h ]”j…!ah"]”h$]”h&]”uh1jy!hjoubeh}”(h]”h ]”h"]”h$]”h&]”Œnoemph”ˆj�jŽuh1jB$hjÌlubeh}”(h]”h ]”h"]”h$]”h&]”j�jŽuh1j<$hj“lh²hh³j¥lh´Mtubeh}”(h]”h ]”h"]”h$]”h&]”j�jŽj˜!ˆuh1jm!j™!jš!hj�lh²hh³j¥lh´Mtubah}”(h]”jŠlah ]”(jž!jŸ!eh"]”h$]”h&]”j£!ˆj¤!)j¥!huh1jg!h³j¥lh´MthjŒlh²hubj§!)�”}”(hhh]”hú)�”}”(hŒ%Requeue waiters from uaddr1 to uaddr2”h]”hŒ%Requeue waiters from uaddr1 to uaddr2”…”�”}”(hjKoh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³Œ_/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1364: ./kernel/futex/requeue.c”•h´MthjHoh²hubah}”(h]”h ]”h"]”h$]”h&]”uh1j¦!hjŒlh²hh³j¥lh´Mtubeh}”(h]”h ]”(jUŒfunction”eh"]”h$]”h&]”j¸!jUj¹!jcojº!jcoj»!‰j¼!‰j½!‰uh1jb!h²hhj6h³Nh´Nubjò!)�”}”(hX**Parameters** ``u32 __user *uaddr1`` source futex user address ``unsigned int flags1`` futex flags (FLAGS_SHARED, etc.) ``u32 __user *uaddr2`` target futex user address ``unsigned int flags2`` futex flags (FLAGS_SHARED, etc.) ``int nr_wake`` number of waiters to wake (must be 1 for requeue_pi) ``int nr_requeue`` number of waiters to requeue (0-INT_MAX) ``u32 *cmpval`` **uaddr1** expected value (or ``NULL``) ``int requeue_pi`` if we are attempting to requeue from a non-pi futex to a pi futex (pi to pi requeue is not supported) **Description** Requeue waiters on uaddr1 to uaddr2. In the requeue_pi case, try to acquire uaddr2 atomically on behalf of the top waiter. **Return** - >=0 - on success, the number of tasks requeued or woken; - <0 - on error”h]”(hú)�”}”(hŒ**Parameters**”h]”j)�”}”(hjmoh]”hŒ Parameters”…”�”}”(hjooh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhjkoubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³Œ_/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1364: ./kernel/futex/requeue.c”h´Mxhjgoubj")�”}”(hhh]”(j")�”}”(hŒ1``u32 __user *uaddr1`` source futex user address ”h]”(j")�”}”(hŒ``u32 __user *uaddr1``”h]”jI)�”}”(hjŒoh]”hŒu32 __user *uaddr1”…”�”}”(hjŽoh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jHhjŠoubah}”(h]”h ]”h"]”h$]”h&]”uh1j"h³Œ_/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1364: ./kernel/futex/requeue.c”h´Muhj†oubj5")�”}”(hhh]”hú)�”}”(hŒsource futex user address”h]”hŒsource futex user address”…”�”}”(hj¥oh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³j¡oh´Muhj¢oubah}”(h]”h ]”h"]”h$]”h&]”uh1j4"hj†oubeh}”(h]”h ]”h"]”h$]”h&]”uh1j"h³j¡oh´Muhjƒoubj")�”}”(hŒ9``unsigned int flags1`` futex flags (FLAGS_SHARED, etc.) ”h]”(j")�”}”(hŒ``unsigned int flags1``”h]”jI)�”}”(hjÅoh]”hŒunsigned int flags1”…”�”}”(hjÇoh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jHhjÃoubah}”(h]”h ]”h"]”h$]”h&]”uh1j"h³Œ_/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1364: ./kernel/futex/requeue.c”h´Mvhj¿oubj5")�”}”(hhh]”hú)�”}”(hŒ futex flags (FLAGS_SHARED, etc.)”h]”hŒ futex flags (FLAGS_SHARED, etc.)”…”�”}”(hjÞoh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³jÚoh´MvhjÛoubah}”(h]”h ]”h"]”h$]”h&]”uh1j4"hj¿oubeh}”(h]”h ]”h"]”h$]”h&]”uh1j"h³jÚoh´Mvhjƒoubj")�”}”(hŒ1``u32 __user *uaddr2`` target futex user address ”h]”(j")�”}”(hŒ``u32 __user *uaddr2``”h]”jI)�”}”(hjþoh]”hŒu32 __user *uaddr2”…”�”}”(hjph²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jHhjüoubah}”(h]”h ]”h"]”h$]”h&]”uh1j"h³Œ_/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1364: ./kernel/futex/requeue.c”h´Mwhjøoubj5")�”}”(hhh]”hú)�”}”(hŒtarget futex user address”h]”hŒtarget futex user address”…”�”}”(hjph²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³jph´Mwhjpubah}”(h]”h ]”h"]”h$]”h&]”uh1j4"hjøoubeh}”(h]”h ]”h"]”h$]”h&]”uh1j"h³jph´Mwhjƒoubj")�”}”(hŒ9``unsigned int flags2`` futex flags (FLAGS_SHARED, etc.) ”h]”(j")�”}”(hŒ``unsigned int flags2``”h]”jI)�”}”(hj7ph]”hŒunsigned int flags2”…”�”}”(hj9ph²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jHhj5pubah}”(h]”h ]”h"]”h$]”h&]”uh1j"h³Œ_/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1364: ./kernel/futex/requeue.c”h´Mxhj1pubj5")�”}”(hhh]”hú)�”}”(hŒ futex flags (FLAGS_SHARED, etc.)”h]”hŒ futex flags (FLAGS_SHARED, etc.)”…”�”}”(hjPph²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³jLph´MxhjMpubah}”(h]”h ]”h"]”h$]”h&]”uh1j4"hj1pubeh}”(h]”h ]”h"]”h$]”h&]”uh1j"h³jLph´Mxhjƒoubj")�”}”(hŒE``int nr_wake`` number of waiters to wake (must be 1 for requeue_pi) ”h]”(j")�”}”(hŒ``int nr_wake``”h]”jI)�”}”(hjpph]”hŒ int nr_wake”…”�”}”(hjrph²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jHhjnpubah}”(h]”h ]”h"]”h$]”h&]”uh1j"h³Œ_/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1364: ./kernel/futex/requeue.c”h´Myhjjpubj5")�”}”(hhh]”hú)�”}”(hŒ4number of waiters to wake (must be 1 for requeue_pi)”h]”hŒ4number of waiters to wake (must be 1 for requeue_pi)”…”�”}”(hj‰ph²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³j…ph´Myhj†pubah}”(h]”h ]”h"]”h$]”h&]”uh1j4"hjjpubeh}”(h]”h ]”h"]”h$]”h&]”uh1j"h³j…ph´Myhjƒoubj")�”}”(hŒ<``int nr_requeue`` number of waiters to requeue (0-INT_MAX) ”h]”(j")�”}”(hŒ``int nr_requeue``”h]”jI)�”}”(hj©ph]”hŒint nr_requeue”…”�”}”(hj«ph²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jHhj§pubah}”(h]”h ]”h"]”h$]”h&]”uh1j"h³Œ_/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1364: ./kernel/futex/requeue.c”h´Mzhj£pubj5")�”}”(hhh]”hú)�”}”(hŒ(number of waiters to requeue (0-INT_MAX)”h]”hŒ(number of waiters to requeue (0-INT_MAX)”…”�”}”(hjÂph²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³j¾ph´Mzhj¿pubah}”(h]”h ]”h"]”h$]”h&]”uh1j4"hj£pubeh}”(h]”h ]”h"]”h$]”h&]”uh1j"h³j¾ph´Mzhjƒoubj")�”}”(hŒ8``u32 *cmpval`` **uaddr1** expected value (or ``NULL``) ”h]”(j")�”}”(hŒ``u32 *cmpval``”h]”jI)�”}”(hjâph]”hŒ u32 *cmpval”…”�”}”(hjäph²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jHhjàpubah}”(h]”h ]”h"]”h$]”h&]”uh1j"h³Œ_/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1364: ./kernel/futex/requeue.c”h´M{hjÜpubj5")�”}”(hhh]”hú)�”}”(hŒ'**uaddr1** expected value (or ``NULL``)”h]”(j)�”}”(hŒ **uaddr1**”h]”hŒuaddr1”…”�”}”(hjÿph²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhjûpubhŒ expected value (or ”…”�”}”(hjûph²hh³Nh´NubjI)�”}”(hŒ``NULL``”h]”hŒNULL”…”�”}”(hjqh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jHhjûpubhŒ)”…”�”}”(hjûph²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hùh³j÷ph´M{hjøpubah}”(h]”h ]”h"]”h$]”h&]”uh1j4"hjÜpubeh}”(h]”h ]”h"]”h$]”h&]”uh1j"h³j÷ph´M{hjƒoubj")�”}”(hŒy``int requeue_pi`` if we are attempting to requeue from a non-pi futex to a pi futex (pi to pi requeue is not supported) ”h]”(j")�”}”(hŒ``int requeue_pi``”h]”jI)�”}”(hj;qh]”hŒint requeue_pi”…”�”}”(hj=qh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jHhj9qubah}”(h]”h ]”h"]”h$]”h&]”uh1j"h³Œ_/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1364: ./kernel/futex/requeue.c”h´M}hj5qubj5")�”}”(hhh]”hú)�”}”(hŒeif we are attempting to requeue from a non-pi futex to a pi futex (pi to pi requeue is not supported)”h]”hŒeif we are attempting to requeue from a non-pi futex to a pi futex (pi to pi requeue is not supported)”…”�”}”(hjTqh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³Œ_/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1364: ./kernel/futex/requeue.c”h´M|hjQqubah}”(h]”h ]”h"]”h$]”h&]”uh1j4"hj5qubeh}”(h]”h ]”h"]”h$]”h&]”uh1j"h³jPqh´M}hjƒoubeh}”(h]”h ]”h"]”h$]”h&]”uh1j"hjgoubhú)�”}”(hŒ**Description**”h]”j)�”}”(hjwqh]”hŒ Description”…”�”}”(hjyqh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhjuqubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³Œ_/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1364: ./kernel/futex/requeue.c”h´Mhjgoubhú)�”}”(hŒzRequeue waiters on uaddr1 to uaddr2. In the requeue_pi case, try to acquire uaddr2 atomically on behalf of the top waiter.”h]”hŒzRequeue waiters on uaddr1 to uaddr2. In the requeue_pi case, try to acquire uaddr2 atomically on behalf of the top waiter.”…”�”}”(hj�qh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³Œ_/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1364: ./kernel/futex/requeue.c”h´M~hjgoubhú)�”}”(hŒ **Return**”h]”j)�”}”(hjžqh]”hŒReturn”…”�”}”(hj qh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhjœqubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³Œ_/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1364: ./kernel/futex/requeue.c”h´M�hjgoubj½ )�”}”(hhh]”(j )�”}”(hŒ8>=0 - on success, the number of tasks requeued or woken;”h]”hú)�”}”(hj¹qh]”hŒ8>=0 - on success, the number of tasks requeued or woken;”…”�”}”(hj»qh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³Œ_/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1364: ./kernel/futex/requeue.c”h´M‚hj·qubah}”(h]”h ]”h"]”h$]”h&]”uh1jÁ hj´qubj )�”}”(hŒ <0 - on error”h]”hú)�”}”(hjÑqh]”hŒ <0 - on error”…”�”}”(hjÓqh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³Œ_/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1364: ./kernel/futex/requeue.c”h´MƒhjÏqubah}”(h]”h ]”h"]”h$]”h&]”uh1jÁ hj´qubeh}”(h]”h ]”h"]”h$]”h&]”j5 j6 uh1j¼ h³jÈqh´M‚hjgoubeh}”(h]”h ]”Œ kernelindent”ah"]”h$]”h&]”uh1jñ!hj6h²hh³Nh´NubjR!)�”}”(hhh]”h}”(h]”h ]”h"]”h$]”h&]”Œentries”]”(j^!Œ+handle_early_requeue_pi_wakeup (C function)”Œ c.handle_early_requeue_pi_wakeup”hNt”auh1jQ!hj6h²hh³Nh´Nubjc!)�”}”(hhh]”(jh!)�”}”(hŒuint handle_early_requeue_pi_wakeup (struct futex_hash_bucket *hb, struct futex_q *q, struct hrtimer_sleeper *timeout)”h]”jn!)�”}”(hŒtint handle_early_requeue_pi_wakeup(struct futex_hash_bucket *hb, struct futex_q *q, struct hrtimer_sleeper *timeout)”h]”(j$)�”}”(hŒint”h]”hŒint”…”�”}”(hj rh²hh³Nh´Nubah}”(h]”h ]”j$ah"]”h$]”h&]”uh1j$hj rh²hh³Œ_/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1364: ./kernel/futex/requeue.c”h´MÆubj$)�”}”(hŒ ”h]”hŒ ”…”�”}”(hjrh²hh³Nh´Nubah}”(h]”h ]”j $ah"]”h$]”h&]”uh1j$hj rh²hh³jrh´MÆubjt!)�”}”(hŒhandle_early_requeue_pi_wakeup”h]”jz!)�”}”(hŒhandle_early_requeue_pi_wakeup”h]”hŒhandle_early_requeue_pi_wakeup”…”�”}”(hj.rh²hh³Nh´Nubah}”(h]”h ]”j…!ah"]”h$]”h&]”uh1jy!hj*rubah}”(h]”h ]”(jŒ!j�!eh"]”h$]”h&]”j�jŽuh1js!hj rh²hh³jrh´MÆubj=$)�”}”(hŒR(struct futex_hash_bucket *hb, struct futex_q *q, struct hrtimer_sleeper *timeout)”h]”(jC$)�”}”(hŒstruct futex_hash_bucket *hb”h]”(jI$)�”}”(hjL$h]”hŒstruct”…”�”}”(hjJrh²hh³Nh´Nubah}”(h]”h ]”jU$ah"]”h$]”h&]”uh1jH$hjFrubj$)�”}”(hŒ ”h]”hŒ ”…”�”}”(hjWrh²hh³Nh´Nubah}”(h]”h ]”j $ah"]”h$]”h&]”uh1j$hjFrubh)�”}”(hhh]”jz!)�”}”(hŒfutex_hash_bucket”h]”hŒfutex_hash_bucket”…”�”}”(hjhrh²hh³Nh´Nubah}”(h]”h ]”j…!ah"]”h$]”h&]”uh1jy!hjerubah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”jUŒreftype”j€$Œ reftarget”jjrŒmodname”NŒ classname”Nj„$j‡$)�”}”jŠ$]”j�$)�”}”j€$j0rsbŒ c.handle_early_requeue_pi_wakeup”†”asbuh1hhjFrubj$)�”}”(hŒ ”h]”hŒ ”…”�”}”(hjˆrh²hh³Nh´Nubah}”(h]”h ]”j $ah"]”h$]”h&]”uh1j$hjFrubj¡$)�”}”(hj¤$h]”hŒ*”…”�”}”(hj–rh²hh³Nh´Nubah}”(h]”h ]”j­$ah"]”h$]”h&]”uh1j $hjFrubjz!)�”}”(hŒhb”h]”hŒhb”…”�”}”(hj£rh²hh³Nh´Nubah}”(h]”h ]”j…!ah"]”h$]”h&]”uh1jy!hjFrubeh}”(h]”h ]”h"]”h$]”h&]”Œnoemph”ˆj�jŽuh1jB$hjBrubjC$)�”}”(hŒstruct futex_q *q”h]”(jI$)�”}”(hjL$h]”hŒstruct”…”�”}”(hj¼rh²hh³Nh´Nubah}”(h]”h ]”jU$ah"]”h$]”h&]”uh1jH$hj¸rubj$)�”}”(hŒ ”h]”hŒ ”…”�”}”(hjÉrh²hh³Nh´Nubah}”(h]”h ]”j $ah"]”h$]”h&]”uh1j$hj¸rubh)�”}”(hhh]”jz!)�”}”(hŒfutex_q”h]”hŒfutex_q”…”�”}”(hjÚrh²hh³Nh´Nubah}”(h]”h ]”j…!ah"]”h$]”h&]”uh1jy!hj×rubah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”jUŒreftype”j€$Œ reftarget”jÜrŒmodname”NŒ classname”Nj„$j‡$)�”}”jŠ$]”j„rŒ c.handle_early_requeue_pi_wakeup”†”asbuh1hhj¸rubj$)�”}”(hŒ ”h]”hŒ ”…”�”}”(hjørh²hh³Nh´Nubah}”(h]”h ]”j $ah"]”h$]”h&]”uh1j$hj¸rubj¡$)�”}”(hj¤$h]”hŒ*”…”�”}”(hjsh²hh³Nh´Nubah}”(h]”h ]”j­$ah"]”h$]”h&]”uh1j $hj¸rubjz!)�”}”(hj;Gh]”hŒq”…”�”}”(hjsh²hh³Nh´Nubah}”(h]”h ]”j…!ah"]”h$]”h&]”uh1jy!hj¸rubeh}”(h]”h ]”h"]”h$]”h&]”Œnoemph”ˆj�jŽuh1jB$hjBrubjC$)�”}”(hŒstruct hrtimer_sleeper *timeout”h]”(jI$)�”}”(hjL$h]”hŒstruct”…”�”}”(hj+sh²hh³Nh´Nubah}”(h]”h ]”jU$ah"]”h$]”h&]”uh1jH$hj'subj$)�”}”(hŒ ”h]”hŒ ”…”�”}”(hj8sh²hh³Nh´Nubah}”(h]”h ]”j $ah"]”h$]”h&]”uh1j$hj'subh)�”}”(hhh]”jz!)�”}”(hŒhrtimer_sleeper”h]”hŒhrtimer_sleeper”…”�”}”(hjIsh²hh³Nh´Nubah}”(h]”h ]”j…!ah"]”h$]”h&]”uh1jy!hjFsubah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”jUŒreftype”j€$Œ reftarget”jKsŒmodname”NŒ classname”Nj„$j‡$)�”}”jŠ$]”j„rŒ c.handle_early_requeue_pi_wakeup”†”asbuh1hhj'subj$)�”}”(hŒ ”h]”hŒ ”…”�”}”(hjgsh²hh³Nh´Nubah}”(h]”h ]”j $ah"]”h$]”h&]”uh1j$hj'subj¡$)�”}”(hj¤$h]”hŒ*”…”�”}”(hjush²hh³Nh´Nubah}”(h]”h ]”j­$ah"]”h$]”h&]”uh1j $hj'subjz!)�”}”(hŒtimeout”h]”hŒtimeout”…”�”}”(hj‚sh²hh³Nh´Nubah}”(h]”h ]”j…!ah"]”h$]”h&]”uh1jy!hj'subeh}”(h]”h ]”h"]”h$]”h&]”Œnoemph”ˆj�jŽuh1jB$hjBrubeh}”(h]”h ]”h"]”h$]”h&]”j�jŽuh1j<$hj rh²hh³jrh´MÆubeh}”(h]”h ]”h"]”h$]”h&]”j�jŽj˜!ˆuh1jm!j™!jš!hjrh²hh³jrh´MÆubah}”(h]”jrah ]”(jž!jŸ!eh"]”h$]”h&]”j£!ˆj¤!)j¥!huh1jg!h³jrh´MÆhjrh²hubj§!)�”}”(hhh]”hú)�”}”(hŒ(Handle early wakeup on the initial futex”h]”hŒ(Handle early wakeup on the initial futex”…”�”}”(hj¬sh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³Œ_/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1364: ./kernel/futex/requeue.c”h´MÆhj©sh²hubah}”(h]”h ]”h"]”h$]”h&]”uh1j¦!hjrh²hh³jrh´MÆubeh}”(h]”h ]”(jUŒfunction”eh"]”h$]”h&]”j¸!jUj¹!jÄsjº!jÄsj»!‰j¼!‰j½!‰uh1jb!h²hhj6h³Nh´Nubjò!)�”}”(hX}**Parameters** ``struct futex_hash_bucket *hb`` the hash_bucket futex_q was original enqueued on ``struct futex_q *q`` the futex_q woken while waiting to be requeued ``struct hrtimer_sleeper *timeout`` the timeout associated with the wait (NULL if none) **Description** Determine the cause for the early wakeup. **Return** -EWOULDBLOCK or -ETIMEDOUT or -ERESTARTNOINTR”h]”(hú)�”}”(hŒ**Parameters**”h]”j)�”}”(hjÎsh]”hŒ Parameters”…”�”}”(hjÐsh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhjÌsubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³Œ_/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1364: ./kernel/futex/requeue.c”h´MÊhjÈsubj")�”}”(hhh]”(j")�”}”(hŒR``struct futex_hash_bucket *hb`` the hash_bucket futex_q was original enqueued on ”h]”(j")�”}”(hŒ ``struct futex_hash_bucket *hb``”h]”jI)�”}”(hjísh]”hŒstruct futex_hash_bucket *hb”…”�”}”(hjïsh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jHhjësubah}”(h]”h ]”h"]”h$]”h&]”uh1j"h³Œ_/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1364: ./kernel/futex/requeue.c”h´MÇhjçsubj5")�”}”(hhh]”hú)�”}”(hŒ0the hash_bucket futex_q was original enqueued on”h]”hŒ0the hash_bucket futex_q was original enqueued on”…”�”}”(hjth²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³jth´MÇhjtubah}”(h]”h ]”h"]”h$]”h&]”uh1j4"hjçsubeh}”(h]”h ]”h"]”h$]”h&]”uh1j"h³jth´MÇhjäsubj")�”}”(hŒE``struct futex_q *q`` the futex_q woken while waiting to be requeued ”h]”(j")�”}”(hŒ``struct futex_q *q``”h]”jI)�”}”(hj&th]”hŒstruct futex_q *q”…”�”}”(hj(th²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jHhj$tubah}”(h]”h ]”h"]”h$]”h&]”uh1j"h³Œ_/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1364: ./kernel/futex/requeue.c”h´MÈhj tubj5")�”}”(hhh]”hú)�”}”(hŒ.the futex_q woken while waiting to be requeued”h]”hŒ.the futex_q woken while waiting to be requeued”…”�”}”(hj?th²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³j;th´MÈhj``u32 __user *uaddr`` the futex we initially wait on (non-pi) ”h]”(j")�”}”(hŒ``u32 __user *uaddr``”h]”jI)�”}”(hj›wh]”hŒu32 __user *uaddr”…”�”}”(hj�wh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jHhj™wubah}”(h]”h ]”h"]”h$]”h&]”uh1j"h³Œ_/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1364: ./kernel/futex/requeue.c”h´Môhj•wubj5")�”}”(hhh]”hú)�”}”(hŒ'the futex we initially wait on (non-pi)”h]”hŒ'the futex we initially wait on (non-pi)”…”�”}”(hj´wh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³j°wh´Môhj±wubah}”(h]”h ]”h"]”h$]”h&]”uh1j4"hj•wubeh}”(h]”h ]”h"]”h$]”h&]”uh1j"h³j°wh´Môhj’wubj")�”}”(hŒ�``unsigned int flags`` futex flags (FLAGS_SHARED, FLAGS_CLOCKRT, etc.), they must be the same type, no requeueing from private to shared, etc. ”h]”(j")�”}”(hŒ``unsigned int flags``”h]”jI)�”}”(hjÔwh]”hŒunsigned int flags”…”�”}”(hjÖwh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jHhjÒwubah}”(h]”h ]”h"]”h$]”h&]”uh1j"h³Œ_/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1364: ./kernel/futex/requeue.c”h´MöhjÎwubj5")�”}”(hhh]”hú)�”}”(hŒwfutex flags (FLAGS_SHARED, FLAGS_CLOCKRT, etc.), they must be the same type, no requeueing from private to shared, etc.”h]”hŒwfutex flags (FLAGS_SHARED, FLAGS_CLOCKRT, etc.), they must be the same type, no requeueing from private to shared, etc.”…”�”}”(hjíwh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³Œ_/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1364: ./kernel/futex/requeue.c”h´Mõhjêwubah}”(h]”h ]”h"]”h$]”h&]”uh1j4"hjÎwubeh}”(h]”h ]”h"]”h$]”h&]”uh1j"h³jéwh´Möhj’wubj")�”}”(hŒ(``u32 val`` the expected value of uaddr ”h]”(j")�”}”(hŒ ``u32 val``”h]”jI)�”}”(hjxh]”hŒu32 val”…”�”}”(hjxh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jHhj xubah}”(h]”h ]”h"]”h$]”h&]”uh1j"h³Œ_/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1364: ./kernel/futex/requeue.c”h´M÷hjxubj5")�”}”(hhh]”hú)�”}”(hŒthe expected value of uaddr”h]”hŒthe expected value of uaddr”…”�”}”(hj'xh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³j#xh´M÷hj$xubah}”(h]”h ]”h"]”h$]”h&]”uh1j4"hjxubeh}”(h]”h ]”h"]”h$]”h&]”uh1j"h³j#xh´M÷hj’wubj")�”}”(hŒ'``ktime_t *abs_time`` absolute timeout ”h]”(j")�”}”(hŒ``ktime_t *abs_time``”h]”jI)�”}”(hjGxh]”hŒktime_t *abs_time”…”�”}”(hjIxh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jHhjExubah}”(h]”h ]”h"]”h$]”h&]”uh1j"h³Œ_/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1364: ./kernel/futex/requeue.c”h´MøhjAxubj5")�”}”(hhh]”hú)�”}”(hŒabsolute timeout”h]”hŒabsolute timeout”…”�”}”(hj`xh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³j\xh´Møhj]xubah}”(h]”h ]”h"]”h$]”h&]”uh1j4"hjAxubeh}”(h]”h ]”h"]”h$]”h&]”uh1j"h³j\xh´Møhj’wubj")�”}”(hŒF``u32 bitset`` 32 bit wakeup bitset set by userspace, defaults to all ”h]”(j")�”}”(hŒ``u32 bitset``”h]”jI)�”}”(hj€xh]”hŒ u32 bitset”…”�”}”(hj‚xh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jHhj~xubah}”(h]”h ]”h"]”h$]”h&]”uh1j"h³Œ_/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1364: ./kernel/futex/requeue.c”h´Mùhjzxubj5")�”}”(hhh]”hú)�”}”(hŒ632 bit wakeup bitset set by userspace, defaults to all”h]”hŒ632 bit wakeup bitset set by userspace, defaults to all”…”�”}”(hj™xh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³j•xh´Mùhj–xubah}”(h]”h ]”h"]”h$]”h&]”uh1j4"hjzxubeh}”(h]”h ]”h"]”h$]”h&]”uh1j"h³j•xh´Mùhj’wubj")�”}”(hŒR``u32 __user *uaddr2`` the pi futex we will take prior to returning to user-space ”h]”(j")�”}”(hŒ``u32 __user *uaddr2``”h]”jI)�”}”(hj¹xh]”hŒu32 __user *uaddr2”…”�”}”(hj»xh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jHhj·xubah}”(h]”h ]”h"]”h$]”h&]”uh1j"h³Œ_/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1364: ./kernel/futex/requeue.c”h´Múhj³xubj5")�”}”(hhh]”hú)�”}”(hŒ:the pi futex we will take prior to returning to user-space”h]”hŒ:the pi futex we will take prior to returning to user-space”…”�”}”(hjÒxh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³jÎxh´MúhjÏxubah}”(h]”h ]”h"]”h$]”h&]”uh1j4"hj³xubeh}”(h]”h ]”h"]”h$]”h&]”uh1j"h³jÎxh´Múhj’wubeh}”(h]”h ]”h"]”h$]”h&]”uh1j"hjvwubhú)�”}”(hŒ**Description**”h]”j)�”}”(hjôxh]”hŒ Description”…”�”}”(hjöxh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhjòxubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³Œ_/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1364: ./kernel/futex/requeue.c”h´Mühjvwubhú)�”}”(hX�The caller will wait on uaddr and will be requeued by futex_requeue() to uaddr2 which must be PI aware and unique from uaddr. Normal wakeup will wake on uaddr2 and complete the acquisition of the rt_mutex prior to returning to userspace. This ensures the rt_mutex maintains an owner when it has waiters; without one, the pi logic would not know which task to boost/deboost, if there was a need to.”h]”hX�The caller will wait on uaddr and will be requeued by futex_requeue() to uaddr2 which must be PI aware and unique from uaddr. Normal wakeup will wake on uaddr2 and complete the acquisition of the rt_mutex prior to returning to userspace. This ensures the rt_mutex maintains an owner when it has waiters; without one, the pi logic would not know which task to boost/deboost, if there was a need to.”…”�”}”(hj yh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³Œ_/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1364: ./kernel/futex/requeue.c”h´Mûhjvwubhú)�”}”(hŒÜWe call schedule in futex_wait_queue() when we enqueue and return there via the following-- 1) wakeup on uaddr2 after an atomic lock acquisition by futex_requeue() 2) wakeup on uaddr2 after a requeue 3) signal 4) timeout”h]”hŒÜWe call schedule in futex_wait_queue() when we enqueue and return there via the following-- 1) wakeup on uaddr2 after an atomic lock acquisition by futex_requeue() 2) wakeup on uaddr2 after a requeue 3) signal 4) timeout”…”�”}”(hjyh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³Œ_/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1364: ./kernel/futex/requeue.c”h´Mhjvwubhú)�”}”(hŒ)If 3, cleanup and return -ERESTARTNOINTR.”h]”hŒ)If 3, cleanup and return -ERESTARTNOINTR.”…”�”}”(hj(yh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³Œ_/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1364: ./kernel/futex/requeue.c”h´M hjvwubhú)�”}”(hŒ�If 2, we may then block on trying to take the rt_mutex and return via: 5) successful lock 6) signal 7) timeout 8) other lock acquisition failure”h]”hŒ�If 2, we may then block on trying to take the rt_mutex and return via: 5) successful lock 6) signal 7) timeout 8) other lock acquisition failure”…”�”}”(hj7yh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³Œ_/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1364: ./kernel/futex/requeue.c”h´M hjvwubhú)�”}”(hŒEIf 6, return -EWOULDBLOCK (restarting the syscall would do the same).”h]”hŒEIf 6, return -EWOULDBLOCK (restarting the syscall would do the same).”…”�”}”(hjFyh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³Œ_/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1364: ./kernel/futex/requeue.c”h´Mhjvwubhú)�”}”(hŒ1If 4 or 7, we cleanup and return with -ETIMEDOUT.”h]”hŒ1If 4 or 7, we cleanup and return with -ETIMEDOUT.”…”�”}”(hjUyh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³Œ_/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1364: ./kernel/futex/requeue.c”h´Mhjvwubhú)�”}”(hŒ **Return**”h]”j)�”}”(hjfyh]”hŒReturn”…”�”}”(hjhyh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhjdyubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³Œ_/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1364: ./kernel/futex/requeue.c”h´Mhjvwubj½ )�”}”(hhh]”(j )�”}”(hŒ0 - On success;”h]”hú)�”}”(hj�yh]”hŒ0 - On success;”…”�”}”(hjƒyh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³Œ_/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1364: ./kernel/futex/requeue.c”h´Mhjyubah}”(h]”h ]”h"]”h$]”h&]”uh1jÁ hj|yubj )�”}”(hŒ <0 - On error”h]”hú)�”}”(hj™yh]”hŒ <0 - On error”…”�”}”(hj›yh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³Œ_/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1364: ./kernel/futex/requeue.c”h´Mhj—yubah}”(h]”h ]”h"]”h$]”h&]”uh1jÁ hj|yubeh}”(h]”h ]”h"]”h$]”h&]”j5 j6 uh1j¼ h³j�yh´Mhjvwubeh}”(h]”h ]”Œ kernelindent”ah"]”h$]”h&]”uh1jñ!hj6h²hh³Nh´NubjR!)�”}”(hhh]”h}”(h]”h ]”h"]”h$]”h&]”Œentries”]”(j^!Œfutex_do_wait (C function)”Œc.futex_do_wait”hNt”auh1jQ!hj6h²hh³Nh´Nubjc!)�”}”(hhh]”(jh!)�”}”(hŒGvoid futex_do_wait (struct futex_q *q, struct hrtimer_sleeper *timeout)”h]”jn!)�”}”(hŒFvoid futex_do_wait(struct futex_q *q, struct hrtimer_sleeper *timeout)”h]”(j$)�”}”(hŒvoid”h]”hŒvoid”…”�”}”(hjÕyh²hh³Nh´Nubah}”(h]”h ]”j$ah"]”h$]”h&]”uh1j$hjÑyh²hh³Œ`/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1367: ./kernel/futex/waitwake.c”h´Mnubj$)�”}”(hŒ ”h]”hŒ ”…”�”}”(hjäyh²hh³Nh´Nubah}”(h]”h ]”j $ah"]”h$]”h&]”uh1j$hjÑyh²hh³jãyh´Mnubjt!)�”}”(hŒ futex_do_wait”h]”jz!)�”}”(hŒ futex_do_wait”h]”hŒ futex_do_wait”…”�”}”(hjöyh²hh³Nh´Nubah}”(h]”h ]”j…!ah"]”h$]”h&]”uh1jy!hjòyubah}”(h]”h ]”(jŒ!j�!eh"]”h$]”h&]”j�jŽuh1js!hjÑyh²hh³jãyh´Mnubj=$)�”}”(hŒ4(struct futex_q *q, struct hrtimer_sleeper *timeout)”h]”(jC$)�”}”(hŒstruct futex_q *q”h]”(jI$)�”}”(hjL$h]”hŒstruct”…”�”}”(hjzh²hh³Nh´Nubah}”(h]”h ]”jU$ah"]”h$]”h&]”uh1jH$hjzubj$)�”}”(hŒ ”h]”hŒ ”…”�”}”(hjzh²hh³Nh´Nubah}”(h]”h ]”j $ah"]”h$]”h&]”uh1j$hjzubh)�”}”(hhh]”jz!)�”}”(hŒfutex_q”h]”hŒfutex_q”…”�”}”(hj0zh²hh³Nh´Nubah}”(h]”h ]”j…!ah"]”h$]”h&]”uh1jy!hj-zubah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”jUŒreftype”j€$Œ reftarget”j2zŒmodname”NŒ classname”Nj„$j‡$)�”}”jŠ$]”j�$)�”}”j€$jøysbŒc.futex_do_wait”†”asbuh1hhjzubj$)�”}”(hŒ ”h]”hŒ ”…”�”}”(hjPzh²hh³Nh´Nubah}”(h]”h ]”j $ah"]”h$]”h&]”uh1j$hjzubj¡$)�”}”(hj¤$h]”hŒ*”…”�”}”(hj^zh²hh³Nh´Nubah}”(h]”h ]”j­$ah"]”h$]”h&]”uh1j $hjzubjz!)�”}”(hj;Gh]”hŒq”…”�”}”(hjkzh²hh³Nh´Nubah}”(h]”h ]”j…!ah"]”h$]”h&]”uh1jy!hjzubeh}”(h]”h ]”h"]”h$]”h&]”Œnoemph”ˆj�jŽuh1jB$hj zubjC$)�”}”(hŒstruct hrtimer_sleeper *timeout”h]”(jI$)�”}”(hjL$h]”hŒstruct”…”�”}”(hjƒzh²hh³Nh´Nubah}”(h]”h ]”jU$ah"]”h$]”h&]”uh1jH$hjzubj$)�”}”(hŒ ”h]”hŒ ”…”�”}”(hj�zh²hh³Nh´Nubah}”(h]”h ]”j $ah"]”h$]”h&]”uh1j$hjzubh)�”}”(hhh]”jz!)�”}”(hŒhrtimer_sleeper”h]”hŒhrtimer_sleeper”…”�”}”(hj¡zh²hh³Nh´Nubah}”(h]”h ]”j…!ah"]”h$]”h&]”uh1jy!hjžzubah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”jUŒreftype”j€$Œ reftarget”j£zŒmodname”NŒ classname”Nj„$j‡$)�”}”jŠ$]”jLzŒc.futex_do_wait”†”asbuh1hhjzubj$)�”}”(hŒ ”h]”hŒ ”…”�”}”(hj¿zh²hh³Nh´Nubah}”(h]”h ]”j $ah"]”h$]”h&]”uh1j$hjzubj¡$)�”}”(hj¤$h]”hŒ*”…”�”}”(hjÍzh²hh³Nh´Nubah}”(h]”h ]”j­$ah"]”h$]”h&]”uh1j $hjzubjz!)�”}”(hŒtimeout”h]”hŒtimeout”…”�”}”(hjÚzh²hh³Nh´Nubah}”(h]”h ]”j…!ah"]”h$]”h&]”uh1jy!hjzubeh}”(h]”h ]”h"]”h$]”h&]”Œnoemph”ˆj�jŽuh1jB$hj zubeh}”(h]”h ]”h"]”h$]”h&]”j�jŽuh1j<$hjÑyh²hh³jãyh´Mnubeh}”(h]”h ]”h"]”h$]”h&]”j�jŽj˜!ˆuh1jm!j™!jš!hjÍyh²hh³jãyh´Mnubah}”(h]”jÈyah ]”(jž!jŸ!eh"]”h$]”h&]”j£!ˆj¤!)j¥!huh1jg!h³jãyh´MnhjÊyh²hubj§!)�”}”(hhh]”hú)�”}”(hŒ#wait for wakeup, timeout, or signal”h]”hŒ#wait for wakeup, timeout, or signal”…”�”}”(hj{h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³Œ`/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1367: ./kernel/futex/waitwake.c”h´Mnhj{h²hubah}”(h]”h ]”h"]”h$]”h&]”uh1j¦!hjÊyh²hh³jãyh´Mnubeh}”(h]”h ]”(jUŒfunction”eh"]”h$]”h&]”j¸!jUj¹!j{jº!j{j»!‰j¼!‰j½!‰uh1jb!h²hhj6h³Nh´Nubjò!)�”}”(hŒž**Parameters** ``struct futex_q *q`` the futex_q to queue up on ``struct hrtimer_sleeper *timeout`` the prepared hrtimer_sleeper, or null for no timeout”h]”(hú)�”}”(hŒ**Parameters**”h]”j)�”}”(hj&{h]”hŒ Parameters”…”�”}”(hj({h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhj${ubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³Œ`/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1367: ./kernel/futex/waitwake.c”h´Mrhj {ubj")�”}”(hhh]”(j")�”}”(hŒ1``struct futex_q *q`` the futex_q to queue up on ”h]”(j")�”}”(hŒ``struct futex_q *q``”h]”jI)�”}”(hjE{h]”hŒstruct futex_q *q”…”�”}”(hjG{h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jHhjC{ubah}”(h]”h ]”h"]”h$]”h&]”uh1j"h³Œ`/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1367: ./kernel/futex/waitwake.c”h´Mohj?{ubj5")�”}”(hhh]”hú)�”}”(hŒthe futex_q to queue up on”h]”hŒthe futex_q to queue up on”…”�”}”(hj^{h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³jZ{h´Mohj[{ubah}”(h]”h ]”h"]”h$]”h&]”uh1j4"hj?{ubeh}”(h]”h ]”h"]”h$]”h&]”uh1j"h³jZ{h´Mohj<{ubj")�”}”(hŒX``struct hrtimer_sleeper *timeout`` the prepared hrtimer_sleeper, or null for no timeout”h]”(j")�”}”(hŒ#``struct hrtimer_sleeper *timeout``”h]”jI)�”}”(hj~{h]”hŒstruct hrtimer_sleeper *timeout”…”�”}”(hj€{h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jHhj|{ubah}”(h]”h ]”h"]”h$]”h&]”uh1j"h³Œ`/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1367: ./kernel/futex/waitwake.c”h´Mqhjx{ubj5")�”}”(hhh]”hú)�”}”(hŒ4the prepared hrtimer_sleeper, or null for no timeout”h]”hŒ4the prepared hrtimer_sleeper, or null for no timeout”…”�”}”(hj—{h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³Œ`/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1367: ./kernel/futex/waitwake.c”h´Mphj”{ubah}”(h]”h ]”h"]”h$]”h&]”uh1j4"hjx{ubeh}”(h]”h ]”h"]”h$]”h&]”uh1j"h³j“{h´Mqhj<{ubeh}”(h]”h ]”h"]”h$]”h&]”uh1j"hj {ubeh}”(h]”h ]”Œ kernelindent”ah"]”h$]”h&]”uh1jñ!hj6h²hh³Nh´NubjR!)�”}”(hhh]”h}”(h]”h ]”h"]”h$]”h&]”Œentries”]”(j^!Œ#futex_unqueue_multiple (C function)”Œc.futex_unqueue_multiple”hNt”auh1jQ!hj6h²hh³Nh´Nubjc!)�”}”(hhh]”(jh!)�”}”(hŒ>int futex_unqueue_multiple (struct futex_vector *v, int count)”h]”jn!)�”}”(hŒ=int futex_unqueue_multiple(struct futex_vector *v, int count)”h]”(j$)�”}”(hŒint”h]”hŒint”…”�”}”(hjØ{h²hh³Nh´Nubah}”(h]”h ]”j$ah"]”h$]”h&]”uh1j$hjÔ{h²hh³Œ`/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1367: ./kernel/futex/waitwake.c”h´M‰ubj$)�”}”(hŒ ”h]”hŒ ”…”�”}”(hjç{h²hh³Nh´Nubah}”(h]”h ]”j $ah"]”h$]”h&]”uh1j$hjÔ{h²hh³jæ{h´M‰ubjt!)�”}”(hŒfutex_unqueue_multiple”h]”jz!)�”}”(hŒfutex_unqueue_multiple”h]”hŒfutex_unqueue_multiple”…”�”}”(hjù{h²hh³Nh´Nubah}”(h]”h ]”j…!ah"]”h$]”h&]”uh1jy!hjõ{ubah}”(h]”h ]”(jŒ!j�!eh"]”h$]”h&]”j�jŽuh1js!hjÔ{h²hh³jæ{h´M‰ubj=$)�”}”(hŒ#(struct futex_vector *v, int count)”h]”(jC$)�”}”(hŒstruct futex_vector *v”h]”(jI$)�”}”(hjL$h]”hŒstruct”…”�”}”(hj|h²hh³Nh´Nubah}”(h]”h ]”jU$ah"]”h$]”h&]”uh1jH$hj|ubj$)�”}”(hŒ ”h]”hŒ ”…”�”}”(hj"|h²hh³Nh´Nubah}”(h]”h ]”j $ah"]”h$]”h&]”uh1j$hj|ubh)�”}”(hhh]”jz!)�”}”(hŒ futex_vector”h]”hŒ futex_vector”…”�”}”(hj3|h²hh³Nh´Nubah}”(h]”h ]”j…!ah"]”h$]”h&]”uh1jy!hj0|ubah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”jUŒreftype”j€$Œ reftarget”j5|Œmodname”NŒ classname”Nj„$j‡$)�”}”jŠ$]”j�$)�”}”j€$jû{sbŒc.futex_unqueue_multiple”†”asbuh1hhj|ubj$)�”}”(hŒ ”h]”hŒ ”…”�”}”(hjS|h²hh³Nh´Nubah}”(h]”h ]”j $ah"]”h$]”h&]”uh1j$hj|ubj¡$)�”}”(hj¤$h]”hŒ*”…”�”}”(hja|h²hh³Nh´Nubah}”(h]”h ]”j­$ah"]”h$]”h&]”uh1j $hj|ubjz!)�”}”(hŒv”h]”hŒv”…”�”}”(hjn|h²hh³Nh´Nubah}”(h]”h ]”j…!ah"]”h$]”h&]”uh1jy!hj|ubeh}”(h]”h ]”h"]”h$]”h&]”Œnoemph”ˆj�jŽuh1jB$hj |ubjC$)�”}”(hŒ int count”h]”(j$)�”}”(hŒint”h]”hŒint”…”�”}”(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ƒ|ubjz!)�”}”(hŒcount”h]”hŒcount”…”�”}”(hj£|h²hh³Nh´Nubah}”(h]”h ]”j…!ah"]”h$]”h&]”uh1jy!hjƒ|ubeh}”(h]”h ]”h"]”h$]”h&]”Œnoemph”ˆj�jŽuh1jB$hj |ubeh}”(h]”h ]”h"]”h$]”h&]”j�jŽuh1j<$hjÔ{h²hh³jæ{h´M‰ubeh}”(h]”h ]”h"]”h$]”h&]”j�jŽj˜!ˆuh1jm!j™!jš!hjÐ{h²hh³jæ{h´M‰ubah}”(h]”jË{ah ]”(jž!jŸ!eh"]”h$]”h&]”j£!ˆj¤!)j¥!huh1jg!h³jæ{h´M‰hjÍ{h²hubj§!)�”}”(hhh]”hú)�”}”(hŒ-Remove various futexes from their hash bucket”h]”hŒ-Remove various futexes from their hash bucket”…”�”}”(hjÍ|h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³Œ`/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1367: ./kernel/futex/waitwake.c”h´M‰hjÊ|h²hubah}”(h]”h ]”h"]”h$]”h&]”uh1j¦!hjÍ{h²hh³jæ{h´M‰ubeh}”(h]”h ]”(jUŒfunction”eh"]”h$]”h&]”j¸!jUj¹!jå|jº!jå|j»!‰j¼!‰j½!‰uh1jb!h²hhj6h³Nh´Nubjò!)�”}”(hX**Parameters** ``struct futex_vector *v`` The list of futexes to unqueue ``int count`` Number of futexes in the list **Description** Helper to unqueue a list of futexes. This can't fail. **Return** - >=0 - Index of the last futex that was awoken; - -1 - No futex was awoken”h]”(hú)�”}”(hŒ**Parameters**”h]”j)�”}”(hjï|h]”hŒ Parameters”…”�”}”(hjñ|h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhjí|ubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³Œ`/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1367: ./kernel/futex/waitwake.c”h´M�hjé|ubj")�”}”(hhh]”(j")�”}”(hŒ:``struct futex_vector *v`` The list of futexes to unqueue ”h]”(j")�”}”(hŒ``struct futex_vector *v``”h]”jI)�”}”(hj}h]”hŒstruct futex_vector *v”…”�”}”(hj}h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jHhj }ubah}”(h]”h ]”h"]”h$]”h&]”uh1j"h³Œ`/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1367: ./kernel/futex/waitwake.c”h´MŠhj}ubj5")�”}”(hhh]”hú)�”}”(hŒThe list of futexes to unqueue”h]”hŒThe list of futexes to unqueue”…”�”}”(hj'}h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³j#}h´MŠhj$}ubah}”(h]”h ]”h"]”h$]”h&]”uh1j4"hj}ubeh}”(h]”h ]”h"]”h$]”h&]”uh1j"h³j#}h´MŠhj}ubj")�”}”(hŒ,``int count`` Number of futexes in the list ”h]”(j")�”}”(hŒ ``int count``”h]”jI)�”}”(hjG}h]”hŒ int count”…”�”}”(hjI}h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jHhjE}ubah}”(h]”h ]”h"]”h$]”h&]”uh1j"h³Œ`/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1367: ./kernel/futex/waitwake.c”h´M‹hjA}ubj5")�”}”(hhh]”hú)�”}”(hŒNumber of futexes in the list”h]”hŒNumber of futexes in the list”…”�”}”(hj`}h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³j\}h´M‹hj]}ubah}”(h]”h ]”h"]”h$]”h&]”uh1j4"hjA}ubeh}”(h]”h ]”h"]”h$]”h&]”uh1j"h³j\}h´M‹hj}ubeh}”(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&]”uh1jhj€}ubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³Œ`/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1367: ./kernel/futex/waitwake.c”h´M�hjé|ubhú)�”}”(hŒ5Helper to unqueue a list of futexes. This can't fail.”h]”hŒ7Helper to unqueue a list of futexes. This can’t fail.”…”�”}”(hj˜}h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³Œ`/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1367: ./kernel/futex/waitwake.c”h´MŒhjé|ubhú)�”}”(hŒ **Return**”h]”j)�”}”(hj©}h]”hŒReturn”…”�”}”(hj«}h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhj§}ubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³Œ`/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1367: ./kernel/futex/waitwake.c”h´MŽhjé|ubj½ )�”}”(hhh]”(j )�”}”(hŒ.>=0 - Index of the last futex that was awoken;”h]”hú)�”}”(hjÄ}h]”hŒ.>=0 - Index of the last futex that was awoken;”…”�”}”(hjÆ}h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³Œ`/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1367: ./kernel/futex/waitwake.c”h´M�hjÂ}ubah}”(h]”h ]”h"]”h$]”h&]”uh1jÁ hj¿}ubj )�”}”(hŒ-1 - No futex was awoken”h]”hŒ option_list”“”)�”}”(hhh]”hŒoption_list_item”“”)�”}”(hhh]”(hŒ option_group”“”)�”}”(hhh]”hŒoption”“”)�”}”(hŒ-1”h]”hŒ option_string”“”)�”}”(hjñ}h]”hŒ-1”…”�”}”hjõ}sbah}”(h]”h ]”h"]”h$]”h&]”uh1jó}hjï}ubah}”(h]”h ]”h"]”h$]”h&]”uh1jí}hjê}ubah}”(h]”h ]”h"]”h$]”h&]”uh1jè}hjå}ubhŒ description”“”)�”}”(hŒ- No futex was awoken”h]”j½ )�”}”(hhh]”j )�”}”(hŒNo futex was awoken”h]”hú)�”}”(hj~h]”hŒNo futex was awoken”…”�”}”(hj~h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³Œ`/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1367: ./kernel/futex/waitwake.c”h´M�hj~ubah}”(h]”h ]”h"]”h$]”h&]”uh1jÁ hj~ubah}”(h]”h ]”h"]”h$]”h&]”j5 j6 uh1j¼ h³j(~h´M�hj~ubah}”(h]”h ]”h"]”h$]”h&]”uh1j~hjå}ubeh}”(h]”h ]”h"]”h$]”h&]”uh1jã}hjà}ubah}”(h]”h ]”h"]”h$]”h&]”uh1jÞ}h³j(~h´M�hjÚ}ubah}”(h]”h ]”h"]”h$]”h&]”uh1jÁ hj¿}ubeh}”(h]”h ]”h"]”h$]”h&]”j5 j6 uh1j¼ h³jÓ}h´M�hjé|ubeh}”(h]”h ]”Œ kernelindent”ah"]”h$]”h&]”uh1jñ!hj6h²hh³Nh´NubjR!)�”}”(hhh]”h}”(h]”h ]”h"]”h$]”h&]”Œentries”]”(j^!Œ&futex_wait_multiple_setup (C function)”Œc.futex_wait_multiple_setup”hNt”auh1jQ!hj6h²hh³Nh´Nubjc!)�”}”(hhh]”(jh!)�”}”(hŒNint futex_wait_multiple_setup (struct futex_vector *vs, int count, int *woken)”h]”jn!)�”}”(hŒMint futex_wait_multiple_setup(struct futex_vector *vs, int count, int *woken)”h]”(j$)�”}”(hŒint”h]”hŒint”…”�”}”(hjs~h²hh³Nh´Nubah}”(h]”h ]”j$ah"]”h$]”h&]”uh1j$hjo~h²hh³Œ`/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1367: ./kernel/futex/waitwake.c”h´M ubj$)�”}”(hŒ ”h]”hŒ ”…”�”}”(hj‚~h²hh³Nh´Nubah}”(h]”h ]”j $ah"]”h$]”h&]”uh1j$hjo~h²hh³j�~h´M ubjt!)�”}”(hŒfutex_wait_multiple_setup”h]”jz!)�”}”(hŒfutex_wait_multiple_setup”h]”hŒfutex_wait_multiple_setup”…”�”}”(hj”~h²hh³Nh´Nubah}”(h]”h ]”j…!ah"]”h$]”h&]”uh1jy!hj�~ubah}”(h]”h ]”(jŒ!j�!eh"]”h$]”h&]”j�jŽuh1js!hjo~h²hh³j�~h´M ubj=$)�”}”(hŒ0(struct futex_vector *vs, int count, int *woken)”h]”(jC$)�”}”(hŒstruct futex_vector *vs”h]”(jI$)�”}”(hjL$h]”hŒstruct”…”�”}”(hj°~h²hh³Nh´Nubah}”(h]”h ]”jU$ah"]”h$]”h&]”uh1jH$hj¬~ubj$)�”}”(hŒ ”h]”hŒ ”…”�”}”(hj½~h²hh³Nh´Nubah}”(h]”h ]”j $ah"]”h$]”h&]”uh1j$hj¬~ubh)�”}”(hhh]”jz!)�”}”(hŒ futex_vector”h]”hŒ futex_vector”…”�”}”(hjÎ~h²hh³Nh´Nubah}”(h]”h ]”j…!ah"]”h$]”h&]”uh1jy!hjË~ubah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”jUŒreftype”j€$Œ reftarget”jÐ~Œmodname”NŒ classname”Nj„$j‡$)�”}”jŠ$]”j�$)�”}”j€$j–~sbŒc.futex_wait_multiple_setup”†”asbuh1hhj¬~ubj$)�”}”(hŒ ”h]”hŒ ”…”�”}”(hjî~h²hh³Nh´Nubah}”(h]”h ]”j $ah"]”h$]”h&]”uh1j$hj¬~ubj¡$)�”}”(hj¤$h]”hŒ*”…”�”}”(hjü~h²hh³Nh´Nubah}”(h]”h ]”j­$ah"]”h$]”h&]”uh1j $hj¬~ubjz!)�”}”(hŒvs”h]”hŒvs”…”�”}”(hj h²hh³Nh´Nubah}”(h]”h ]”j…!ah"]”h$]”h&]”uh1jy!hj¬~ubeh}”(h]”h ]”h"]”h$]”h&]”Œnoemph”ˆj�jŽuh1jB$hj¨~ubjC$)�”}”(hŒ int count”h]”(j$)�”}”(hŒint”h]”hŒint”…”�”}”(hj"h²hh³Nh´Nubah}”(h]”h ]”j$ah"]”h$]”h&]”uh1j$hjubj$)�”}”(hŒ ”h]”hŒ ”…”�”}”(hj0h²hh³Nh´Nubah}”(h]”h ]”j $ah"]”h$]”h&]”uh1j$hjubjz!)�”}”(hŒcount”h]”hŒcount”…”�”}”(hj>h²hh³Nh´Nubah}”(h]”h ]”j…!ah"]”h$]”h&]”uh1jy!hjubeh}”(h]”h ]”h"]”h$]”h&]”Œnoemph”ˆj�jŽuh1jB$hj¨~ubjC$)�”}”(hŒ int *woken”h]”(j$)�”}”(hŒint”h]”hŒint”…”�”}”(hjWh²hh³Nh´Nubah}”(h]”h ]”j$ah"]”h$]”h&]”uh1j$hjSubj$)�”}”(hŒ ”h]”hŒ ”…”�”}”(hjeh²hh³Nh´Nubah}”(h]”h ]”j $ah"]”h$]”h&]”uh1j$hjSubj¡$)�”}”(hj¤$h]”hŒ*”…”�”}”(hjsh²hh³Nh´Nubah}”(h]”h ]”j­$ah"]”h$]”h&]”uh1j $hjSubjz!)�”}”(hŒwoken”h]”hŒwoken”…”�”}”(hj€h²hh³Nh´Nubah}”(h]”h ]”j…!ah"]”h$]”h&]”uh1jy!hjSubeh}”(h]”h ]”h"]”h$]”h&]”Œnoemph”ˆj�jŽuh1jB$hj¨~ubeh}”(h]”h ]”h"]”h$]”h&]”j�jŽuh1j<$hjo~h²hh³j�~h´M ubeh}”(h]”h ]”h"]”h$]”h&]”j�jŽj˜!ˆuh1jm!j™!jš!hjk~h²hh³j�~h´M ubah}”(h]”jf~ah ]”(jž!jŸ!eh"]”h$]”h&]”j£!ˆj¤!)j¥!huh1jg!h³j�~h´M hjh~h²hubj§!)�”}”(hhh]”hú)�”}”(hŒ,Prepare to wait and enqueue multiple futexes”h]”hŒ,Prepare to wait and enqueue multiple futexes”…”�”}”(hjªh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³Œ`/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1367: ./kernel/futex/waitwake.c”h´M hj§h²hubah}”(h]”h ]”h"]”h$]”h&]”uh1j¦!hjh~h²hh³j�~h´M ubeh}”(h]”h ]”(jUŒfunction”eh"]”h$]”h&]”j¸!jUj¹!jÂjº!jÂj»!‰j¼!‰j½!‰uh1jb!h²hhj6h³Nh´Nubjò!)�”}”(hXL**Parameters** ``struct futex_vector *vs`` The futex list to wait on ``int count`` The size of the list ``int *woken`` Index of the last woken futex, if any. Used to notify the caller that it can return this index to userspace (return parameter) **Description** Prepare multiple futexes in a single step and enqueue them. This may fail if the futex list is invalid or if any futex was already awoken. On success the task is ready to interruptible sleep. **Return** - 1 - One of the futexes was woken by another thread - 0 - Success - <0 - -EFAULT, -EWOULDBLOCK or -EINVAL”h]”(hú)�”}”(hŒ**Parameters**”h]”j)�”}”(hjÌh]”hŒ Parameters”…”�”}”(hjÎh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhjÊubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³Œ`/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1367: ./kernel/futex/waitwake.c”h´M¤hjÆubj")�”}”(hhh]”(j")�”}”(hŒ6``struct futex_vector *vs`` The futex list to wait on ”h]”(j")�”}”(hŒ``struct futex_vector *vs``”h]”jI)�”}”(hjëh]”hŒstruct futex_vector *vs”…”�”}”(hjíh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jHhjéubah}”(h]”h ]”h"]”h$]”h&]”uh1j"h³Œ`/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1367: ./kernel/futex/waitwake.c”h´M¡hjåubj5")�”}”(hhh]”hú)�”}”(hŒThe futex list to wait on”h]”hŒThe futex list to wait on”…”�”}”(hj€h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³j€h´M¡hj€ubah}”(h]”h ]”h"]”h$]”h&]”uh1j4"hjåubeh}”(h]”h ]”h"]”h$]”h&]”uh1j"h³j€h´M¡hjâubj")�”}”(hŒ#``int count`` The size of the list ”h]”(j")�”}”(hŒ ``int count``”h]”jI)�”}”(hj$€h]”hŒ int count”…”�”}”(hj&€h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jHhj"€ubah}”(h]”h ]”h"]”h$]”h&]”uh1j"h³Œ`/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1367: ./kernel/futex/waitwake.c”h´M¢hj€ubj5")�”}”(hhh]”hú)�”}”(hŒThe size of the list”h]”hŒThe size of the list”…”�”}”(hj=€h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³j9€h´M¢hj:€ubah}”(h]”h ]”h"]”h$]”h&]”uh1j4"hj€ubeh}”(h]”h ]”h"]”h$]”h&]”uh1j"h³j9€h´M¢hjâubj")�”}”(hŒŽ``int *woken`` Index of the last woken futex, if any. Used to notify the caller that it can return this index to userspace (return parameter) ”h]”(j")�”}”(hŒ``int *woken``”h]”jI)�”}”(hj]€h]”hŒ int *woken”…”�”}”(hj_€h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jHhj[€ubah}”(h]”h ]”h"]”h$]”h&]”uh1j"h³Œ`/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1367: ./kernel/futex/waitwake.c”h´M¤hjW€ubj5")�”}”(hhh]”hú)�”}”(hŒ~Index of the last woken futex, if any. Used to notify the caller that it can return this index to userspace (return parameter)”h]”hŒ~Index of the last woken futex, if any. Used to notify the caller that it can return this index to userspace (return parameter)”…”�”}”(hjv€h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³Œ`/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1367: ./kernel/futex/waitwake.c”h´M£hjs€ubah}”(h]”h ]”h"]”h$]”h&]”uh1j4"hjW€ubeh}”(h]”h ]”h"]”h$]”h&]”uh1j"h³jr€h´M¤hjâubeh}”(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&]”uh1jhj—€ubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³Œ`/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1367: ./kernel/futex/waitwake.c”h´M¦hjÆubhú)�”}”(hŒ¿Prepare multiple futexes in a single step and enqueue them. This may fail if the futex list is invalid or if any futex was already awoken. On success the task is ready to interruptible sleep.”h]”hŒ¿Prepare multiple futexes in a single step and enqueue them. This may fail if the futex list is invalid or if any futex was already awoken. On success the task is ready to interruptible sleep.”…”�”}”(hj¯€h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³Œ`/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1367: ./kernel/futex/waitwake.c”h´M¥hjÆubhú)�”}”(hŒ **Return**”h]”j)�”}”(hjÀ€h]”hŒReturn”…”�”}”(hj€h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhj¾€ubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³Œ`/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1367: ./kernel/futex/waitwake.c”h´M©hjÆubj½ )�”}”(hhh]”(j )�”}”(hŒ21 - One of the futexes was woken by another thread”h]”hú)�”}”(hjÛ€h]”hŒ21 - One of the futexes was woken by another thread”…”�”}”(hjÝ€h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³Œ`/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1367: ./kernel/futex/waitwake.c”h´MªhjÙ€ubah}”(h]”h ]”h"]”h$]”h&]”uh1jÁ hjÖ€ubj )�”}”(hŒ 0 - Success”h]”hú)�”}”(hjó€h]”hŒ 0 - Success”…”�”}”(hjõ€h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³Œ`/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1367: ./kernel/futex/waitwake.c”h´M«hjñ€ubah}”(h]”h ]”h"]”h$]”h&]”uh1jÁ hjÖ€ubj )�”}”(hŒ%<0 - -EFAULT, -EWOULDBLOCK or -EINVAL”h]”hú)�”}”(hj �h]”hŒ%<0 - -EFAULT, -EWOULDBLOCK or -EINVAL”…”�”}”(hj �h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³Œ`/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1367: ./kernel/futex/waitwake.c”h´M¬hj �ubah}”(h]”h ]”h"]”h$]”h&]”uh1jÁ hjÖ€ubeh}”(h]”h ]”h"]”h$]”h&]”j5 j6 uh1j¼ h³jê€h´MªhjÆubeh}”(h]”h ]”Œ kernelindent”ah"]”h$]”h&]”uh1jñ!hj6h²hh³Nh´NubjR!)�”}”(hhh]”h}”(h]”h ]”h"]”h$]”h&]”Œentries”]”(j^!Œ!futex_sleep_multiple (C function)”Œc.futex_sleep_multiple”hNt”auh1jQ!hj6h²hh³Nh´Nubjc!)�”}”(hhh]”(jh!)�”}”(hŒcvoid futex_sleep_multiple (struct futex_vector *vs, unsigned int count, struct hrtimer_sleeper *to)”h]”jn!)�”}”(hŒbvoid futex_sleep_multiple(struct futex_vector *vs, unsigned int count, struct hrtimer_sleeper *to)”h]”(j$)�”}”(hŒvoid”h]”hŒvoid”…”�”}”(hjG�h²hh³Nh´Nubah}”(h]”h ]”j$ah"]”h$]”h&]”uh1j$hjC�h²hh³Œ`/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1367: ./kernel/futex/waitwake.c”h´Mubj$)�”}”(hŒ ”h]”hŒ ”…”�”}”(hjV�h²hh³Nh´Nubah}”(h]”h ]”j $ah"]”h$]”h&]”uh1j$hjC�h²hh³jU�h´Mubjt!)�”}”(hŒfutex_sleep_multiple”h]”jz!)�”}”(hŒfutex_sleep_multiple”h]”hŒfutex_sleep_multiple”…”�”}”(hjh�h²hh³Nh´Nubah}”(h]”h ]”j…!ah"]”h$]”h&]”uh1jy!hjd�ubah}”(h]”h ]”(jŒ!j�!eh"]”h$]”h&]”j�jŽuh1js!hjC�h²hh³jU�h´Mubj=$)�”}”(hŒI(struct futex_vector *vs, unsigned int count, struct hrtimer_sleeper *to)”h]”(jC$)�”}”(hŒstruct futex_vector *vs”h]”(jI$)�”}”(hjL$h]”hŒstruct”…”�”}”(hj„�h²hh³Nh´Nubah}”(h]”h ]”jU$ah"]”h$]”h&]”uh1jH$hj€�ubj$)�”}”(hŒ ”h]”hŒ ”…”�”}”(hj‘�h²hh³Nh´Nubah}”(h]”h ]”j $ah"]”h$]”h&]”uh1j$hj€�ubh)�”}”(hhh]”jz!)�”}”(hŒ futex_vector”h]”hŒ futex_vector”…”�”}”(hj¢�h²hh³Nh´Nubah}”(h]”h ]”j…!ah"]”h$]”h&]”uh1jy!hjŸ�ubah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”jUŒreftype”j€$Œ reftarget”j¤�Œmodname”NŒ classname”Nj„$j‡$)�”}”jŠ$]”j�$)�”}”j€$jj�sbŒc.futex_sleep_multiple”†”asbuh1hhj€�ubj$)�”}”(hŒ ”h]”hŒ ”…”�”}”(hjÂ�h²hh³Nh´Nubah}”(h]”h ]”j $ah"]”h$]”h&]”uh1j$hj€�ubj¡$)�”}”(hj¤$h]”hŒ*”…”�”}”(hjÐ�h²hh³Nh´Nubah}”(h]”h ]”j­$ah"]”h$]”h&]”uh1j $hj€�ubjz!)�”}”(hŒvs”h]”hŒvs”…”�”}”(hjÝ�h²hh³Nh´Nubah}”(h]”h ]”j…!ah"]”h$]”h&]”uh1jy!hj€�ubeh}”(h]”h ]”h"]”h$]”h&]”Œnoemph”ˆj�jŽuh1jB$hj|�ubjC$)�”}”(hŒunsigned int count”h]”(j$)�”}”(hŒunsigned”h]”hŒunsigned”…”�”}”(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ò�ubj$)�”}”(hŒint”h]”hŒint”…”�”}”(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ò�ubjz!)�”}”(hŒcount”h]”hŒcount”…”�”}”(hj.‚h²hh³Nh´Nubah}”(h]”h ]”j…!ah"]”h$]”h&]”uh1jy!hjò�ubeh}”(h]”h ]”h"]”h$]”h&]”Œnoemph”ˆj�jŽuh1jB$hj|�ubjC$)�”}”(hŒstruct hrtimer_sleeper *to”h]”(jI$)�”}”(hjL$h]”hŒstruct”…”�”}”(hjG‚h²hh³Nh´Nubah}”(h]”h ]”jU$ah"]”h$]”h&]”uh1jH$hjC‚ubj$)�”}”(hŒ ”h]”hŒ ”…”�”}”(hjT‚h²hh³Nh´Nubah}”(h]”h ]”j $ah"]”h$]”h&]”uh1j$hjC‚ubh)�”}”(hhh]”jz!)�”}”(hŒhrtimer_sleeper”h]”hŒhrtimer_sleeper”…”�”}”(hje‚h²hh³Nh´Nubah}”(h]”h ]”j…!ah"]”h$]”h&]”uh1jy!hjb‚ubah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”jUŒreftype”j€$Œ reftarget”jg‚Œmodname”NŒ classname”Nj„$j‡$)�”}”jŠ$]”j¾�Œc.futex_sleep_multiple”†”asbuh1hhjC‚ubj$)�”}”(hŒ ”h]”hŒ ”…”�”}”(hjƒ‚h²hh³Nh´Nubah}”(h]”h ]”j $ah"]”h$]”h&]”uh1j$hjC‚ubj¡$)�”}”(hj¤$h]”hŒ*”…”�”}”(hj‘‚h²hh³Nh´Nubah}”(h]”h ]”j­$ah"]”h$]”h&]”uh1j $hjC‚ubjz!)�”}”(hŒto”h]”hŒto”…”�”}”(hjž‚h²hh³Nh´Nubah}”(h]”h ]”j…!ah"]”h$]”h&]”uh1jy!hjC‚ubeh}”(h]”h ]”h"]”h$]”h&]”Œnoemph”ˆj�jŽuh1jB$hj|�ubeh}”(h]”h ]”h"]”h$]”h&]”j�jŽuh1j<$hjC�h²hh³jU�h´Mubeh}”(h]”h ]”h"]”h$]”h&]”j�jŽj˜!ˆuh1jm!j™!jš!hj?�h²hh³jU�h´Mubah}”(h]”j:�ah ]”(jž!jŸ!eh"]”h$]”h&]”j£!ˆj¤!)j¥!huh1jg!h³jU�h´Mhj<�h²hubj§!)�”}”(hhh]”hú)�”}”(hŒ#Check sleeping conditions and sleep”h]”hŒ#Check sleeping conditions and sleep”…”�”}”(hjÈ‚h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³Œ`/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1367: ./kernel/futex/waitwake.c”h´MhjÅ‚h²hubah}”(h]”h ]”h"]”h$]”h&]”uh1j¦!hj<�h²hh³jU�h´Mubeh}”(h]”h ]”(jUŒfunction”eh"]”h$]”h&]”j¸!jUj¹!jà‚jº!jà‚j»!‰j¼!‰j½!‰uh1jb!h²hhj6h³Nh´Nubjò!)�”}”(hX**Parameters** ``struct futex_vector *vs`` List of futexes to wait for ``unsigned int count`` Length of vs ``struct hrtimer_sleeper *to`` Timeout **Description** Sleep if and only if the timeout hasn't expired and no futex on the list has been woken up.”h]”(hú)�”}”(hŒ**Parameters**”h]”j)�”}”(hjê‚h]”hŒ Parameters”…”�”}”(hjì‚h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhjè‚ubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³Œ`/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1367: ./kernel/futex/waitwake.c”h´Mhjä‚ubj")�”}”(hhh]”(j")�”}”(hŒ8``struct futex_vector *vs`` List of futexes to wait for ”h]”(j")�”}”(hŒ``struct futex_vector *vs``”h]”jI)�”}”(hj ƒh]”hŒstruct futex_vector *vs”…”�”}”(hj ƒh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jHhjƒubah}”(h]”h ]”h"]”h$]”h&]”uh1j"h³Œ`/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1367: ./kernel/futex/waitwake.c”h´Mhjƒubj5")�”}”(hhh]”hú)�”}”(hŒList of futexes to wait for”h]”hŒList of futexes to wait for”…”�”}”(hj"ƒh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³jƒh´Mhjƒubah}”(h]”h ]”h"]”h$]”h&]”uh1j4"hjƒubeh}”(h]”h ]”h"]”h$]”h&]”uh1j"h³jƒh´Mhjƒubj")�”}”(hŒ$``unsigned int count`` Length of vs ”h]”(j")�”}”(hŒ``unsigned int count``”h]”jI)�”}”(hjBƒh]”hŒunsigned int count”…”�”}”(hjDƒh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jHhj@ƒubah}”(h]”h ]”h"]”h$]”h&]”uh1j"h³Œ`/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1367: ./kernel/futex/waitwake.c”h´Mhj<ƒubj5")�”}”(hhh]”hú)�”}”(hŒ Length of vs”h]”hŒ Length of vs”…”�”}”(hj[ƒh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³jWƒh´MhjXƒubah}”(h]”h ]”h"]”h$]”h&]”uh1j4"hj<ƒubeh}”(h]”h ]”h"]”h$]”h&]”uh1j"h³jWƒh´Mhjƒubj")�”}”(hŒ'``struct hrtimer_sleeper *to`` Timeout ”h]”(j")�”}”(hŒ``struct hrtimer_sleeper *to``”h]”jI)�”}”(hj{ƒh]”hŒstruct hrtimer_sleeper *to”…”�”}”(hj}ƒh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jHhjyƒubah}”(h]”h ]”h"]”h$]”h&]”uh1j"h³Œ`/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1367: ./kernel/futex/waitwake.c”h´Mhjuƒubj5")�”}”(hhh]”hú)�”}”(hŒTimeout”h]”hŒTimeout”…”�”}”(hj”ƒh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³j�ƒh´Mhj‘ƒubah}”(h]”h ]”h"]”h$]”h&]”uh1j4"hjuƒubeh}”(h]”h ]”h"]”h$]”h&]”uh1j"h³j�ƒh´Mhjƒubeh}”(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&]”uh1jhj´ƒubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³Œ`/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1367: ./kernel/futex/waitwake.c”h´Mhjä‚ubhú)�”}”(hŒ[Sleep if and only if the timeout hasn't expired and no futex on the list has been woken up.”h]”hŒ]Sleep if and only if the timeout hasn’t expired and no futex on the list has been woken up.”…”�”}”(hj̃h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³Œ`/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1367: ./kernel/futex/waitwake.c”h´Mhjä‚ubeh}”(h]”h ]”Œ kernelindent”ah"]”h$]”h&]”uh1jñ!hj6h²hh³Nh´NubjR!)�”}”(hhh]”h}”(h]”h ]”h"]”h$]”h&]”Œentries”]”(j^!Œ futex_wait_multiple (C function)”Œc.futex_wait_multiple”hNt”auh1jQ!hj6h²hh³Nh´Nubjc!)�”}”(hhh]”(jh!)�”}”(hŒaint futex_wait_multiple (struct futex_vector *vs, unsigned int count, struct hrtimer_sleeper *to)”h]”jn!)�”}”(hŒ`int futex_wait_multiple(struct futex_vector *vs, unsigned int count, struct hrtimer_sleeper *to)”h]”(j$)�”}”(hŒint”h]”hŒint”…”�”}”(hjûƒh²hh³Nh´Nubah}”(h]”h ]”j$ah"]”h$]”h&]”uh1j$hj÷ƒh²hh³Œ`/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1367: ./kernel/futex/waitwake.c”h´M*ubj$)�”}”(hŒ ”h]”hŒ ”…”�”}”(hj „h²hh³Nh´Nubah}”(h]”h ]”j $ah"]”h$]”h&]”uh1j$hj÷ƒh²hh³j „h´M*ubjt!)�”}”(hŒfutex_wait_multiple”h]”jz!)�”}”(hŒfutex_wait_multiple”h]”hŒfutex_wait_multiple”…”�”}”(hj„h²hh³Nh´Nubah}”(h]”h ]”j…!ah"]”h$]”h&]”uh1jy!hj„ubah}”(h]”h ]”(jŒ!j�!eh"]”h$]”h&]”j�jŽuh1js!hj÷ƒh²hh³j „h´M*ubj=$)�”}”(hŒI(struct futex_vector *vs, unsigned int count, struct hrtimer_sleeper *to)”h]”(jC$)�”}”(hŒstruct futex_vector *vs”•.¤h]”(jI$)�”}”(hjL$h]”hŒstruct”…”�”}”(hj8„h²hh³Nh´Nubah}”(h]”h ]”jU$ah"]”h$]”h&]”uh1jH$hj4„ubj$)�”}”(hŒ ”h]”hŒ ”…”�”}”(hjE„h²hh³Nh´Nubah}”(h]”h ]”j $ah"]”h$]”h&]”uh1j$hj4„ubh)�”}”(hhh]”jz!)�”}”(hŒ futex_vector”h]”hŒ futex_vector”…”�”}”(hjV„h²hh³Nh´Nubah}”(h]”h ]”j…!ah"]”h$]”h&]”uh1jy!hjS„ubah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”jUŒreftype”j€$Œ reftarget”jX„Œmodname”NŒ classname”Nj„$j‡$)�”}”jŠ$]”j�$)�”}”j€$j„sbŒc.futex_wait_multiple”†”asbuh1hhj4„ubj$)�”}”(hŒ ”h]”hŒ ”…”�”}”(hjv„h²hh³Nh´Nubah}”(h]”h ]”j $ah"]”h$]”h&]”uh1j$hj4„ubj¡$)�”}”(hj¤$h]”hŒ*”…”�”}”(hj„„h²hh³Nh´Nubah}”(h]”h ]”j­$ah"]”h$]”h&]”uh1j $hj4„ubjz!)�”}”(hŒvs”h]”hŒvs”…”�”}”(hj‘„h²hh³Nh´Nubah}”(h]”h ]”j…!ah"]”h$]”h&]”uh1jy!hj4„ubeh}”(h]”h ]”h"]”h$]”h&]”Œnoemph”ˆj�jŽuh1jB$hj0„ubjC$)�”}”(hŒunsigned int count”h]”(j$)�”}”(hŒunsigned”h]”hŒunsigned”…”�”}”(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¦„ubj$)�”}”(hŒint”h]”hŒint”…”�”}”(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¦„ubjz!)�”}”(hŒcount”h]”hŒcount”…”�”}”(hjâ„h²hh³Nh´Nubah}”(h]”h ]”j…!ah"]”h$]”h&]”uh1jy!hj¦„ubeh}”(h]”h ]”h"]”h$]”h&]”Œnoemph”ˆj�jŽuh1jB$hj0„ubjC$)�”}”(hŒstruct hrtimer_sleeper *to”h]”(jI$)�”}”(hjL$h]”hŒstruct”…”�”}”(hjû„h²hh³Nh´Nubah}”(h]”h ]”jU$ah"]”h$]”h&]”uh1jH$hj÷„ubj$)�”}”(hŒ ”h]”hŒ ”…”�”}”(hj…h²hh³Nh´Nubah}”(h]”h ]”j $ah"]”h$]”h&]”uh1j$hj÷„ubh)�”}”(hhh]”jz!)�”}”(hŒhrtimer_sleeper”h]”hŒhrtimer_sleeper”…”�”}”(hj…h²hh³Nh´Nubah}”(h]”h ]”j…!ah"]”h$]”h&]”uh1jy!hj…ubah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”jUŒreftype”j€$Œ reftarget”j…Œmodname”NŒ classname”Nj„$j‡$)�”}”jŠ$]”jr„Œc.futex_wait_multiple”†”asbuh1hhj÷„ubj$)�”}”(hŒ ”h]”hŒ ”…”�”}”(hj7…h²hh³Nh´Nubah}”(h]”h ]”j $ah"]”h$]”h&]”uh1j$hj÷„ubj¡$)�”}”(hj¤$h]”hŒ*”…”�”}”(hjE…h²hh³Nh´Nubah}”(h]”h ]”j­$ah"]”h$]”h&]”uh1j $hj÷„ubjz!)�”}”(hŒto”h]”hŒto”…”�”}”(hjR…h²hh³Nh´Nubah}”(h]”h ]”j…!ah"]”h$]”h&]”uh1jy!hj÷„ubeh}”(h]”h ]”h"]”h$]”h&]”Œnoemph”ˆj�jŽuh1jB$hj0„ubeh}”(h]”h ]”h"]”h$]”h&]”j�jŽuh1j<$hj÷ƒh²hh³j „h´M*ubeh}”(h]”h ]”h"]”h$]”h&]”j�jŽj˜!ˆuh1jm!j™!jš!hjóƒh²hh³j „h´M*ubah}”(h]”jîƒah ]”(jž!jŸ!eh"]”h$]”h&]”j£!ˆj¤!)j¥!huh1jg!h³j „h´M*hjðƒh²hubj§!)�”}”(hhh]”hú)�”}”(hŒ.Prepare to wait on and enqueue several futexes”h]”hŒ.Prepare to wait on and enqueue several futexes”…”�”}”(hj|…h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³Œ`/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1367: ./kernel/futex/waitwake.c”h´M*hjy…h²hubah}”(h]”h ]”h"]”h$]”h&]”uh1j¦!hjðƒh²hh³j „h´M*ubeh}”(h]”h ]”(jUŒfunction”eh"]”h$]”h&]”j¸!jUj¹!j”…jº!j”…j»!‰j¼!‰j½!‰uh1jb!h²hhj6h³Nh´Nubjò!)�”}”(hXß**Parameters** ``struct futex_vector *vs`` The list of futexes to wait on ``unsigned int count`` The number of objects ``struct hrtimer_sleeper *to`` Timeout before giving up and returning to userspace **Description** Entry point for the FUTEX_WAIT_MULTIPLE futex operation, this function sleeps on a group of futexes and returns on the first futex that is wake, or after the timeout has elapsed. **Return** - >=0 - Hint to the futex that was awoken - <0 - On error”h]”(hú)�”}”(hŒ**Parameters**”h]”j)�”}”(hjž…h]”hŒ Parameters”…”�”}”(hj …h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhjœ…ubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³Œ`/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1367: ./kernel/futex/waitwake.c”h´M.hj˜…ubj")�”}”(hhh]”(j")�”}”(hŒ;``struct futex_vector *vs`` The list of futexes to wait on ”h]”(j")�”}”(hŒ``struct futex_vector *vs``”h]”jI)�”}”(hj½…h]”hŒstruct futex_vector *vs”…”�”}”(hj¿…h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jHhj»…ubah}”(h]”h ]”h"]”h$]”h&]”uh1j"h³Œ`/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1367: ./kernel/futex/waitwake.c”h´M+hj·…ubj5")�”}”(hhh]”hú)�”}”(hŒThe list of futexes to wait on”h]”hŒThe list of futexes to wait on”…”�”}”(hjÖ…h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³jÒ…h´M+hjÓ…ubah}”(h]”h ]”h"]”h$]”h&]”uh1j4"hj·…ubeh}”(h]”h ]”h"]”h$]”h&]”uh1j"h³jÒ…h´M+hj´…ubj")�”}”(hŒ-``unsigned int count`` The number of objects ”h]”(j")�”}”(hŒ``unsigned int count``”h]”jI)�”}”(hjö…h]”hŒunsigned int count”…”�”}”(hjø…h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jHhjô…ubah}”(h]”h ]”h"]”h$]”h&]”uh1j"h³Œ`/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1367: ./kernel/futex/waitwake.c”h´M,hjð…ubj5")�”}”(hhh]”hú)�”}”(hŒThe number of objects”h]”hŒThe number of objects”…”�”}”(hj†h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³j †h´M,hj †ubah}”(h]”h ]”h"]”h$]”h&]”uh1j4"hjð…ubeh}”(h]”h ]”h"]”h$]”h&]”uh1j"h³j †h´M,hj´…ubj")�”}”(hŒS``struct hrtimer_sleeper *to`` Timeout before giving up and returning to userspace ”h]”(j")�”}”(hŒ``struct hrtimer_sleeper *to``”h]”jI)�”}”(hj/†h]”hŒstruct hrtimer_sleeper *to”…”�”}”(hj1†h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jHhj-†ubah}”(h]”h ]”h"]”h$]”h&]”uh1j"h³Œ`/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1367: ./kernel/futex/waitwake.c”h´M-hj)†ubj5")�”}”(hhh]”hú)�”}”(hŒ3Timeout before giving up and returning to userspace”h]”hŒ3Timeout before giving up and returning to userspace”…”�”}”(hjH†h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³jD†h´M-hjE†ubah}”(h]”h ]”h"]”h$]”h&]”uh1j4"hj)†ubeh}”(h]”h ]”h"]”h$]”h&]”uh1j"h³jD†h´M-hj´…ubeh}”(h]”h ]”h"]”h$]”h&]”uh1j"hj˜…ubhú)�”}”(hŒ**Description**”h]”j)�”}”(hjj†h]”hŒ Description”…”�”}”(hjl†h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhjh†ubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³Œ`/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1367: ./kernel/futex/waitwake.c”h´M/hj˜…ubhú)�”}”(hŒ²Entry point for the FUTEX_WAIT_MULTIPLE futex operation, this function sleeps on a group of futexes and returns on the first futex that is wake, or after the timeout has elapsed.”h]”hŒ²Entry point for the FUTEX_WAIT_MULTIPLE futex operation, this function sleeps on a group of futexes and returns on the first futex that is wake, or after the timeout has elapsed.”…”�”}”(hj€†h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³Œ`/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1367: ./kernel/futex/waitwake.c”h´M.hj˜…ubhú)�”}”(hŒ **Return**”h]”j)�”}”(hj‘†h]”hŒReturn”…”�”}”(hj“†h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhj�†ubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³Œ`/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1367: ./kernel/futex/waitwake.c”h´M2hj˜…ubj½ )�”}”(hhh]”(j )�”}”(hŒ'>=0 - Hint to the futex that was awoken”h]”hú)�”}”(hj¬†h]”hŒ'>=0 - Hint to the futex that was awoken”…”�”}”(hj®†h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³Œ`/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1367: ./kernel/futex/waitwake.c”h´M3hjª†ubah}”(h]”h ]”h"]”h$]”h&]”uh1jÁ hj§†ubj )�”}”(hŒ<0 - On error”h]”hú)�”}”(hjĆh]”hŒ<0 - On error”…”�”}”(hjƆh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³Œ`/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1367: ./kernel/futex/waitwake.c”h´M4hj†ubah}”(h]”h ]”h"]”h$]”h&]”uh1jÁ hj§†ubeh}”(h]”h ]”h"]”h$]”h&]”j5 j6 uh1j¼ h³j»†h´M3hj˜…ubeh}”(h]”h ]”Œ kernelindent”ah"]”h$]”h&]”uh1jñ!hj6h²hh³Nh´NubjR!)�”}”(hhh]”h}”(h]”h ]”h"]”h$]”h&]”Œentries”]”(j^!Œfutex_wait_setup (C function)”Œc.futex_wait_setup”hNt”auh1jQ!hj6h²hh³Nh´Nubjc!)�”}”(hhh]”(jh!)�”}”(hŒ‰int futex_wait_setup (u32 __user *uaddr, u32 val, unsigned int flags, struct futex_q *q, union futex_key *key2, struct task_struct *task)”h]”jn!)�”}”(hŒˆint futex_wait_setup(u32 __user *uaddr, u32 val, unsigned int flags, struct futex_q *q, union futex_key *key2, struct task_struct *task)”h]”(j$)�”}”(hŒint”h]”hŒint”…”�”}”(hj‡h²hh³Nh´Nubah}”(h]”h ]”j$ah"]”h$]”h&]”uh1j$hjü†h²hh³Œ`/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1367: ./kernel/futex/waitwake.c”h´M]ubj$)�”}”(hŒ ”h]”hŒ ”…”�”}”(hj‡h²hh³Nh´Nubah}”(h]”h ]”j $ah"]”h$]”h&]”uh1j$hjü†h²hh³j‡h´M]ubjt!)�”}”(hŒfutex_wait_setup”h]”jz!)�”}”(hŒfutex_wait_setup”h]”hŒfutex_wait_setup”…”�”}”(hj!‡h²hh³Nh´Nubah}”(h]”h ]”j…!ah"]”h$]”h&]”uh1jy!hj‡ubah}”(h]”h ]”(jŒ!j�!eh"]”h$]”h&]”j�jŽuh1js!hjü†h²hh³j‡h´M]ubj=$)�”}”(hŒt(u32 __user *uaddr, u32 val, unsigned int flags, struct futex_q *q, union futex_key *key2, struct task_struct *task)”h]”(jC$)�”}”(hŒu32 __user *uaddr”h]”(h)�”}”(hhh]”jz!)�”}”(hŒu32”h]”hŒu32”…”�”}”(hj@‡h²hh³Nh´Nubah}”(h]”h ]”j…!ah"]”h$]”h&]”uh1jy!hj=‡ubah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”jUŒreftype”j€$Œ reftarget”jB‡Œmodname”NŒ classname”Nj„$j‡$)�”}”jŠ$]”j�$)�”}”j€$j#‡sbŒc.futex_wait_setup”†”asbuh1hhj9‡ubj$)�”}”(hŒ ”h]”hŒ ”…”�”}”(hj`‡h²hh³Nh´Nubah}”(h]”h ]”j $ah"]”h$]”h&]”uh1j$hj9‡ubhŒ__user”…”�”}”(hj9‡h²hh³Nh´Nubj$)�”}”(hŒ ”h]”hŒ ”…”�”}”(hjr‡h²hh³Nh´Nubah}”(h]”h ]”j $ah"]”h$]”h&]”uh1j$hj9‡ubj¡$)�”}”(hj¤$h]”hŒ*”…”�”}”(hj€‡h²hh³Nh´Nubah}”(h]”h ]”j­$ah"]”h$]”h&]”uh1j $hj9‡ubjz!)�”}”(hŒuaddr”h]”hŒuaddr”…”�”}”(hj�‡h²hh³Nh´Nubah}”(h]”h ]”j…!ah"]”h$]”h&]”uh1jy!hj9‡ubeh}”(h]”h ]”h"]”h$]”h&]”Œnoemph”ˆj�jŽuh1jB$hj5‡ubjC$)�”}”(hŒu32 val”h]”(h)�”}”(hhh]”jz!)�”}”(hŒu32”h]”hŒu32”…”�”}”(hj©‡h²hh³Nh´Nubah}”(h]”h ]”j…!ah"]”h$]”h&]”uh1jy!hj¦‡ubah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”jUŒreftype”j€$Œ reftarget”j«‡Œmodname”NŒ classname”Nj„$j‡$)�”}”jŠ$]”j\‡Œc.futex_wait_setup”†”asbuh1hhj¢‡ubj$)�”}”(hŒ ”h]”hŒ ”…”�”}”(hjLJh²hh³Nh´Nubah}”(h]”h ]”j $ah"]”h$]”h&]”uh1j$hj¢‡ubjz!)�”}”(hŒval”h]”hŒval”…”�”}”(hjÕ‡h²hh³Nh´Nubah}”(h]”h ]”j…!ah"]”h$]”h&]”uh1jy!hj¢‡ubeh}”(h]”h ]”h"]”h$]”h&]”Œnoemph”ˆj�jŽuh1jB$hj5‡ubjC$)�”}”(hŒunsigned int flags”h]”(j$)�”}”(hŒunsigned”h]”hŒunsigned”…”�”}”(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ê‡ubj$)�”}”(hŒint”h]”hŒint”…”�”}”(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ê‡ubjz!)�”}”(hŒflags”h]”hŒflags”…”�”}”(hj&ˆh²hh³Nh´Nubah}”(h]”h ]”j…!ah"]”h$]”h&]”uh1jy!hjê‡ubeh}”(h]”h ]”h"]”h$]”h&]”Œnoemph”ˆj�jŽuh1jB$hj5‡ubjC$)�”}”(hŒstruct futex_q *q”h]”(jI$)�”}”(hjL$h]”hŒstruct”…”�”}”(hj?ˆh²hh³Nh´Nubah}”(h]”h ]”jU$ah"]”h$]”h&]”uh1jH$hj;ˆubj$)�”}”(hŒ ”h]”hŒ ”…”�”}”(hjLˆh²hh³Nh´Nubah}”(h]”h ]”j $ah"]”h$]”h&]”uh1j$hj;ˆubh)�”}”(hhh]”jz!)�”}”(hŒfutex_q”h]”hŒfutex_q”…”�”}”(hj]ˆh²hh³Nh´Nubah}”(h]”h ]”j…!ah"]”h$]”h&]”uh1jy!hjZˆubah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”jUŒreftype”j€$Œ reftarget”j_ˆŒmodname”NŒ classname”Nj„$j‡$)�”}”jŠ$]”j\‡Œc.futex_wait_setup”†”asbuh1hhj;ˆubj$)�”}”(hŒ ”h]”hŒ ”…”�”}”(hj{ˆh²hh³Nh´Nubah}”(h]”h ]”j $ah"]”h$]”h&]”uh1j$hj;ˆubj¡$)�”}”(hj¤$h]”hŒ*”…”�”}”(hj‰ˆh²hh³Nh´Nubah}”(h]”h ]”j­$ah"]”h$]”h&]”uh1j $hj;ˆubjz!)�”}”(hj;Gh]”hŒq”…”�”}”(hj–ˆh²hh³Nh´Nubah}”(h]”h ]”j…!ah"]”h$]”h&]”uh1jy!hj;ˆubeh}”(h]”h ]”h"]”h$]”h&]”Œnoemph”ˆj�jŽuh1jB$hj5‡ubjC$)�”}”(hŒunion futex_key *key2”h]”(jI$)�”}”(hj§6h]”hŒunion”…”�”}”(hj®ˆh²hh³Nh´Nubah}”(h]”h ]”jU$ah"]”h$]”h&]”uh1jH$hjªˆubj$)�”}”(hŒ ”h]”hŒ ”…”�”}”(hj»ˆh²hh³Nh´Nubah}”(h]”h ]”j $ah"]”h$]”h&]”uh1j$hjªˆubh)�”}”(hhh]”jz!)�”}”(hŒ futex_key”h]”hŒ futex_key”…”�”}”(hj̈h²hh³Nh´Nubah}”(h]”h ]”j…!ah"]”h$]”h&]”uh1jy!hjɈubah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”jUŒreftype”j€$Œ reftarget”jΈŒmodname”NŒ classname”Nj„$j‡$)�”}”jŠ$]”j\‡Œc.futex_wait_setup”†”asbuh1hhjªˆubj$)�”}”(hŒ ”h]”hŒ ”…”�”}”(hjêˆh²hh³Nh´Nubah}”(h]”h ]”j $ah"]”h$]”h&]”uh1j$hjªˆubj¡$)�”}”(hj¤$h]”hŒ*”…”�”}”(hjøˆh²hh³Nh´Nubah}”(h]”h ]”j­$ah"]”h$]”h&]”uh1j $hjªˆubjz!)�”}”(hŒkey2”h]”hŒkey2”…”�”}”(hj‰h²hh³Nh´Nubah}”(h]”h ]”j…!ah"]”h$]”h&]”uh1jy!hjªˆubeh}”(h]”h ]”h"]”h$]”h&]”Œnoemph”ˆj�jŽuh1jB$hj5‡ubjC$)�”}”(hŒstruct task_struct *task”h]”(jI$)�”}”(hjL$h]”hŒstruct”…”�”}”(hj‰h²hh³Nh´Nubah}”(h]”h ]”jU$ah"]”h$]”h&]”uh1jH$hj‰ubj$)�”}”(hŒ ”h]”hŒ ”…”�”}”(hj+‰h²hh³Nh´Nubah}”(h]”h ]”j $ah"]”h$]”h&]”uh1j$hj‰ubh)�”}”(hhh]”jz!)�”}”(hŒ task_struct”h]”hŒ task_struct”…”�”}”(hj<‰h²hh³Nh´Nubah}”(h]”h ]”j…!ah"]”h$]”h&]”uh1jy!hj9‰ubah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”jUŒreftype”j€$Œ reftarget”j>‰Œmodname”NŒ classname”Nj„$j‡$)�”}”jŠ$]”j\‡Œc.futex_wait_setup”†”asbuh1hhj‰ubj$)�”}”(hŒ ”h]”hŒ ”…”�”}”(hjZ‰h²hh³Nh´Nubah}”(h]”h ]”j $ah"]”h$]”h&]”uh1j$hj‰ubj¡$)�”}”(hj¤$h]”hŒ*”…”�”}”(hjh‰h²hh³Nh´Nubah}”(h]”h ]”j­$ah"]”h$]”h&]”uh1j $hj‰ubjz!)�”}”(hŒtask”h]”hŒtask”…”�”}”(hju‰h²hh³Nh´Nubah}”(h]”h ]”j…!ah"]”h$]”h&]”uh1jy!hj‰ubeh}”(h]”h ]”h"]”h$]”h&]”Œnoemph”ˆj�jŽuh1jB$hj5‡ubeh}”(h]”h ]”h"]”h$]”h&]”j�jŽuh1j<$hjü†h²hh³j‡h´M]ubeh}”(h]”h ]”h"]”h$]”h&]”j�jŽj˜!ˆuh1jm!j™!jš!hjø†h²hh³j‡h´M]ubah}”(h]”jó†ah ]”(jž!jŸ!eh"]”h$]”h&]”j£!ˆj¤!)j¥!huh1jg!h³j‡h´M]hjõ†h²hubj§!)�”}”(hhh]”hú)�”}”(hŒPrepare to wait on a futex”h]”hŒPrepare to wait on a futex”…”�”}”(hjŸ‰h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³Œ`/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1367: ./kernel/futex/waitwake.c”h´M]hjœ‰h²hubah}”(h]”h ]”h"]”h$]”h&]”uh1j¦!hjõ†h²hh³j‡h´M]ubeh}”(h]”h ]”(jUŒfunction”eh"]”h$]”h&]”j¸!jUj¹!j·‰jº!j·‰j»!‰j¼!‰j½!‰uh1jb!h²hhj6h³Nh´Nubjò!)�”}”(hX**Parameters** ``u32 __user *uaddr`` the futex userspace address ``u32 val`` the expected value ``unsigned int flags`` futex flags (FLAGS_SHARED, etc.) ``struct futex_q *q`` the associated futex_q ``union futex_key *key2`` the second futex_key if used for requeue PI ``struct task_struct *task`` Task queueing this futex **Description** Setup the futex_q and locate the hash_bucket. Get the futex value and compare it with the expected value. Handle atomic faults internally. Return with the hb lock held on success, and unlocked on failure. **Return** - 0 - uaddr contains val and hb has been locked; - <0 - On error and the hb is unlocked. A possible reason: the uaddr can not be read, does not contain the expected value or is not properly aligned.”h]”(hú)�”}”(hŒ**Parameters**”h]”j)�”}”(hjÁ‰h]”hŒ Parameters”…”�”}”(hjÉh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhj¿‰ubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³Œ`/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1367: ./kernel/futex/waitwake.c”h´Mahj»‰ubj")�”}”(hhh]”(j")�”}”(hŒ2``u32 __user *uaddr`` the futex userspace address ”h]”(j")�”}”(hŒ``u32 __user *uaddr``”h]”jI)�”}”(hjà‰h]”hŒu32 __user *uaddr”…”�”}”(hjâ‰h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jHhjÞ‰ubah}”(h]”h ]”h"]”h$]”h&]”uh1j"h³Œ`/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1367: ./kernel/futex/waitwake.c”h´M^hjÚ‰ubj5")�”}”(hhh]”hú)�”}”(hŒthe futex userspace address”h]”hŒthe futex userspace address”…”�”}”(hjù‰h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³jõ‰h´M^hjö‰ubah}”(h]”h ]”h"]”h$]”h&]”uh1j4"hjÚ‰ubeh}”(h]”h ]”h"]”h$]”h&]”uh1j"h³jõ‰h´M^hj׉ubj")�”}”(hŒ``u32 val`` the expected value ”h]”(j")�”}”(hŒ ``u32 val``”h]”jI)�”}”(hjŠh]”hŒu32 val”…”�”}”(hjŠh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jHhjŠubah}”(h]”h ]”h"]”h$]”h&]”uh1j"h³Œ`/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1367: ./kernel/futex/waitwake.c”h´M_hjŠubj5")�”}”(hhh]”hú)�”}”(hŒthe expected value”h]”hŒthe expected value”…”�”}”(hj2Šh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³j.Šh´M_hj/Šubah}”(h]”h ]”h"]”h$]”h&]”uh1j4"hjŠubeh}”(h]”h ]”h"]”h$]”h&]”uh1j"h³j.Šh´M_hj׉ubj")�”}”(hŒ8``unsigned int flags`` futex flags (FLAGS_SHARED, etc.) ”h]”(j")�”}”(hŒ``unsigned int flags``”h]”jI)�”}”(hjRŠh]”hŒunsigned int flags”…”�”}”(hjTŠh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jHhjPŠubah}”(h]”h ]”h"]”h$]”h&]”uh1j"h³Œ`/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1367: ./kernel/futex/waitwake.c”h´M`hjLŠubj5")�”}”(hhh]”hú)�”}”(hŒ futex flags (FLAGS_SHARED, etc.)”h]”hŒ futex flags (FLAGS_SHARED, etc.)”…”�”}”(hjkŠh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³jgŠh´M`hjhŠubah}”(h]”h ]”h"]”h$]”h&]”uh1j4"hjLŠubeh}”(h]”h ]”h"]”h$]”h&]”uh1j"h³jgŠh´M`hj׉ubj")�”}”(hŒ-``struct futex_q *q`` the associated futex_q ”h]”(j")�”}”(hŒ``struct futex_q *q``”h]”jI)�”}”(hj‹Šh]”hŒstruct futex_q *q”…”�”}”(hj�Šh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jHhj‰Šubah}”(h]”h ]”h"]”h$]”h&]”uh1j"h³Œ`/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1367: ./kernel/futex/waitwake.c”h´Mahj…Šubj5")�”}”(hhh]”hú)�”}”(hŒthe associated futex_q”h]”hŒthe associated futex_q”…”�”}”(hj¤Šh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³j Šh´Mahj¡Šubah}”(h]”h ]”h"]”h$]”h&]”uh1j4"hj…Šubeh}”(h]”h ]”h"]”h$]”h&]”uh1j"h³j Šh´Mahj׉ubj")�”}”(hŒF``union futex_key *key2`` the second futex_key if used for requeue PI ”h]”(j")�”}”(hŒ``union futex_key *key2``”h]”jI)�”}”(hjÄŠh]”hŒunion futex_key *key2”…”�”}”(hjÆŠh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jHhjŠubah}”(h]”h ]”h"]”h$]”h&]”uh1j"h³Œ`/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1367: ./kernel/futex/waitwake.c”h´Mbhj¾Šubj5")�”}”(hhh]”hú)�”}”(hŒ+the second futex_key if used for requeue PI”h]”hŒ+the second futex_key if used for requeue PI”…”�”}”(hjÝŠh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³jÙŠh´MbhjÚŠubah}”(h]”h ]”h"]”h$]”h&]”uh1j4"hj¾Šubeh}”(h]”h ]”h"]”h$]”h&]”uh1j"h³jÙŠh´Mbhj׉ubj")�”}”(hŒ6``struct task_struct *task`` Task queueing this futex ”h]”(j")�”}”(hŒ``struct task_struct *task``”h]”jI)�”}”(hjýŠh]”hŒstruct task_struct *task”…”�”}”(hjÿŠh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jHhjûŠubah}”(h]”h ]”h"]”h$]”h&]”uh1j"h³Œ`/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1367: ./kernel/futex/waitwake.c”h´Mchj÷Šubj5")�”}”(hhh]”hú)�”}”(hŒTask queueing this futex”h]”hŒTask queueing this futex”…”�”}”(hj‹h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³j‹h´Mchj‹ubah}”(h]”h ]”h"]”h$]”h&]”uh1j4"hj÷Šubeh}”(h]”h ]”h"]”h$]”h&]”uh1j"h³j‹h´Mchj׉ubeh}”(h]”h ]”h"]”h$]”h&]”uh1j"hj»‰ubhú)�”}”(hŒ**Description**”h]”j)�”}”(hj8‹h]”hŒ Description”…”�”}”(hj:‹h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhj6‹ubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³Œ`/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1367: ./kernel/futex/waitwake.c”h´Mehj»‰ubhú)�”}”(hŒÎSetup the futex_q and locate the hash_bucket. Get the futex value and compare it with the expected value. Handle atomic faults internally. Return with the hb lock held on success, and unlocked on failure.”h]”hŒÎSetup the futex_q and locate the hash_bucket. Get the futex value and compare it with the expected value. Handle atomic faults internally. Return with the hb lock held on success, and unlocked on failure.”…”�”}”(hjN‹h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³Œ`/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1367: ./kernel/futex/waitwake.c”h´Mdhj»‰ubhú)�”}”(hŒ **Return**”h]”j)�”}”(hj_‹h]”hŒReturn”…”�”}”(hja‹h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhj]‹ubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³Œ`/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1367: ./kernel/futex/waitwake.c”h´Mhhj»‰ubj½ )�”}”(hhh]”(j )�”}”(hŒ.0 - uaddr contains val and hb has been locked;”h]”hú)�”}”(hjz‹h]”hŒ.0 - uaddr contains val and hb has been locked;”…”�”}”(hj|‹h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³Œ`/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1367: ./kernel/futex/waitwake.c”h´Mihjx‹ubah}”(h]”h ]”h"]”h$]”h&]”uh1jÁ hju‹ubj )�”}”(hŒ˜<0 - On error and the hb is unlocked. A possible reason: the uaddr can not be read, does not contain the expected value or is not properly aligned.”h]”j")�”}”(hhh]”j")�”}”(hŒ“<0 - On error and the hb is unlocked. A possible reason: the uaddr can not be read, does not contain the expected value or is not properly aligned.”h]”(j")�”}”(hŒJ<0 - On error and the hb is unlocked. A possible reason: the uaddr can not”h]”hŒJ<0 - On error and the hb is unlocked. A possible reason: the uaddr can not”…”�”}”(hj›‹h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j"h³Œ`/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1367: ./kernel/futex/waitwake.c”h´Mjhj—‹ubj5")�”}”(hhh]”hú)�”}”(hŒHbe read, does not contain the expected value or is not properly aligned.”h]”hŒHbe read, does not contain the expected value or is not properly aligned.”…”�”}”(hj­‹h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³Œ`/var/lib/git/docbuild/linux/Documentation/kernel-hacking/locking:1367: ./kernel/futex/waitwake.c”h´Mkhjª‹ubah}”(h]”h ]”h"]”h$]”h&]”uh1j4"hj—‹ubeh}”(h]”h ]”h"]”h$]”h&]”uh1j"h³j©‹h´Mjhj”‹ubah}”(h]”h ]”h"]”h$]”h&]”uh1j"hj�‹ubah}”(h]”h ]”h"]”h$]”h&]”uh1jÁ hju‹ubeh}”(h]”h ]”h"]”h$]”h&]”j5 j6 uh1j¼ h³j‰‹h´Mihj»‰ubeh}”(h]”h ]”Œ kernelindent”ah"]”h$]”h&]”uh1jñ!hj6h²hh³Nh´Nubeh}”(h]”Œfutex-api-reference”ah ]”h"]”Œfutex api reference”ah$]”h&]”uh1hÄhhÆh²hh³hÃh´MIubhÅ)�”}”(hhh]”(hÊ)�”}”(hŒFurther reading”h]”hŒFurther reading”…”�”}”(hjì‹h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÉhjé‹h²hh³hÃh´M[ubj½ )�”}”(hhh]”(j )�”}”(hŒe``Documentation/locking/spinlocks.rst``: Linus Torvalds' spinlocking tutorial in the kernel sources. ”h]”hú)�”}”(hŒd``Documentation/locking/spinlocks.rst``: Linus Torvalds' spinlocking tutorial in the kernel sources.”h]”(jI)�”}”(hŒ'``Documentation/locking/spinlocks.rst``”h]”hŒ#Documentation/locking/spinlocks.rst”…”�”}”(hjŒh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jHhjŒubhŒ?: Linus Torvalds’ spinlocking tutorial in the kernel sources.”…”�”}”(hjŒh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´M]hjý‹ubah}”(h]”h ]”h"]”h$]”h&]”uh1jÁ hjú‹h²hh³hÃh´Nubj )�”}”(hX?Unix Systems for Modern Architectures: Symmetric Multiprocessing and Caching for Kernel Programmers: Curt Schimmel's very good introduction to kernel level locking (not written for Linux, but nearly everything applies). The book is expensive, but really worth every penny to understand SMP locking. [ISBN: 0201633388] ”h]”(hú)�”}”(hŒdUnix Systems for Modern Architectures: Symmetric Multiprocessing and Caching for Kernel Programmers:”h]”hŒdUnix Systems for Modern Architectures: Symmetric Multiprocessing and Caching for Kernel Programmers:”…”�”}”(hj'Œh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´M`hj#Œubhú)�”}”(hŒØCurt Schimmel's very good introduction to kernel level locking (not written for Linux, but nearly everything applies). The book is expensive, but really worth every penny to understand SMP locking. [ISBN: 0201633388]”h]”hŒÚCurt Schimmel’s very good introduction to kernel level locking (not written for Linux, but nearly everything applies). The book is expensive, but really worth every penny to understand SMP locking. [ISBN: 0201633388]”…”�”}”(hj5Œh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´Mchj#Œubeh}”(h]”h ]”h"]”h$]”h&]”uh1jÁ hjú‹h²hh³hÃh´Nubeh}”(h]”h ]”h"]”h$]”h&]”j5 j6 uh1j¼ h³hÃh´M]hjé‹h²hubeh}”(h]”Œfurther-reading”ah ]”h"]”Œfurther reading”ah$]”h&]”uh1hÄhhÆh²hh³hÃh´M[ubhÅ)�”}”(hhh]”(hÊ)�”}”(hŒThanks”h]”hŒThanks”…”�”}”(hjZŒh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÉhjWŒh²hh³hÃh´Miubhú)�”}”(hŒBThanks to Telsa Gwynne for DocBooking, neatening and adding style.”h]”hŒBThanks to Telsa Gwynne for DocBooking, neatening and adding style.”…”�”}”(hjhŒh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´MkhjWŒh²hubhú)�”}”(hŒôThanks to Martin Pool, Philipp Rumpf, Stephen Rothwell, Paul Mackerras, Ruedi Aschwanden, Alan Cox, Manfred Spraul, Tim Waugh, Pete Zaitcev, James Morris, Robert Love, Paul McKenney, John Ashby for proofreading, correcting, flaming, commenting.”h]”hŒôThanks to Martin Pool, Philipp Rumpf, Stephen Rothwell, Paul Mackerras, Ruedi Aschwanden, Alan Cox, Manfred Spraul, Tim Waugh, Pete Zaitcev, James Morris, Robert Love, Paul McKenney, John Ashby for proofreading, correcting, flaming, commenting.”…”�”}”(hjvŒh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´MmhjWŒh²hubhú)�”}”(hŒ=Thanks to the cabal for having no influence on this document.”h]”hŒ=Thanks to the cabal for having no influence on this document.”…”�”}”(hj„Œh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´MrhjWŒh²hubeh}”(h]”Œthanks”ah ]”h"]”Œthanks”ah$]”h&]”uh1hÄhhÆh²hh³hÃh´MiubhÅ)�”}”(hhh]”(hÊ)�”}”(hŒGlossary”h]”hŒGlossary”…”�”}”(hj�Œh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÉhjšŒh²hh³hÃh´Muubj")�”}”(hhh]”(j")�”}”(hXpreemption Prior to 2.5, or when ``CONFIG_PREEMPT`` is unset, processes in user context inside the kernel would not preempt each other (ie. you had that CPU until you gave it up, except for interrupts). With the addition of ``CONFIG_PREEMPT`` in 2.5.4, this changed: when in user context, higher priority tasks can "cut in": spinlocks were changed to disable preemption, even on UP. ”h]”(j")�”}”(hŒ preemption”h]”hŒ preemption”…”�”}”(hj²Œh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j"h³hÃh´M}hj®Œubj5")�”}”(hhh]”hú)�”}”(hXsPrior to 2.5, or when ``CONFIG_PREEMPT`` is unset, processes in user context inside the kernel would not preempt each other (ie. you had that CPU until you gave it up, except for interrupts). With the addition of ``CONFIG_PREEMPT`` in 2.5.4, this changed: when in user context, higher priority tasks can "cut in": spinlocks were changed to disable preemption, even on UP.”h]”(hŒPrior to 2.5, or when ”…”�”}”(hjÃŒh²hh³Nh´NubjI)�”}”(hŒ``CONFIG_PREEMPT``”h]”hŒCONFIG_PREEMPT”…”�”}”(hjËŒh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jHhjÃŒubhŒ­ is unset, processes in user context inside the kernel would not preempt each other (ie. you had that CPU until you gave it up, except for interrupts). With the addition of ”…”�”}”(hjÃŒh²hh³Nh´NubjI)�”}”(hŒ``CONFIG_PREEMPT``”h]”hŒCONFIG_PREEMPT”…”�”}”(hjÝŒh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jHhjÃŒubhŒ� in 2.5.4, this changed: when in user context, higher priority tasks can “cut inâ€�: spinlocks were changed to disable preemption, even on UP.”…”�”}”(hjÃŒh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´MxhjÀŒubah}”(h]”h ]”h"]”h$]”h&]”uh1j4"hj®Œubeh}”(h]”h ]”h"]”h$]”h&]”uh1j"h³hÃh´M}hj«Œubj")�”}”(hX3bh Bottom Half: for historical reasons, functions with '_bh' in them often now refer to any software interrupt, e.g. spin_lock_bh() blocks any software interrupt on the current CPU. Bottom halves are deprecated, and will eventually be replaced by tasklets. Only one bottom half will be running at any time. ”h]”(j")�”}”(hŒbh”h]”hŒbh”…”�”}”(hj�h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j"h³hÃh´M„hj�ubj5")�”}”(hhh]”hú)�”}”(hX/Bottom Half: for historical reasons, functions with '_bh' in them often now refer to any software interrupt, e.g. spin_lock_bh() blocks any software interrupt on the current CPU. Bottom halves are deprecated, and will eventually be replaced by tasklets. Only one bottom half will be running at any time.”h]”hX3Bottom Half: for historical reasons, functions with ‘_bh’ in them often now refer to any software interrupt, e.g. spin_lock_bh() blocks any software interrupt on the current CPU. Bottom halves are deprecated, and will eventually be replaced by tasklets. Only one bottom half will be running at any time.”…”�”}”(hj�h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´M€hj�ubah}”(h]”h ]”h"]”h$]”h&]”uh1j4"hj�ubeh}”(h]”h ]”h"]”h$]”h&]”uh1j"h³hÃh´M„hj«Œh²hubj")�”}”(hŒyHardware Interrupt / Hardware IRQ Hardware interrupt request. in_hardirq() returns true in a hardware interrupt handler. ”h]”(j")�”}”(hŒ!Hardware Interrupt / Hardware IRQ”h]”hŒ!Hardware Interrupt / Hardware IRQ”…”�”}”(hj4�h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j"h³hÃh´Mˆhj0�ubj5")�”}”(hhh]”hú)�”}”(hŒVHardware interrupt request. in_hardirq() returns true in a hardware interrupt handler.”h]”hŒVHardware interrupt request. in_hardirq() returns true in a hardware interrupt handler.”…”�”}”(hjE�h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´M‡hjB�ubah}”(h]”h ]”h"]”h$]”h&]”uh1j4"hj0�ubeh}”(h]”h ]”h"]”h$]”h&]”uh1j"h³hÃh´Mˆhj«Œh²hubj")�”}”(hŒ…Interrupt Context Not user context: processing a hardware irq or software irq. Indicated by the in_interrupt() macro returning true. ”h]”(j")�”}”(hŒInterrupt Context”h]”hŒInterrupt Context”…”�”}”(hjc�h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j"h³hÃh´MŒhj_�ubj5")�”}”(hhh]”hú)�”}”(hŒrNot user context: processing a hardware irq or software irq. Indicated by the in_interrupt() macro returning true.”h]”hŒrNot user context: processing a hardware irq or software irq. Indicated by the in_interrupt() macro returning true.”…”�”}”(hjt�h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´M‹hjq�ubah}”(h]”h ]”h"]”h$]”h&]”uh1j4"hj_�ubeh}”(h]”h ]”h"]”h$]”h&]”uh1j"h³hÃh´MŒhj«Œh²hubj")�”}”(hŒ_SMP Symmetric Multi-Processor: kernels compiled for multiple-CPU machines. (``CONFIG_SMP=y``). ”h]”(j")�”}”(hŒSMP”h]”hŒSMP”…”�”}”(hj’�h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j"h³hÃh´M�hjŽ�ubj5")�”}”(hhh]”hú)�”}”(hŒZSymmetric Multi-Processor: kernels compiled for multiple-CPU machines. (``CONFIG_SMP=y``).”h]”(hŒHSymmetric Multi-Processor: kernels compiled for multiple-CPU machines. (”…”�”}”(hj£�h²hh³Nh´NubjI)�”}”(hŒ``CONFIG_SMP=y``”h]”hŒ CONFIG_SMP=y”…”�”}”(hj«�h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jHhj£�ubhŒ).”…”�”}”(hj£�h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´M�hj �ubah}”(h]”h ]”h"]”h$]”h&]”uh1j4"hjŽ�ubeh}”(h]”h ]”h"]”h$]”h&]”uh1j"h³hÃh´M�hj«Œh²hubj")�”}”(hX~Software Interrupt / softirq Software interrupt handler. in_hardirq() returns false; in_softirq() returns true. Tasklets and softirqs both fall into the category of 'software interrupts'. Strictly speaking a softirq is one of up to 32 enumerated software interrupts which can run on multiple CPUs at once. Sometimes used to refer to tasklets as well (ie. all software interrupts). ”h]”(j")�”}”(hŒSoftware Interrupt / softirq”h]”hŒSoftware Interrupt / softirq”…”�”}”(hjÓ�h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j"h³hÃh´M™hjÏ�ubj5")�”}”(hhh]”(hú)�”}”(hŒžSoftware interrupt handler. in_hardirq() returns false; in_softirq() returns true. Tasklets and softirqs both fall into the category of 'software interrupts'.”h]”hŒ¢Software interrupt handler. in_hardirq() returns false; in_softirq() returns true. Tasklets and softirqs both fall into the category of ‘software interrupts’.”…”�”}”(hjä�h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´M“hjá�ubhú)�”}”(hŒÀStrictly speaking a softirq is one of up to 32 enumerated software interrupts which can run on multiple CPUs at once. Sometimes used to refer to tasklets as well (ie. all software interrupts).”h]”hŒÀStrictly speaking a softirq is one of up to 32 enumerated software interrupts which can run on multiple CPUs at once. Sometimes used to refer to tasklets as well (ie. all software interrupts).”…”�”}”(hjò�h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´M—hjá�ubeh}”(h]”h ]”h"]”h$]”h&]”uh1j4"hjÏ�ubeh}”(h]”h ]”h"]”h$]”h&]”uh1j"h³hÃh´M™hj«Œh²hubj")�”}”(hŒltasklet A dynamically-registrable software interrupt, which is guaranteed to only run on one CPU at a time. ”h]”(j")�”}”(hŒtasklet”h]”hŒtasklet”…”�”}”(hjŽh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j"h³hÃh´M�hj Žubj5")�”}”(hhh]”hú)�”}”(hŒcA dynamically-registrable software interrupt, which is guaranteed to only run on one CPU at a time.”h]”hŒcA dynamically-registrable software interrupt, which is guaranteed to only run on one CPU at a time.”…”�”}”(hj!Žh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´MœhjŽubah}”(h]”h ]”h"]”h$]”h&]”uh1j4"hj Žubeh}”(h]”h ]”h"]”h$]”h&]”uh1j"h³hÃh´M�hj«Œh²hubj")�”}”(hŒ¿timer A dynamically-registrable software interrupt, which is run at (or close to) a given time. When running, it is just like a tasklet (in fact, they are called from the ``TIMER_SOFTIRQ``). ”h]”(j")�”}”(hŒtimer”h]”hŒtimer”…”�”}”(hj?Žh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j"h³hÃh´M¢hj;Žubj5")�”}”(hhh]”hú)�”}”(hŒ¸A dynamically-registrable software interrupt, which is run at (or close to) a given time. When running, it is just like a tasklet (in fact, they are called from the ``TIMER_SOFTIRQ``).”h]”(hŒ¥A dynamically-registrable software interrupt, which is run at (or close to) a given time. When running, it is just like a tasklet (in fact, they are called from the ”…”�”}”(hjPŽh²hh³Nh´NubjI)�”}”(hŒ``TIMER_SOFTIRQ``”h]”hŒ TIMER_SOFTIRQ”…”�”}”(hjXŽh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jHhjPŽubhŒ).”…”�”}”(hjPŽh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´M hjMŽubah}”(h]”h ]”h"]”h$]”h&]”uh1j4"hj;Žubeh}”(h]”h ]”h"]”h$]”h&]”uh1j"h³hÃh´M¢hj«Œh²hubj")�”}”(hŒ/UP Uni-Processor: Non-SMP. (``CONFIG_SMP=n``). ”h]”(j")�”}”(hŒUP”h]”hŒUP”…”�”}”(hj€Žh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j"h³hÃh´M¥hj|Žubj5")�”}”(hhh]”hú)�”}”(hŒ+Uni-Processor: Non-SMP. (``CONFIG_SMP=n``).”h]”(hŒUni-Processor: Non-SMP. (”…”�”}”(hj‘Žh²hh³Nh´NubjI)�”}”(hŒ``CONFIG_SMP=n``”h]”hŒ CONFIG_SMP=n”…”�”}”(hj™Žh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jHhj‘ŽubhŒ).”…”�”}”(hj‘Žh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´M¥hjŽŽubah}”(h]”h ]”h"]”h$]”h&]”uh1j4"hj|Žubeh}”(h]”h ]”h"]”h$]”h&]”uh1j"h³hÃh´M¥hj«Œh²hubj")�”}”(hXUser Context The kernel executing on behalf of a particular process (ie. a system call or trap) or kernel thread. You can tell which process with the ``current`` macro.) Not to be confused with userspace. Can be interrupted by software or hardware interrupts. ”h]”(j")�”}”(hŒ User Context”h]”hŒ User Context”…”�”}”(hjÁŽh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j"h³hÃh´M«hj½Žubj5")�”}”(hhh]”hú)�”}”(hŒöThe kernel executing on behalf of a particular process (ie. a system call or trap) or kernel thread. You can tell which process with the ``current`` macro.) Not to be confused with userspace. Can be interrupted by software or hardware interrupts.”h]”(hŒ‰The kernel executing on behalf of a particular process (ie. a system call or trap) or kernel thread. You can tell which process with the ”…”�”}”(hjÒŽh²hh³Nh´NubjI)�”}”(hŒ ``current``”h]”hŒcurrent”…”�”}”(hjÚŽh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jHhjÒŽubhŒb macro.) Not to be confused with userspace. Can be interrupted by software or hardware interrupts.”…”�”}”(hjÒŽh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´M¨hjÏŽubah}”(h]”h ]”h"]”h$]”h&]”uh1j4"hj½Žubeh}”(h]”h ]”h"]”h$]”h&]”uh1j"h³hÃh´M«hj«Œh²hubj")�”}”(hŒ>Userspace A process executing its own code outside the kernel.”h]”(j")�”}”(hŒ Userspace”h]”hŒ Userspace”…”�”}”(hj�h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j"h³hÃh´M­hjþŽubj5")�”}”(hhh]”hú)�”}”(hŒ4A process executing its own code outside the kernel.”h]”hŒ4A process executing its own code outside the kernel.”…”�”}”(hj�h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´M®hj�ubah}”(h]”h ]”h"]”h$]”h&]”uh1j4"hjþŽubeh}”(h]”h ]”h"]”h$]”h&]”uh1j"h³hÃh´M­hj«Œh²hubeh}”(h]”h ]”h"]”h$]”h&]”uh1j"hjšŒh²hh³hÃh´Nubeh}”(h]”Œglossary”ah ]”h"]”Œglossary”ah$]”h&]”uh1hÄhhÆh²hh³hÃh´Muubeh}”(h]”(Œunreliable-guide-to-locking”hÂeh ]”h"]”(Œunreliable guide to locking”Œkernel_hacking_lock”eh$]”h&]”uh1hÄhhh²hh³hÃh´KŒexpect_referenced_by_name”}”jA�h·sŒexpect_referenced_by_id”}”hÂh·subeh}”(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”jÕŒ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”jj�Œ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”}”(Œ0what functions are safe to call from interrupts?”]”j~aŒdeadlock: simple and advanced”]”j¢aŒhard irq context”]”j&aŒ per-cpu data”]”jdauŒrefids”}”hÂ]”h·asŒnameids”}”(jA�hÂj@�j=�jMjJjëjèjãjàjÉjÆjÂj¿jj|jêjçjfjcj�jŠj´j±j)j&júj÷j!jjÁj¾j’j�j¹j¶j™ j6jk jh j’ j� jAj>j9j6j„j�j0j-jôjñj‰j†j j�j˜j•j(j%jêjçjÝj²jGjDj?j<jâjßj°j­jÓjÐjÑjÎjWjtj¨j¥j=!jŽj¾ j» j6!j3!jþ5jû5jæ‹jã‹jTŒjQŒj—Œj”Œj8�j5�uŒ nametypes”}”(jA�ˆj@�‰jM‰jë‰jã‰jɉj‰j‰jê‰jf‰j�‰j´‰j)‰jú‰j!‰jÁ‰j’‰j¹‰j™ ‰jk ‰j’ ‰jA‰j9‰j„‰j0‰jô‰j‰‰j ‰j˜‰j(‰jê‰j݉jG‰j?‰jâ‰j°‰jÓ‰jщjW‰j¨‰j=!‰j¾ ‰j6!‰jþ5‰j拉jTŒ‰j—Œ‰j8�‰uh}”(hÂhÆj=�hÆjJjjèjPjàj£jÆjîj¿j/j|jÅjçj‚jcjíjŠjij±j�j&j·j÷jÖjjýj¾j,j�jKj¶j•j6jÌjh jëj� jn j>j� j6j7 j�jDj-j‡jñj¦j†j÷j�jŒj•j-j%j£jçj3j²jDjDjàj<jjßjJj­jíjÐjZjÎjÖjtjÔj¥jZjŽj³j» jÒj3!jÁ jû5j@!j`!ji!j¢"j§"jô#jù#j�%j”%j='jB'jë(jð(j{*j€*jÕ,jÚ,j¶.j».j—0jœ0j?2jD2jö3jû3jã‹j6j6j#6j;9j@9jt<jy<j—@jœ@j0Bj5Bj•DjšDj–Fj›FjHjHjèIjíIj‡Kj�Kj§Oj¬OjÑQjÖQjÄTjÉTj-Vj2Vj\j \jû^j_jPbjUbj fjfjŠlj�ljrjrjùtjþtjÈyjÍyjË{jÐ{jf~jk~j:�j?�jîƒjóƒjó†jø†jQŒjé‹j”ŒjWŒj5�jšŒjjŸ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”“”}”jx�Ks…”R”Œparse_messages”]”hŒsystem_message”“”)�”}”(hhh]”hú)�”}”(hŒeUnexpected possible title overline or transition. Treating it as ordinary text because it's so short.”h]”hŒgUnexpected possible title overline or transition. Treating it as ordinary text because it’s so short.”…”�”}”(hjÚ�h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùhj×�ubah}”(h]”h ]”h"]”h$]”h&]”Œlevel”KŒtype”ŒINFO”Œline”MBŒsource”hÃuh1jÕ�hjð ubaŒtransform_messages”]”jÖ�)�”}”(hhh]”hú)�”}”(hhh]”hŒ9Hyperlink target "kernel-hacking-lock" is not referenced.”…”�”}”hjø�sbah}”(h]”h ]”h"]”h$]”h&]”uh1hùhjõ�ubah}”(h]”h ]”h"]”h$]”h&]”Œlevel”KŒtype”jð�Œsource”hÃŒline”Kuh1jÕ�ubaŒ transformer”NŒ include_log”]”Œ decoration”Nh²hub.