xref: /freebsd/share/man/man9/rmlock.9 (revision cd32bd7ad19a39a19789ffcc4d70dca646c3914b)
1f53d15feSStephan Uphoff.\" Copyright (c) 2007 Stephan Uphoff <ups@FreeBSD.org>
2f53d15feSStephan Uphoff.\" Copyright (c) 2006 Gleb Smirnoff <glebius@FreeBSD.org>
3f53d15feSStephan Uphoff.\" All rights reserved.
4f53d15feSStephan Uphoff.\"
5f53d15feSStephan Uphoff.\" Redistribution and use in source and binary forms, with or without
6f53d15feSStephan Uphoff.\" modification, are permitted provided that the following conditions
7f53d15feSStephan Uphoff.\" are met:
8f53d15feSStephan Uphoff.\" 1. Redistributions of source code must retain the above copyright
9f53d15feSStephan Uphoff.\"    notice, this list of conditions and the following disclaimer.
10f53d15feSStephan Uphoff.\" 2. Redistributions in binary form must reproduce the above copyright
11f53d15feSStephan Uphoff.\"    notice, this list of conditions and the following disclaimer in the
12f53d15feSStephan Uphoff.\"    documentation and/or other materials provided with the distribution.
13f53d15feSStephan Uphoff.\"
14f53d15feSStephan Uphoff.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15f53d15feSStephan Uphoff.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16f53d15feSStephan Uphoff.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17f53d15feSStephan Uphoff.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18f53d15feSStephan Uphoff.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19f53d15feSStephan Uphoff.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20f53d15feSStephan Uphoff.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21f53d15feSStephan Uphoff.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22f53d15feSStephan Uphoff.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23f53d15feSStephan Uphoff.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24f53d15feSStephan Uphoff.\" SUCH DAMAGE.
25f53d15feSStephan Uphoff.\"
26f53d15feSStephan Uphoff.\" $FreeBSD$
27f53d15feSStephan Uphoff.\"
28f53d15feSStephan Uphoff.\" Based on rwlock.9 man page
29*cd32bd7aSJohn Baldwin.Dd June 25, 2013
30f53d15feSStephan Uphoff.Dt RMLOCK 9
31f53d15feSStephan Uphoff.Os
32f53d15feSStephan Uphoff.Sh NAME
33f53d15feSStephan Uphoff.Nm rmlock ,
34f53d15feSStephan Uphoff.Nm rm_init ,
351a109c1cSRobert Watson.Nm rm_init_flags ,
36f53d15feSStephan Uphoff.Nm rm_destroy ,
37f53d15feSStephan Uphoff.Nm rm_rlock ,
3836058c09SMax Laier.Nm rm_try_rlock ,
39f53d15feSStephan Uphoff.Nm rm_wlock ,
40f53d15feSStephan Uphoff.Nm rm_runlock ,
41f53d15feSStephan Uphoff.Nm rm_wunlock ,
42433ea89aSRobert Watson.Nm rm_wowned ,
43*cd32bd7aSJohn Baldwin.Nm rm_sleep ,
44*cd32bd7aSJohn Baldwin.Nm rm_assert ,
45f53d15feSStephan Uphoff.Nm RM_SYSINIT
468403b193SJohn Baldwin.Nd kernel reader/writer lock optimized for read-mostly access patterns
47f53d15feSStephan Uphoff.Sh SYNOPSIS
48f53d15feSStephan Uphoff.In sys/param.h
49f53d15feSStephan Uphoff.In sys/lock.h
50f53d15feSStephan Uphoff.In sys/rmlock.h
51f53d15feSStephan Uphoff.Ft void
521a109c1cSRobert Watson.Fn rm_init "struct rmlock *rm" "const char *name"
531a109c1cSRobert Watson.Ft void
541a109c1cSRobert Watson.Fn rm_init_flags "struct rmlock *rm" "const char *name" "int opts"
55f53d15feSStephan Uphoff.Ft void
56f53d15feSStephan Uphoff.Fn rm_destroy "struct rmlock *rm"
57f53d15feSStephan Uphoff.Ft void
58f53d15feSStephan Uphoff.Fn rm_rlock "struct rmlock *rm"  "struct rm_priotracker* tracker"
5936058c09SMax Laier.Ft int
6036058c09SMax Laier.Fn rm_try_rlock "struct rmlock *rm"  "struct rm_priotracker* tracker"
61f53d15feSStephan Uphoff.Ft void
62f53d15feSStephan Uphoff.Fn rm_wlock "struct rmlock *rm"
63f53d15feSStephan Uphoff.Ft void
64f53d15feSStephan Uphoff.Fn rm_runlock "struct rmlock *rm" "struct rm_priotracker* tracker"
65f53d15feSStephan Uphoff.Ft void
66f53d15feSStephan Uphoff.Fn rm_wunlock "struct rmlock *rm"
67433ea89aSRobert Watson.Ft int
68d576deedSPawel Jakub Dawidek.Fn rm_wowned "const struct rmlock *rm"
69*cd32bd7aSJohn Baldwin.Ft int
70*cd32bd7aSJohn Baldwin.Fn rm_sleep "void *wchan" "struct rmlock *rm" "int priority" "const char *wmesg" "int timo"
71*cd32bd7aSJohn Baldwin.Pp
72*cd32bd7aSJohn Baldwin.Cd "options INVARIANTS"
73*cd32bd7aSJohn Baldwin.Cd "options INVARIANT_SUPPORT"
74*cd32bd7aSJohn Baldwin.Ft void
75*cd32bd7aSJohn Baldwin.Fn rm_assert "struct rmlock *rm" "int what"
76f53d15feSStephan Uphoff.In sys/kernel.h
77f53d15feSStephan Uphoff.Fn RM_SYSINIT "name" "struct rmlock *rm" "const char *desc" "int opts"
78f53d15feSStephan Uphoff.Sh DESCRIPTION
798403b193SJohn BaldwinRead-mostly locks allow shared access to protected data by multiple threads,
80f53d15feSStephan Uphoffor exclusive access by a single thread.
81f53d15feSStephan UphoffThe threads with shared access are known as
82f53d15feSStephan Uphoff.Em readers
83f53d15feSStephan Uphoffsince they only read the protected data.
84f53d15feSStephan UphoffA thread with exclusive access is known as a
85f53d15feSStephan Uphoff.Em writer
86f53d15feSStephan Uphoffsince it can modify protected data.
87f53d15feSStephan Uphoff.Pp
888403b193SJohn BaldwinRead-mostly locks are designed to be efficient for locks almost exclusively
89989cbe40SHiten Pandyaused as reader locks and as such should be used for protecting data that
90989cbe40SHiten Pandyararely changes.
918403b193SJohn BaldwinAcquiring an exclusive lock after the lock has been locked for shared access
92989cbe40SHiten Pandyais an expensive operation.
93f53d15feSStephan Uphoff.Pp
948403b193SJohn BaldwinNormal read-mostly locks are similar to
958403b193SJohn Baldwin.Xr rwlock 9
968403b193SJohn Baldwinlocks and follow the same lock ordering rules as
978403b193SJohn Baldwin.Xr rwlock 9
988403b193SJohn Baldwinlocks.
998403b193SJohn BaldwinRead-mostly locks have full priority propagation like mutexes.
100f53d15feSStephan UphoffUnlike
1018403b193SJohn Baldwin.Xr rwlock 9 ,
1028403b193SJohn Baldwinread-mostly locks propagate priority to both readers and writers.
1038403b193SJohn BaldwinThis is implemented via the
104989cbe40SHiten Pandya.Va rm_priotracker
1058403b193SJohn Baldwinstructure argument supplied to
106989cbe40SHiten Pandya.Fn rm_rlock
107989cbe40SHiten Pandyaand
1088403b193SJohn Baldwin.Fn rm_runlock .
1098403b193SJohn BaldwinReaders can recurse if the lock is initialized with the
1108403b193SJohn Baldwin.Dv RM_RECURSE
1118403b193SJohn Baldwinoption;
1128403b193SJohn Baldwinhowever, writers are never allowed to recurse.
1138403b193SJohn Baldwin.Pp
1148403b193SJohn BaldwinSleepable read-mostly locks are created by passing
1158403b193SJohn Baldwin.Dv RM_SLEEPABLE
1168403b193SJohn Baldwinto
1178403b193SJohn Baldwin.Fn rm_init_flags .
1188403b193SJohn BaldwinUnlike normal read-mostly locks,
1198403b193SJohn Baldwinsleepable read-mostly locks follow the same lock ordering rules as
1208403b193SJohn Baldwin.Xr sx 9
1218403b193SJohn Baldwinlocks.
1228403b193SJohn BaldwinSleepable read-mostly locks do not propagate priority to writers,
1238403b193SJohn Baldwinbut they do propagate priority to readers.
1248403b193SJohn BaldwinWriters are permitted to sleep while holding a read-mostly lock,
1258403b193SJohn Baldwinbut readers are not.
1268403b193SJohn BaldwinUnlike other sleepable locks such as
1278403b193SJohn Baldwin.Xr sx 9
1288403b193SJohn Baldwinlocks,
1298403b193SJohn Baldwinreaders must use try operations on other sleepable locks to avoid sleeping.
130f53d15feSStephan Uphoff.Ss Macros and Functions
131f53d15feSStephan Uphoff.Bl -tag -width indent
1321a109c1cSRobert Watson.It Fn rm_init "struct rmlock *rm" "const char *name"
1338403b193SJohn BaldwinInitialize the read-mostly lock
1348403b193SJohn Baldwin.Fa rm .
1358403b193SJohn BaldwinThe
1368403b193SJohn Baldwin.Fa name
1378403b193SJohn Baldwindescription is used solely for debugging purposes.
138f53d15feSStephan UphoffThis function must be called before any other operations
139f53d15feSStephan Uphoffon the lock.
1401a109c1cSRobert Watson.It Fn rm_init_flags "struct rmlock *rm" "const char *name" "int opts"
1418403b193SJohn BaldwinSimilar to
1428403b193SJohn Baldwin.Fn rm_init ,
1438403b193SJohn Baldwininitialize the read-mostly lock
1448403b193SJohn Baldwin.Fa rm
1458403b193SJohn Baldwinwith a set of optional flags.
1468403b193SJohn BaldwinThe
1471a109c1cSRobert Watson.Fa opts
1488403b193SJohn Baldwinarguments contains one or more of the following flags:
1491a109c1cSRobert Watson.Bl -tag -width ".Dv RM_NOWITNESS"
1501a109c1cSRobert Watson.It Dv RM_NOWITNESS
1511a109c1cSRobert WatsonInstruct
1521a109c1cSRobert Watson.Xr witness 4
1531a109c1cSRobert Watsonto ignore this lock.
1541a109c1cSRobert Watson.It Dv RM_RECURSE
1558403b193SJohn BaldwinAllow threads to recursively acquire shared locks for
1561a109c1cSRobert Watson.Fa rm .
15736058c09SMax Laier.It Dv RM_SLEEPABLE
1588403b193SJohn BaldwinCreate a sleepable read-mostly lock.
1591a109c1cSRobert Watson.El
160f53d15feSStephan Uphoff.It Fn rm_rlock "struct rmlock *rm" "struct rm_priotracker* tracker"
161f53d15feSStephan UphoffLock
162f53d15feSStephan Uphoff.Fa rm
1638403b193SJohn Baldwinas a reader using
164f53d15feSStephan Uphoff.Fa tracker
165f53d15feSStephan Uphoffto track read owners of a lock for priority propagation.
166989cbe40SHiten PandyaThis data structure is only used internally by
167989cbe40SHiten Pandya.Nm
168c6d7cf7bSChristian Bruefferand must persist until
169c6d7cf7bSChristian Brueffer.Fn rm_runlock
170c6d7cf7bSChristian Bruefferhas been called.
171989cbe40SHiten PandyaThis data structure can be allocated on the stack since
1728403b193SJohn Baldwinreaders cannot sleep.
173f53d15feSStephan UphoffIf any thread holds this lock exclusively, the current thread blocks,
174f53d15feSStephan Uphoffand its priority is propagated to the exclusive holder.
175989cbe40SHiten PandyaIf the lock was initialized with the
1768403b193SJohn Baldwin.Dv RM_RECURSE
177989cbe40SHiten Pandyaoption the
178f53d15feSStephan Uphoff.Fn rm_rlock
1798403b193SJohn Baldwinfunction can be called when the current thread has already acquired reader
180f53d15feSStephan Uphoffaccess on
181f53d15feSStephan Uphoff.Fa rm .
18236058c09SMax Laier.It Fn rm_try_rlock "struct rmlock *rm" "struct rm_priotracker* tracker"
18336058c09SMax LaierTry to lock
18436058c09SMax Laier.Fa rm
18536058c09SMax Laieras a reader.
18636058c09SMax Laier.Fn rm_try_rlock
18736058c09SMax Laierwill return 0 if the lock cannot be acquired immediately;
1888403b193SJohn Baldwinotherwise,
1898403b193SJohn Baldwinthe lock will be acquired and a non-zero value will be returned.
19036058c09SMax LaierNote that
19136058c09SMax Laier.Fn rm_try_rlock
19236058c09SMax Laiermay fail even while the lock is not currently held by a writer.
1938403b193SJohn BaldwinIf the lock was initialized with the
1948403b193SJohn Baldwin.Dv RM_RECURSE
1958403b193SJohn Baldwinoption,
1968403b193SJohn Baldwin.Fn rm_try_rlock
1978403b193SJohn Baldwinwill succeed if the current thread has already acquired reader access.
198f53d15feSStephan Uphoff.It Fn rm_wlock "struct rmlock *rm"
199f53d15feSStephan UphoffLock
200f53d15feSStephan Uphoff.Fa rm
201f53d15feSStephan Uphoffas a writer.
202f53d15feSStephan UphoffIf there are any shared owners of the lock, the current thread blocks.
203f53d15feSStephan UphoffThe
204f53d15feSStephan Uphoff.Fn rm_wlock
205f53d15feSStephan Uphofffunction cannot be called recursively.
206f53d15feSStephan Uphoff.It Fn rm_runlock "struct rmlock *rm" "struct rm_priotracker* tracker"
207f53d15feSStephan UphoffThis function releases a shared lock previously acquired by
208f53d15feSStephan Uphoff.Fn rm_rlock .
209f53d15feSStephan UphoffThe
210f53d15feSStephan Uphoff.Fa tracker
211f53d15feSStephan Uphoffargument must match the
212f53d15feSStephan Uphoff.Fa tracker
213f53d15feSStephan Uphoffargument used for acquiring the shared lock
214f53d15feSStephan Uphoff.It Fn rm_wunlock "struct rmlock *rm"
215f53d15feSStephan UphoffThis function releases an exclusive lock previously acquired by
216f53d15feSStephan Uphoff.Fn rm_wlock .
217f53d15feSStephan Uphoff.It Fn rm_destroy "struct rmlock *rm"
218f53d15feSStephan UphoffThis functions destroys a lock previously initialized with
219f53d15feSStephan Uphoff.Fn rm_init .
220f53d15feSStephan UphoffThe
221f53d15feSStephan Uphoff.Fa rm
222f53d15feSStephan Uphofflock must be unlocked.
223d576deedSPawel Jakub Dawidek.It Fn rm_wowned "const struct rmlock *rm"
224433ea89aSRobert WatsonThis function returns a non-zero value if the current thread owns an
225433ea89aSRobert Watsonexclusive lock on
226433ea89aSRobert Watson.Fa rm .
227*cd32bd7aSJohn Baldwin.It Fn rm_sleep "void *wchan" "struct rmlock *rm" "int priority" "const char *wmesg" "int timo"
228*cd32bd7aSJohn BaldwinThis function atomically releases
229*cd32bd7aSJohn Baldwin.Fa rm
230*cd32bd7aSJohn Baldwinwhile waiting for an event.
231*cd32bd7aSJohn BaldwinThe
232*cd32bd7aSJohn Baldwin.Fa rm
233*cd32bd7aSJohn Baldwinlock must be exclusively locked.
234*cd32bd7aSJohn BaldwinFor more details on the parameters to this function,
235*cd32bd7aSJohn Baldwinsee
236*cd32bd7aSJohn Baldwin.Xr sleep 9 .
237*cd32bd7aSJohn Baldwin.It Fn rm_assert "struct rmlock *rm" "int what"
238*cd32bd7aSJohn BaldwinThis function asserts that the
239*cd32bd7aSJohn Baldwin.Fa rm
240*cd32bd7aSJohn Baldwinlock is in the state specified by
241*cd32bd7aSJohn Baldwin.Fa what .
242*cd32bd7aSJohn BaldwinIf the assertions are not true and the kernel is compiled with
243*cd32bd7aSJohn Baldwin.Cd "options INVARIANTS"
244*cd32bd7aSJohn Baldwinand
245*cd32bd7aSJohn Baldwin.Cd "options INVARIANT_SUPPORT" ,
246*cd32bd7aSJohn Baldwinthe kernel will panic.
247*cd32bd7aSJohn BaldwinCurrently the following base assertions are supported:
248*cd32bd7aSJohn Baldwin.Bl -tag -width ".Dv RA_UNLOCKED"
249*cd32bd7aSJohn Baldwin.It Dv RA_LOCKED
250*cd32bd7aSJohn BaldwinAssert that current thread holds either a shared or exclusive lock
251*cd32bd7aSJohn Baldwinof
252*cd32bd7aSJohn Baldwin.Fa rm .
253*cd32bd7aSJohn Baldwin.It Dv RA_RLOCKED
254*cd32bd7aSJohn BaldwinAssert that current thread holds a shared lock of
255*cd32bd7aSJohn Baldwin.Fa rm .
256*cd32bd7aSJohn Baldwin.It Dv RA_WLOCKED
257*cd32bd7aSJohn BaldwinAssert that current thread holds an exclusive lock of
258*cd32bd7aSJohn Baldwin.Fa rm .
259*cd32bd7aSJohn Baldwin.It Dv RA_UNLOCKED
260*cd32bd7aSJohn BaldwinAssert that current thread holds neither a shared nor exclusive lock of
261*cd32bd7aSJohn Baldwin.Fa rm .
262*cd32bd7aSJohn Baldwin.El
263*cd32bd7aSJohn Baldwin.Pp
264*cd32bd7aSJohn BaldwinIn addition, one of the following optional flags may be specified with
265*cd32bd7aSJohn Baldwin.Dv RA_LOCKED ,
266*cd32bd7aSJohn Baldwin.Dv RA_RLOCKED ,
267*cd32bd7aSJohn Baldwinor
268*cd32bd7aSJohn Baldwin.Dv RA_WLOCKED :
269*cd32bd7aSJohn Baldwin.Bl -tag -width ".Dv RA_NOTRECURSED"
270*cd32bd7aSJohn Baldwin.It Dv RA_RECURSED
271*cd32bd7aSJohn BaldwinAssert that the current thread holds a recursive lock of
272*cd32bd7aSJohn Baldwin.Fa rm .
273*cd32bd7aSJohn Baldwin.It Dv RA_NOTRECURSED
274*cd32bd7aSJohn BaldwinAssert that the current thread does not hold a recursive lock of
275*cd32bd7aSJohn Baldwin.Fa rm .
276*cd32bd7aSJohn Baldwin.El
277f53d15feSStephan Uphoff.El
278f53d15feSStephan Uphoff.Sh SEE ALSO
279f53d15feSStephan Uphoff.Xr locking 9 ,
280f53d15feSStephan Uphoff.Xr mutex 9 ,
281f53d15feSStephan Uphoff.Xr panic 9 ,
282f53d15feSStephan Uphoff.Xr rwlock 9 ,
283*cd32bd7aSJohn Baldwin.Xr sleep 9 ,
284f53d15feSStephan Uphoff.Xr sema 9 ,
285f53d15feSStephan Uphoff.Xr sx 9
286f53d15feSStephan Uphoff.Sh HISTORY
287f53d15feSStephan UphoffThese
288f53d15feSStephan Uphofffunctions appeared in
289f53d15feSStephan Uphoff.Fx 7.0 .
290f53d15feSStephan Uphoff.Sh AUTHORS
291f53d15feSStephan Uphoff.An -nosplit
292f53d15feSStephan UphoffThe
293f53d15feSStephan Uphoff.Nm
294f53d15feSStephan Uphofffacility was written by
295f53d15feSStephan Uphoff.An "Stephan Uphoff" .
296f53d15feSStephan UphoffThis manual page was written by
297f53d15feSStephan Uphoff.An "Gleb Smirnoff"
298989cbe40SHiten Pandyafor rwlock and modified to reflect rmlock by
299f53d15feSStephan Uphoff.An "Stephan Uphoff" .
300f53d15feSStephan Uphoff.Sh BUGS
301989cbe40SHiten PandyaThe
302989cbe40SHiten Pandya.Nm
303989cbe40SHiten Pandyaimplementation is currently not optimized for single processor systems.
304989cbe40SHiten Pandya.Pp
30536058c09SMax Laier.Fn rm_try_rlock
30636058c09SMax Laiercan fail transiently even when there is no writer, while another reader
30736058c09SMax Laierupdates the state on the local CPU.
30836058c09SMax Laier.Pp
309989cbe40SHiten PandyaThe
310989cbe40SHiten Pandya.Nm
311c6d7cf7bSChristian Bruefferimplementation uses a single per CPU list shared by all
312989cbe40SHiten Pandyarmlocks in the system.
313c6d7cf7bSChristian BruefferIf rmlocks become popular, hashing to multiple per CPU queues may
314989cbe40SHiten Pandyabe needed to speed up the writer lock process.
315