xref: /freebsd/share/man/man9/epoch.9 (revision 33346ed65c9b6c90f92085741cc9887c299b3a22)
1*33346ed6SMatt Macy.\"
2*33346ed6SMatt Macy.\" Copyright (C) 2018 Matthew Macy <mmacy@FreeBSD.org>.
3*33346ed6SMatt Macy.\"
4*33346ed6SMatt Macy.\" Redistribution and use in source and binary forms, with or without
5*33346ed6SMatt Macy.\" modification, are permitted provided that the following conditions
6*33346ed6SMatt Macy.\" are met:
7*33346ed6SMatt Macy.\" 1. Redistributions of source code must retain the above copyright
8*33346ed6SMatt Macy.\"    notice(s), this list of conditions and the following disclaimer as
9*33346ed6SMatt Macy.\"    the first lines of this file unmodified other than the possible
10*33346ed6SMatt Macy.\"    addition of one or more copyright notices.
11*33346ed6SMatt Macy.\" 2. Redistributions in binary form must reproduce the above copyright
12*33346ed6SMatt Macy.\"    notice(s), this list of conditions and the following disclaimer in the
13*33346ed6SMatt Macy.\"    documentation and/or other materials provided with the distribution.
14*33346ed6SMatt Macy.\"
15*33346ed6SMatt Macy.\" THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) ``AS IS'' AND ANY
16*33346ed6SMatt Macy.\" EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17*33346ed6SMatt Macy.\" WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18*33346ed6SMatt Macy.\" DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) BE LIABLE FOR ANY
19*33346ed6SMatt Macy.\" DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
20*33346ed6SMatt Macy.\" (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
21*33346ed6SMatt Macy.\" SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
22*33346ed6SMatt Macy.\" CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23*33346ed6SMatt Macy.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24*33346ed6SMatt Macy.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
25*33346ed6SMatt Macy.\" DAMAGE.
26*33346ed6SMatt Macy.\"
27*33346ed6SMatt Macy.\" $FreeBSD$
28*33346ed6SMatt Macy.\"
29*33346ed6SMatt Macy.Dd May 13, 2018
30*33346ed6SMatt Macy.Dt EPOCH 9
31*33346ed6SMatt Macy.Os
32*33346ed6SMatt Macy.Sh NAME
33*33346ed6SMatt Macy.Nm epoch ,
34*33346ed6SMatt Macy.Nm epoch_context ,
35*33346ed6SMatt Macy.Nm epoch_alloc ,
36*33346ed6SMatt Macy.Nm epoch_free ,
37*33346ed6SMatt Macy.Nm epoch_enter ,
38*33346ed6SMatt Macy.Nm epoch_exit ,
39*33346ed6SMatt Macy.Nm epoch_wait ,
40*33346ed6SMatt Macy.Nm epoch_call ,
41*33346ed6SMatt Macy.Nm in_epoch ,
42*33346ed6SMatt Macy.Nd kernel epoch based reclaimation
43*33346ed6SMatt Macy.Sh SYNOPSIS
44*33346ed6SMatt Macy.In sys/param.h
45*33346ed6SMatt Macy.In sys/proc.h
46*33346ed6SMatt Macy.In sys/epoch.h
47*33346ed6SMatt Macy.Ft epoch_t
48*33346ed6SMatt Macy.Fn epoch_alloc "void"
49*33346ed6SMatt Macy.Ft void
50*33346ed6SMatt Macy.Fn epoch_enter "epoch_t epoch"
51*33346ed6SMatt Macy.Ft void
52*33346ed6SMatt Macy.Fn epoch_exit "epoch_t epoch"
53*33346ed6SMatt Macy.Ft void
54*33346ed6SMatt Macy.Fn epoch_wait "epoch_t epoch"
55*33346ed6SMatt Macy.Ft void
56*33346ed6SMatt Macy.Fn epoch_call "epoch_t epoch" "epoch_context_t ctx" "void (*callback) (epoch_context_t)"
57*33346ed6SMatt Macy.Ft int
58*33346ed6SMatt Macy.Fn in_epoch "void"
59*33346ed6SMatt Macy.Sh DESCRIPTION
60*33346ed6SMatt MacyEpochs are used to guarantee liveness and immutability of data by
61*33346ed6SMatt Macydeferring reclamation and mutation until a grace period has elapsed.
62*33346ed6SMatt MacyEpochs do not have any lock ordering issues. Entering and leaving
63*33346ed6SMatt Macyan epoch section will never block.
64*33346ed6SMatt Macy.Pp
65*33346ed6SMatt MacyEpochs are allocated with
66*33346ed6SMatt Macy.Fn epoch_alloc
67*33346ed6SMatt Macyand freed with
68*33346ed6SMatt Macy.Fn epoch_free .
69*33346ed6SMatt MacyThreads indicate the start of an epoch critical section by calling
70*33346ed6SMatt Macy.Fn epoch_enter .
71*33346ed6SMatt MacyThe end of a critical section is indicated by calling
72*33346ed6SMatt Macy.Fn epoch_exit .
73*33346ed6SMatt MacyA thread can wait until a grace period has elapsed
74*33346ed6SMatt Macysince any threads have entered
75*33346ed6SMatt Macythe epoch by calling
76*33346ed6SMatt Macy.Fn epoch_wait .
77*33346ed6SMatt MacyIf the thread can't sleep or is otherwise in a performance sensitive
78*33346ed6SMatt Macypath it can ensure that a grace period has elapsed by calling
79*33346ed6SMatt Macy.Fn epoch_call
80*33346ed6SMatt Macywith a callback with any work that needs to wait for an epoch to elapse.
81*33346ed6SMatt MacyOnly non-sleepable locks can be acquired during a section protected by
82*33346ed6SMatt Macy.Fn epoch_enter
83*33346ed6SMatt Macyand
84*33346ed6SMatt Macy.Fn epoch_exit .
85*33346ed6SMatt MacyINVARIANTS can assert that a thread is in an epoch by using
86*33346ed6SMatt Macy.Fn in_epoch .
87*33346ed6SMatt Macy.Pp
88*33346ed6SMatt MacyThe epoch API currently does not support sleeping in epoch sections.
89*33346ed6SMatt MacyA caller cannot do epoch_enter recursively on different epochs. A
90*33346ed6SMatt Macycaller should never call
91*33346ed6SMatt Macy.Fn epoch_wait
92*33346ed6SMatt Macyin the middle of an epoch section as this will lead to a deadlock.
93*33346ed6SMatt Macy.Pp
94*33346ed6SMatt MacyNote that epochs are not a straight replacement for read locks. Callers
95*33346ed6SMatt Macymust use safe list and tailq traversal routines in an epoch (see ck_queue).
96*33346ed6SMatt MacyWhen modifying a list referenced from an epoch section safe removal
97*33346ed6SMatt Macyroutines must be used and the caller can no longer modify a list entry
98*33346ed6SMatt Macyin place. An item to be modified must be handled with copy on write
99*33346ed6SMatt Macyand frees must be deferred until after a grace period has elapsed.
100*33346ed6SMatt Macy
101*33346ed6SMatt Macy.Sh RETURN VALUES
102*33346ed6SMatt Macy.Fn in_epoch
103*33346ed6SMatt Macywill return 1 if curthread is in an epoch, 0 otherwise.
104*33346ed6SMatt Macy.Sh EXAMPLES
105*33346ed6SMatt MacyAsync free example:
106*33346ed6SMatt Macy
107*33346ed6SMatt MacyThread 1:
108*33346ed6SMatt Macy.Bd -literal
109*33346ed6SMatt Macy{
110*33346ed6SMatt Macy    epoch_enter(net_epoch);
111*33346ed6SMatt Macy    CK_STAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
112*33346ed6SMatt Macy        sa = ifa->ifa_addr;
113*33346ed6SMatt Macy	if (sa->sa_family != AF_INET)
114*33346ed6SMatt Macy	    continue;
115*33346ed6SMatt Macy	sin = (struct sockaddr_in *)sa;
116*33346ed6SMatt Macy	if (prison_check_ip4(cred, &sin->sin_addr) == 0) {
117*33346ed6SMatt Macy	     ia = (struct in_ifaddr *)ifa;
118*33346ed6SMatt Macy	     break;
119*33346ed6SMatt Macy	}
120*33346ed6SMatt Macy    }
121*33346ed6SMatt Macy    epoch_exit(net_epoch);
122*33346ed6SMatt Macy}
123*33346ed6SMatt Macy.Ed
124*33346ed6SMatt MacyThread 2:
125*33346ed6SMatt Macy.Bd -literal
126*33346ed6SMatt Macyvoid
127*33346ed6SMatt Macyifa_free(struct ifaddr *ifa)
128*33346ed6SMatt Macy{
129*33346ed6SMatt Macy
130*33346ed6SMatt Macy    if (refcount_release(&ifa->ifa_refcnt))
131*33346ed6SMatt Macy        epoch_call(net_epoch, &ifa->ifa_epoch_ctx, ifa_destroy);
132*33346ed6SMatt Macy}
133*33346ed6SMatt Macy
134*33346ed6SMatt Macy{
135*33346ed6SMatt Macy
136*33346ed6SMatt Macy    IF_ADDR_WLOCK(ifp);
137*33346ed6SMatt Macy    CK_STAILQ_REMOVE(&ifp->if_addrhead, ifa, ifaddr, ifa_link);
138*33346ed6SMatt Macy    /* mark as unlinked */
139*33346ed6SMatt Macy    ifa->ifa_addr->sa_family = AF_UNSPEC;
140*33346ed6SMatt Macy    IF_ADDR_WUNLOCK(ifp);
141*33346ed6SMatt Macy    ifa_free(ifa);
142*33346ed6SMatt Macy}
143*33346ed6SMatt Macy.Ed
144*33346ed6SMatt Macy.Pp
145*33346ed6SMatt MacyThread 1 traverses the ifaddr list in an epoch. Thread 2 unlinks
146*33346ed6SMatt Macywith the corresponding epoch safe macro, marks as logically free,
147*33346ed6SMatt Macyand then defers deletion. More general mutation or a synchronous
148*33346ed6SMatt Macyfree would have to follow a a call to
149*33346ed6SMatt Macy.Fn epoch_wait .
150*33346ed6SMatt Macy.Sh ERRORS
151*33346ed6SMatt MacyNone.
152*33346ed6SMatt Macy.El
153*33346ed6SMatt Macy.Sh SEE ALSO
154*33346ed6SMatt Macy.Xr locking 9 ,
155*33346ed6SMatt Macy.Xr mtx_pool 9 ,
156*33346ed6SMatt Macy.Xr mutex 9 ,
157*33346ed6SMatt Macy.Xr rwlock 9 ,
158*33346ed6SMatt Macy.Xr sema 9 ,
159*33346ed6SMatt Macy.Xr sleep 9 ,
160*33346ed6SMatt Macy.Xr sx 9 ,
161*33346ed6SMatt Macy.Xr timeout 9
162