xref: /dflybsd-src/share/man/man9/spinlock.9 (revision deff95cb9689e092bc08ed53878ea432387b690c)
116338e2dSSascha Wildner.\"
216338e2dSSascha Wildner.\" Copyright (c) 2006 The DragonFly Project.  All rights reserved.
316338e2dSSascha Wildner.\"
416338e2dSSascha Wildner.\" Redistribution and use in source and binary forms, with or without
516338e2dSSascha Wildner.\" modification, are permitted provided that the following conditions
616338e2dSSascha Wildner.\" are met:
716338e2dSSascha Wildner.\"
816338e2dSSascha Wildner.\" 1. Redistributions of source code must retain the above copyright
916338e2dSSascha Wildner.\"    notice, this list of conditions and the following disclaimer.
1016338e2dSSascha Wildner.\" 2. Redistributions in binary form must reproduce the above copyright
1116338e2dSSascha Wildner.\"    notice, this list of conditions and the following disclaimer in
1216338e2dSSascha Wildner.\"    the documentation and/or other materials provided with the
1316338e2dSSascha Wildner.\"    distribution.
1416338e2dSSascha Wildner.\" 3. Neither the name of The DragonFly Project nor the names of its
1516338e2dSSascha Wildner.\"    contributors may be used to endorse or promote products derived
1616338e2dSSascha Wildner.\"    from this software without specific, prior written permission.
1716338e2dSSascha Wildner.\"
1816338e2dSSascha Wildner.\" THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
1916338e2dSSascha Wildner.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
2016338e2dSSascha Wildner.\" LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
2116338e2dSSascha Wildner.\" FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
2216338e2dSSascha Wildner.\" COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
2316338e2dSSascha Wildner.\" INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
2416338e2dSSascha Wildner.\" BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
2516338e2dSSascha Wildner.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
2616338e2dSSascha Wildner.\" AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
2716338e2dSSascha Wildner.\" OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
2816338e2dSSascha Wildner.\" OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2916338e2dSSascha Wildner.\" SUCH DAMAGE.
3016338e2dSSascha Wildner.\"
31*deff95cbSSascha Wildner.Dd April 10, 2010
3216338e2dSSascha Wildner.Os
3316338e2dSSascha Wildner.Dt SPINLOCK 9
3416338e2dSSascha Wildner.Sh NAME
3516338e2dSSascha Wildner.Nm spin_init ,
3616338e2dSSascha Wildner.Nm spin_lock_rd ,
3716338e2dSSascha Wildner.Nm spin_lock_rd_quick ,
3816338e2dSSascha Wildner.Nm spin_lock_wr ,
3916338e2dSSascha Wildner.Nm spin_lock_wr_quick ,
4016338e2dSSascha Wildner.Nm spin_trylock_wr ,
4116338e2dSSascha Wildner.Nm spin_uninit ,
4216338e2dSSascha Wildner.Nm spin_unlock_rd ,
4316338e2dSSascha Wildner.Nm spin_unlock_rd_quick ,
4416338e2dSSascha Wildner.Nm spin_unlock_wr ,
4516338e2dSSascha Wildner.Nm spin_unlock_wr_quick
4616338e2dSSascha Wildner.Nd core spinlocks
4716338e2dSSascha Wildner.Sh SYNOPSIS
4816338e2dSSascha Wildner.In sys/spinlock.h
4916338e2dSSascha Wildner.In sys/spinlock2.h
5016338e2dSSascha Wildner.Ft void
5116338e2dSSascha Wildner.Fn spin_init "struct spinlock *mtx"
5216338e2dSSascha Wildner.Ft void
5316338e2dSSascha Wildner.Fn spin_uninit "struct spinlock *mtx"
5416338e2dSSascha Wildner.Ft void
5516338e2dSSascha Wildner.Fn spin_lock_rd "struct spinlock *mtx"
5616338e2dSSascha Wildner.Ft void
5716338e2dSSascha Wildner.Fn spin_lock_rd_quick "globaldata_t gd" "struct spinlock *mtx"
5816338e2dSSascha Wildner.Ft void
5916338e2dSSascha Wildner.Fn spin_unlock_rd "struct spinlock *mtx"
6016338e2dSSascha Wildner.Ft void
6116338e2dSSascha Wildner.Fn spin_unlock_rd_quick "globaldata_t gd" "struct spinlock *mtx"
6216338e2dSSascha Wildner.Ft void
6316338e2dSSascha Wildner.Fn spin_lock_wr "struct spinlock *mtx"
6416338e2dSSascha Wildner.Ft void
6516338e2dSSascha Wildner.Fn spin_lock_wr_quick "globaldata_t gd" "struct spinlock *mtx"
6616338e2dSSascha Wildner.Ft boolean_t
6716338e2dSSascha Wildner.Fn spin_trylock_wr "struct spinlock *mtx"
6816338e2dSSascha Wildner.Ft void
6916338e2dSSascha Wildner.Fn spin_unlock_wr "struct spinlock *mtx"
7016338e2dSSascha Wildner.Ft void
7116338e2dSSascha Wildner.Fn spin_unlock_wr_quick "globaldata_t gd" "struct spinlock *mtx"
7216338e2dSSascha Wildner.Sh DESCRIPTION
7316338e2dSSascha WildnerThe
7416338e2dSSascha Wildner.Fa spinlock
7516338e2dSSascha Wildnerstructure and call API are defined in the
7616338e2dSSascha Wildner.In sys/spinlock.h
7716338e2dSSascha Wildnerand
7816338e2dSSascha Wildner.In sys/spinlock2.h
7916338e2dSSascha Wildnerheader files, respectively.
8016338e2dSSascha Wildner.Pp
8116338e2dSSascha WildnerThe
8216338e2dSSascha Wildner.Fn spin_init
8316338e2dSSascha Wildnerfunction initializes a new
8416338e2dSSascha Wildner.Fa spinlock
8516338e2dSSascha Wildnerstructure for use.
8616338e2dSSascha WildnerThe structure is cleaned up with
8716338e2dSSascha Wildner.Fn spin_uninit
8816338e2dSSascha Wildnerwhen it is no longer needed.
8916338e2dSSascha Wildner.Pp
9016338e2dSSascha WildnerThe
9116338e2dSSascha Wildner.Fn spin_lock_rd
9216338e2dSSascha Wildnerfunction obtains a shared
9316338e2dSSascha Wildner.Em read-only
9416338e2dSSascha Wildnerspinlock.
956196d487SMatthew DillonA thread may hold only one shared lock at a time, and may not acquire any
966196d487SMatthew Dillonnew exclusive locks while holding a shared lock (but may already be holding
9735b4e70bSSascha Wildnersome).
9835b4e70bSSascha WildnerA shared spinlock can be held by multiple CPUs concurrently.
9916338e2dSSascha WildnerIf a thread attempts to obtain an exclusive spinlock while shared
10035b4e70bSSascha Wildnerreferences from other CPUs exist it will spin until the shared references
1016196d487SMatthew Dillongo away.
10216338e2dSSascha WildnerNo new shared references will be allowed (that is, new shared requests
10316338e2dSSascha Wildnerwill also spin) while the exclusive spinlock is being acquired.
10416338e2dSSascha WildnerIf you have the current CPU's
10516338e2dSSascha Wildner.Fa globaldata
10616338e2dSSascha Wildnerpointer in hand you can call
10716338e2dSSascha Wildner.Fn spin_lock_rd_quick ,
10816338e2dSSascha Wildnerbut most code will just call the normal version.
10916338e2dSSascha WildnerShared spinlocks reserve a bit in the spinlock's memory for each CPU
11016338e2dSSascha Wildnerand do not clear the bit once set.
11116338e2dSSascha WildnerThis means that once set, a shared spinlock does not need to issue a
11216338e2dSSascha Wildnerlocked read-modify-write bus cycle to the spinlock's memory, which in
11316338e2dSSascha Wildnerturn greatly reduces conflicts between CPU caches.
1144331bf91SMatthew DillonThe bit is cleared via a different mechanism only when an exclusive
1154331bf91SMatthew Dillonspinlock is acquired.
11616338e2dSSascha WildnerThe result is extremely low overheads even when a shared spinlock is
11716338e2dSSascha Wildnerbeing operated upon concurrently by multiple CPUs.
11816338e2dSSascha Wildner.Pp
11916338e2dSSascha WildnerA previously obtained shared spinlock is released by calling either
12016338e2dSSascha Wildner.Fn spin_unlock_rd
12116338e2dSSascha Wildneror
12216338e2dSSascha Wildner.Fn spin_unlock_rd_quick .
12316338e2dSSascha Wildner.Pp
12416338e2dSSascha WildnerThe
12516338e2dSSascha Wildner.Fn spin_lock_wr
12616338e2dSSascha Wildnerfunction obtains an exclusive
12716338e2dSSascha Wildner.Em read-write
12816338e2dSSascha Wildnerspinlock.
12916338e2dSSascha WildnerA thread may hold any number of exclusive spinlocks but should always
13035b4e70bSSascha Wildnerbe mindful of ordering deadlocks.
13135b4e70bSSascha WildnerExclusive spinlocks can only be safely
1326196d487SMatthew Dillonacquired if no shared spinlocks are held.
13316338e2dSSascha WildnerThe
13416338e2dSSascha Wildner.Fn spin_trylock_wr
13516338e2dSSascha Wildnerfunction will return
13616338e2dSSascha Wildner.Dv TRUE
13716338e2dSSascha Wildnerif the spinlock was successfully obtained and
13816338e2dSSascha Wildner.Dv FALSE
13916338e2dSSascha Wildnerif it wasn't.
14016338e2dSSascha WildnerIf you have the current CPU's
14116338e2dSSascha Wildner.Fa globaldata
14216338e2dSSascha Wildnerpointer in hand you can call
14316338e2dSSascha Wildner.Fn spin_lock_wr_quick ,
14416338e2dSSascha Wildnerbut most code will just call the normal version.
14516338e2dSSascha WildnerA spinlock used only for exclusive access has about the same overhead
14616338e2dSSascha Wildneras a mutex based on a locked bus cycle.
14716338e2dSSascha WildnerWhen used in a mixed shared/exclusive environment, however, additional
14816338e2dSSascha Wildneroverhead may be incurred to obtain the exclusive spinlock.
14916338e2dSSascha WildnerBecause shared spinlocks are left intact even after released (to
15016338e2dSSascha Wildneroptimize shared spinlock performance), the exclusive spinlock code
15116338e2dSSascha Wildnermust run through any shared bits it finds in the spinlock, clear them,
15216338e2dSSascha Wildnerand check the related CPU's
15316338e2dSSascha Wildner.Fa globaldata
15416338e2dSSascha Wildnerstructure to determine whether it needs to spin or not.
15516338e2dSSascha Wildner.Pp
15616338e2dSSascha WildnerA previously obtained exclusive spinlock is released by calling either
15716338e2dSSascha Wildner.Fn spin_unlock_wr
15816338e2dSSascha Wildneror
15916338e2dSSascha Wildner.Fn spin_unlock_wr_quick .
16016338e2dSSascha Wildner.Sh IMPLEMENTATION NOTES
16116338e2dSSascha WildnerA thread may not hold any spinlock across a blocking condition or
16216338e2dSSascha Wildnerthread switch.
16316338e2dSSascha WildnerLWKT tokens should be used for situations where you want an exclusive
16416338e2dSSascha Wildnerrun-time lock that will survive a blocking condition or thread switch.
16516338e2dSSascha WildnerTokens will be automatically unlocked when a thread switches away and
16616338e2dSSascha Wildnerrelocked when the thread is switched back in.
16716338e2dSSascha WildnerIf you want a lock that survives a blocking condition or thread switch
16816338e2dSSascha Wildnerwithout being released, use
16916338e2dSSascha Wildner.Xr lockmgr 9
17016338e2dSSascha Wildnerlocks or LWKT reader/writer locks.
17116338e2dSSascha Wildner.Pp
17216338e2dSSascha Wildner.Dx Ap s
17316338e2dSSascha Wildnercore spinlocks should only be used around small contained sections of
17416338e2dSSascha Wildnercode.
17516338e2dSSascha WildnerFor example, to manage a reference count or to implement higher level
17616338e2dSSascha Wildnerlocking mechanisms.
17716338e2dSSascha WildnerBoth the token code and the
17816338e2dSSascha Wildner.Xr lockmgr 9
17916338e2dSSascha Wildnercode use exclusive spinlocks internally.
18016338e2dSSascha WildnerCore spinlocks should not be used around large chunks of code.
18116338e2dSSascha Wildner.Pp
18216338e2dSSascha WildnerHolding one or more spinlocks will disable thread preemption by
18316338e2dSSascha Wildneranother thread (e.g. preemption by an interrupt thread), but will not
18416338e2dSSascha Wildnerdisable FAST interrupts or IPIs.
18530946a66SNuno AntunesThis means that a FAST interrupt can still operate during a spinlock,
18630946a66SNuno Antunesand any threaded interrupt (which is basically all interrupts except
18730946a66SNuno Antunesthe clock interrupt) will still be scheduled for later execution, but
18830946a66SNuno Antuneswill not be able to preempt the current thread.
18916338e2dSSascha WildnerIf you wish to disable FAST interrupts and IPIs you need to enter a
1904331bf91SMatthew Dilloncritical section prior to obtaining the spinlock.
1914331bf91SMatthew Dillon.Pp
1924331bf91SMatthew DillonCurrently, FAST interrupts, including IPI messages, are not allowed to
19335b4e70bSSascha Wildneracquire any spinlocks.
19435b4e70bSSascha WildnerIt is possible to work around this if
19535b4e70bSSascha Wildner.Va mycpu->gd_spinlocks_wr
19635b4e70bSSascha Wildnerand
19735b4e70bSSascha Wildner.Va mycpu->gd_spinlocks_rd
19835b4e70bSSascha Wildnerare both 0.
19935b4e70bSSascha WildnerIf one
2004331bf91SMatthew Dillonor the other is not zero, the FAST interrupt or IPI cannot acquire
2014331bf91SMatthew Dillonany spinlocks without risking a deadlock, even if the spinlocks in
2024331bf91SMatthew Dillonquestion are not related.
20316338e2dSSascha Wildner.Pp
20416338e2dSSascha WildnerA thread may hold any number of exclusive
20516338e2dSSascha Wildner.Em read-write
2064331bf91SMatthew Dillonspinlocks.
2074331bf91SMatthew DillonHowever, a thread may only hold one shared
20816338e2dSSascha Wildner.Em read-only
2096196d487SMatthew Dillonspinlock, and may not acquire any new exclusive locks while it is holding
21035b4e70bSSascha Wildnerthat one shared lock.
21135b4e70bSSascha WildnerThis requirement is due to the method exclusive
2124331bf91SMatthew Dillonspinlocks use to determine when they can clear cached shared bits in
21335b4e70bSSascha Wildnerthe lock.
21435b4e70bSSascha WildnerIf an exclusive lock is acquired while holding shared locks,
2154331bf91SMatthew Dillona deadlock can occur even if the locks are unrelated.
21616338e2dSSascha WildnerAlways be mindful of potential deadlocks.
21716338e2dSSascha Wildner.Pp
21816338e2dSSascha WildnerSpinlocks spin.
21916338e2dSSascha WildnerA thread will not block, switch away, or lose its critical section
22016338e2dSSascha Wildnerwhile obtaining or releasing a spinlock.
22116338e2dSSascha WildnerSpinlocks do not use IPIs or other mechanisms.
22216338e2dSSascha WildnerThey are considered to be a very low level mechanism.
22316338e2dSSascha Wildner.Pp
22416338e2dSSascha WildnerIf a spinlock can not be obtained after one second a warning will be
22516338e2dSSascha Wildnerprinted on the console.
2266196d487SMatthew DillonIf a system panic occurs, spinlocks will succeed after one second in
22716338e2dSSascha Wildnerorder to allow the panic operation to proceed.
22816338e2dSSascha Wildner.Pp
22916338e2dSSascha WildnerIf you have a complex structure such as a
23016338e2dSSascha Wildner.Xr vnode 9
23116338e2dSSascha Wildnerwhich contains a token or
23216338e2dSSascha Wildner.Xr lockmgr 9
23316338e2dSSascha Wildnerlock, it is legal to directly access the internal spinlock embedded
2346196d487SMatthew Dillonin those structures for other purposes as long as the spinlock is not
23535b4e70bSSascha Wildnerheld when you issue the token or
23635b4e70bSSascha Wildner.Xr lockmgr 9
23735b4e70bSSascha Wildneroperation.
238*deff95cbSSascha Wildner.Sh FILES
239*deff95cbSSascha WildnerThe uncontended path of the spinlock implementation is in
240*deff95cbSSascha Wildner.Pa /sys/sys/spinlock2.h .
241*deff95cbSSascha WildnerThe core of the spinlock implementation is in
242*deff95cbSSascha Wildner.Pa /sys/kern/kern_spinlock.c .
24316338e2dSSascha Wildner.Sh SEE ALSO
244e1700543SSascha Wildner.Xr crit_enter 9 ,
245a8b21083SSascha Wildner.Xr lockmgr 9 ,
246e1700543SSascha Wildner.Xr serializer 9
24716338e2dSSascha Wildner.Sh HISTORY
24816338e2dSSascha WildnerA
24916338e2dSSascha Wildner.Nm spinlock
25016338e2dSSascha Wildnerimplementation first appeared in
25116338e2dSSascha Wildner.Dx 1.3 .
25216338e2dSSascha Wildner.Sh AUTHORS
25316338e2dSSascha Wildner.An -nosplit
25416338e2dSSascha WildnerThe original
25516338e2dSSascha Wildner.Nm spinlock
25616338e2dSSascha Wildnerimplementation was written by
25716338e2dSSascha Wildner.An Jeffrey M. Hsu
25816338e2dSSascha Wildnerand was later extended by
25916338e2dSSascha Wildner.An Matthew Dillon .
26016338e2dSSascha WildnerThis manual page was written by
26116338e2dSSascha Wildner.An Matthew Dillon
26216338e2dSSascha Wildnerand
26316338e2dSSascha Wildner.An Sascha Wildner .
264