doc/en_US.ISO8859-1/books/developers-handbook/locking/chapter.sgml
John Baldwin 6fa60155c8 Check in some updates I made to this ages ago which are at least still
partially applicable.  This does at least remove some mutex flags that
were obsoleted a long, long time ago as well as rename the lockmgr section
to be more generic.
2003-02-03 18:47:06 +00:00

313 lines
9.4 KiB
Text

<!--
The FreeBSD Documentation Project
The FreeBSD SMP Next Generation Project
$FreeBSD$
-->
<chapter id="locking">
<title>Locking Notes</title>
<para><emphasis>This chapter is maintained by the FreeBSD SMP Next
Generation Project. Please direct any comments or suggestions
to its &a.smp;.</emphasis></para>
<para>This document outlines the locking used in the FreeBSD kernel
to permit effective multi-processing within the kernel. Locking
can be achieved via several means. Data structures can be
protected by mutexes or &man.lockmgr.9; locks. A few variables
are protected simply by always using atomic operations to access
them.</para>
<sect1 id="locking-mutexes">
<title>Mutexes</title>
<para>A mutex is simply a lock used to guarantee mutual exclusion.
Specifically, a mutex may only be owned by one entity at a time.
If another entity wishes to obtain a mutex that is already
owned, it must wait until the mutex is released. In the FreeBSD
kernel, mutexes are owned by processes.</para>
<para>Mutexes may be recursively acquired, but they are intended
to be held for a short period of time. Specifically, one may
not sleep while holding a mutex. If you need to hold a lock
across a sleep, use a &man.lockmgr.9; lock.</para>
<para>Each mutex has several properties of interest:</para>
<variablelist>
<varlistentry>
<term>Variable Name</term>
<listitem>
<para>The name of the <type>struct mtx</type> variable in
the kernel source.</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Logical Name</term>
<listitem>
<para>The name of the mutex assigned to it by
<function>mtx_init</function>. This name is displayed in
KTR trace messages and witness errors and warnings and is
used to distinguish mutexes in the witness code.</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Type</term>
<listitem>
<para>The type of the mutex in terms of the
<constant>MTX_*</constant> flags. The meaning for each
flag is related to its meaning as documented in
&man.mutex.9;.</para>
<variablelist>
<varlistentry>
<term><constant>MTX_DEF</constant></term>
<listitem>
<para>A sleep mutex</para>
</listitem>
</varlistentry>
<varlistentry>
<term><constant>MTX_SPIN</constant></term>
<listitem>
<para>A spin mutex</para>
</listitem>
</varlistentry>
<varlistentry>
<term><constant>MTX_RECURSE</constant></term>
<listitem>
<para>This mutex is allowed to recurse.</para>
</listitem>
</varlistentry>
</variablelist>
</listitem>
</varlistentry>
<varlistentry>
<term>Protectees</term>
<listitem>
<para>A list of data structures or data structure members
that this entry protects. For data structure members, the
name will be in the form of
<structname/structure name/.<structfield/member name/.</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Dependent Functions</term>
<listitem>
<para>Functions that can only be called if this mutex is
held.</para>
</listitem>
</varlistentry>
</variablelist>
<table frame="all" colsep="1" rowsep="1" pgwide="1">
<title>Mutex List</title>
<tgroup cols="5">
<thead>
<row>
<entry>Variable Name</entry>
<entry>Logical Name</entry>
<entry>Type</entry>
<entry>Protectees</entry>
<entry>Dependent Functions</entry>
</row>
</thead>
<!-- The scheduler lock -->
<tbody>
<row>
<entry>sched_lock</entry>
<entry><quote>sched lock</quote></entry>
<entry>
<constant>MTX_SPIN</constant> |
<constant>MTX_RECURSE</constant>
</entry>
<entry>
<varname>_gmonparam</varname>,
<varname>cnt.v_swtch</varname>,
<varname>cp_time</varname>,
<varname>curpriority</varname>,
<structname/mtx/.<structfield/mtx_blocked/,
<structname/mtx/.<structfield/mtx_contested/,
<structname/proc/.<structfield/p_procq/,
<structname/proc/.<structfield/p_slpq/,
<structname/proc/.<structfield/p_sflag/
<structname/proc/.<structfield/p_stat/,
<structname/proc/.<structfield/p_estcpu/,
<structname/proc/.<structfield/p_cpticks/
<structname/proc/.<structfield/p_pctcpu/,
<structname/proc/.<structfield/p_wchan/,
<structname/proc/.<structfield/p_wmesg/,
<structname/proc/.<structfield/p_swtime/,
<structname/proc/.<structfield/p_slptime/,
<structname/proc/.<structfield/p_runtime/,
<structname/proc/.<structfield/p_uu/,
<structname/proc/.<structfield/p_su/,
<structname/proc/.<structfield/p_iu/,
<structname/proc/.<structfield/p_uticks/,
<structname/proc/.<structfield/p_sticks/,
<structname/proc/.<structfield/p_iticks/,
<structname/proc/.<structfield/p_oncpu/,
<structname/proc/.<structfield/p_lastcpu/,
<structname/proc/.<structfield/p_rqindex/,
<structname/proc/.<structfield/p_heldmtx/,
<structname/proc/.<structfield/p_blocked/,
<structname/proc/.<structfield/p_mtxname/,
<structname/proc/.<structfield/p_contested/,
<structname/proc/.<structfield/p_priority/,
<structname/proc/.<structfield/p_usrpri/,
<structname/proc/.<structfield/p_nativepri/,
<structname/proc/.<structfield/p_nice/,
<structname/proc/.<structfield/p_rtprio/,
<varname>pscnt</varname>,
<varname>slpque</varname>,
<varname>itqueuebits</varname>,
<varname>itqueues</varname>,
<varname>rtqueuebits</varname>,
<varname>rtqueues</varname>,
<varname>queuebits</varname>,
<varname>queues</varname>,
<varname>idqueuebits</varname>,
<varname>idqueues</varname>,
<varname>switchtime</varname>,
<varname>switchticks</varname>
</entry>
<entry>
<function>setrunqueue</function>,
<function>remrunqueue</function>,
<function>mi_switch</function>,
<function>chooseproc</function>,
<function>schedclock</function>,
<function>resetpriority</function>,
<function>updatepri</function>,
<function>maybe_resched</function>,
<function>cpu_switch</function>,
<function>cpu_throw</function>,
<function>need_resched</function>,
<function>resched_wanted</function>,
<function>clear_resched</function>,
<function>aston</function>,
<function>astoff</function>,
<function>astpending</function>,
<function>calcru</function>,
<function>proc_compare</function>
</entry>
</row>
<!-- The vm86 pcb lock -->
<row>
<entry>vm86pcb_lock</entry>
<entry><quote>vm86pcb lock</quote></entry>
<entry>
<constant>MTX_DEF</constant>
</entry>
<entry>
<varname>vm86pcb</varname>
</entry>
<entry>
<function>vm86_bioscall</function>
</entry>
</row>
<!-- Giant -->
<row>
<entry>Giant</entry>
<entry><quote>Giant</quote></entry>
<entry>
<constant>MTX_DEF</constant> |
<constant>MTX_RECURSE</constant>
</entry>
<entry>nearly everything</entry>
<entry>lots</entry>
</row>
<!-- The callout lock -->
<row>
<entry>callout_lock</entry>
<entry><quote>callout lock</quote></entry>
<entry>
<constant>MTX_SPIN</constant> |
<constant>MTX_RECURSE</constant>
</entry>
<entry>
<varname>callfree</varname>,
<varname>callwheel</varname>,
<varname>nextsoftcheck</varname>,
<structname/proc/.<structfield/p_itcallout/,
<structname/proc/.<structfield/p_slpcallout/,
<varname>softticks</varname>,
<varname>ticks</varname>
</entry>
<entry>
</entry>
</row>
</tbody>
</tgroup>
</table>
</sect1>
<sect1 id="locking-sx">
<title>Shared Exclusive Locks</title>
<para>These locks provide basic reader-writer type functionality
and may be held by a sleeping process. Currently they are
backed by &man.lockmgr.9;.</para>
<table>
<title>Shared Exclusive Lock List</title>
<tgroup cols="2">
<thead>
<row>
<entry>Variable Name</entry>
<entry>Protectees</entry>
</row>
</thead>
<tbody>
<row>
<entry><varname>allproc_lock</varname></entry>
<entry>
<varname>allproc</varname>
<varname>zombproc</varname>
<varname>pidhashtbl</varname>
<structname/proc/.<structfield/p_list/
<structname/proc/.<structfield/p_hash/
<varname>nextpid</varname>
</entry>
<entry><varname>proctree_lock</varname></entry>
<entry>
<structname/proc/.<structfield/p_children/
<structname/proc/.<structfield/p_sibling/
</entry>
</row>
</tbody>
</tgroup>
</table>
</sect1>
<sect1 id="locking-atomic">
<title>Atomically Protected Variables</title>
<para>An atomically protected variable is a special variable that
is not protected by an explicit lock. Instead, all data
accesses to the variables use special atomic operations as
described in &man.atomic.9;. Very few variables are treated
this way, although other synchronization primitives such as
mutexes are implemented with atomically protected
variables.</para>
<itemizedlist>
<listitem>
<para><structname/mtx/.<structfield/mtx_lock/</para>
</listitem>
</itemizedlist>
</sect1>
</chapter>