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