diff --git a/share/man/man9/epoch.9 b/share/man/man9/epoch.9 index 5ce2a2c50a5d..b15e5afcecab 100644 --- a/share/man/man9/epoch.9 +++ b/share/man/man9/epoch.9 @@ -1,5 +1,5 @@ .\" -.\" Copyright (C) 2018 Matthew Macy . +.\" Copyright (C) 2018 Matthew Macy . .\" .\" Redistribution and use in source and binary forms, with or without .\" modification, are permitted provided that the following conditions @@ -65,15 +65,15 @@ .Sh DESCRIPTION Epochs are used to guarantee liveness and immutability of data by deferring reclamation and mutation until a grace period has elapsed. -Epochs do not have any lock ordering issues. Entering and leaving -an epoch section will never block. +Epochs do not have any lock ordering issues. +Entering and leaving an epoch section will never block. .Pp Epochs are allocated with .Fn epoch_alloc and freed with .Fn epoch_free . The flags passed to epoch_alloc determine whether preemption is -allowed during a section or not (the dafult), as specified by +allowed during a section or not (the default), as specified by EPOCH_PREEMPT. Threads indicate the start of an epoch critical section by calling .Fn epoch_enter . @@ -104,16 +104,17 @@ INVARIANTS can assert that a thread is in an epoch by using .Fn in_epoch . .Pp The epoch API currently does not support sleeping in epoch_preempt sections. -A caller cannot do epoch_enter recursively on different preemptible epochs. A -caller should never call +A caller cannot do epoch_enter recursively on different preemptible epochs. +A caller should never call .Fn epoch_wait in the middle of an epoch section as this will lead to a deadlock. .Pp -Note that epochs are not a straight replacement for read locks. Callers -must use safe list and tailq traversal routines in an epoch (see ck_queue). +Note that epochs are not a straight replacement for read locks. +Callers must use safe list and tailq traversal routines in an epoch (see ck_queue). When modifying a list referenced from an epoch section safe removal routines must be used and the caller can no longer modify a list entry -in place. An item to be modified must be handled with copy on write +in place. +An item to be modified must be handled with copy on write and frees must be deferred until after a grace period has elapsed. .Sh RETURN VALUES .Fn in_epoch @@ -123,11 +124,11 @@ One must be cautious when using .Fn epoch_wait_preempt threads are pinned during epoch sections so if a thread in a section is then preempted by a higher priority compute bound thread on that CPU it can be -prevented from leaving the section. Thus the wait time for the waiter is +prevented from leaving the section. +Thus the wait time for the waiter is potentially unbounded. .Sh EXAMPLES Async free example: - Thread 1: .Bd -literal int @@ -164,7 +165,7 @@ void if_purgeaddrs(struct ifnet *ifp) { - /* .... */ + /* .... * IF_ADDR_WLOCK(ifp); CK_STAILQ_REMOVE(&ifp->if_addrhead, ifa, ifaddr, ifa_link); IF_ADDR_WUNLOCK(ifp); @@ -172,10 +173,11 @@ if_purgeaddrs(struct ifnet *ifp) } .Ed .Pp -Thread 1 traverses the ifaddr list in an epoch. Thread 2 unlinks -with the corresponding epoch safe macro, marks as logically free, -and then defers deletion. More general mutation or a synchronous -free would have to follow a a call to +Thread 1 traverses the ifaddr list in an epoch. +Thread 2 unlinks with the corresponding epoch safe macro, marks as logically free, +and then defers deletion. +More general mutation or a synchronous +free would have to follow a call to .Fn epoch_wait . .Sh ERRORS None.