diff options
Diffstat (limited to 'static/freebsd/man9/epoch.9 4.html')
| -rw-r--r-- | static/freebsd/man9/epoch.9 4.html | 284 |
1 files changed, 0 insertions, 284 deletions
diff --git a/static/freebsd/man9/epoch.9 4.html b/static/freebsd/man9/epoch.9 4.html deleted file mode 100644 index eb84213b..00000000 --- a/static/freebsd/man9/epoch.9 4.html +++ /dev/null @@ -1,284 +0,0 @@ -<table class="head"> - <tr> - <td class="head-ltitle">EPOCH(9)</td> - <td class="head-vol">Kernel Developer's Manual</td> - <td class="head-rtitle">EPOCH(9)</td> - </tr> -</table> -<div class="manual-text"> -<section class="Sh"> -<h1 class="Sh" id="NAME"><a class="permalink" href="#NAME">NAME</a></h1> -<p class="Pp"><code class="Nm">epoch</code>, - <code class="Nm">epoch_context</code>, <code class="Nm">epoch_alloc</code>, - <code class="Nm">epoch_free</code>, <code class="Nm">epoch_enter</code>, - <code class="Nm">epoch_exit</code>, <code class="Nm">epoch_wait</code>, - <code class="Nm">epoch_enter_preempt</code>, - <code class="Nm">epoch_exit_preempt</code>, - <code class="Nm">epoch_wait_preempt</code>, - <code class="Nm">epoch_call</code>, - <code class="Nm">epoch_drain_callbacks</code>, - <code class="Nm">in_epoch</code>, <code class="Nm">in_epoch_verbose</code> - — <span class="Nd">kernel epoch based reclamation</span></p> -</section> -<section class="Sh"> -<h1 class="Sh" id="SYNOPSIS"><a class="permalink" href="#SYNOPSIS">SYNOPSIS</a></h1> -<p class="Pp"><code class="In">#include - <<a class="In">sys/param.h</a>></code> - <br/> - <code class="In">#include <<a class="In">sys/proc.h</a>></code> - <br/> - <code class="In">#include <<a class="In">sys/epoch.h</a>></code></p> -<div class="Bd Pp Li"> -<pre>struct epoch; /* Opaque */</pre> -</div> -<br/> -<var class="Vt">typedef struct epoch *epoch_t</var>; -<div class="Bd Pp Li"> -<pre>struct epoch_context { - void *data[2]; -};</pre> -</div> -<br/> -<var class="Vt">typedef struct epoch_context *epoch_context_t</var>; -<br/> -<var class="Vt">typedef void epoch_callback_t(epoch_context_t)</var>; -<div class="Bd Pp Li"> -<pre>struct epoch_tracker; /* Opaque */</pre> -</div> -<br/> -<var class="Vt">typedef struct epoch_tracker *epoch_tracker_t</var>; -<p class="Pp"><var class="Ft">epoch_t</var> - <br/> - <code class="Fn">epoch_alloc</code>(<var class="Fa" style="white-space: nowrap;">const - char *name</var>, <var class="Fa" style="white-space: nowrap;">int - flags</var>);</p> -<p class="Pp"><var class="Ft">void</var> - <br/> - <code class="Fn">epoch_free</code>(<var class="Fa" style="white-space: nowrap;">epoch_t - epoch</var>);</p> -<p class="Pp"><var class="Ft">void</var> - <br/> - <code class="Fn">epoch_enter</code>(<var class="Fa" style="white-space: nowrap;">epoch_t - epoch</var>);</p> -<p class="Pp"><var class="Ft">void</var> - <br/> - <code class="Fn">epoch_exit</code>(<var class="Fa" style="white-space: nowrap;">epoch_t - epoch</var>);</p> -<p class="Pp"><var class="Ft">void</var> - <br/> - <code class="Fn">epoch_wait</code>(<var class="Fa" style="white-space: nowrap;">epoch_t - epoch</var>);</p> -<p class="Pp"><var class="Ft">void</var> - <br/> - <code class="Fn">epoch_enter_preempt</code>(<var class="Fa" style="white-space: nowrap;">epoch_t - epoch</var>, <var class="Fa" style="white-space: nowrap;">epoch_tracker_t - et</var>);</p> -<p class="Pp"><var class="Ft">void</var> - <br/> - <code class="Fn">epoch_exit_preempt</code>(<var class="Fa" style="white-space: nowrap;">epoch_t - epoch</var>, <var class="Fa" style="white-space: nowrap;">epoch_tracker_t - et</var>);</p> -<p class="Pp"><var class="Ft">void</var> - <br/> - <code class="Fn">epoch_wait_preempt</code>(<var class="Fa" style="white-space: nowrap;">epoch_t - epoch</var>);</p> -<p class="Pp"><var class="Ft">void</var> - <br/> - <code class="Fn">epoch_call</code>(<var class="Fa" style="white-space: nowrap;">epoch_t - epoch</var>, <var class="Fa" style="white-space: nowrap;">epoch_callback_t - callback</var>, <var class="Fa" style="white-space: nowrap;">epoch_context_t - ctx</var>);</p> -<p class="Pp"><var class="Ft">void</var> - <br/> - <code class="Fn">epoch_drain_callbacks</code>(<var class="Fa" style="white-space: nowrap;">epoch_t - epoch</var>);</p> -<p class="Pp"><var class="Ft">int</var> - <br/> - <code class="Fn">in_epoch</code>(<var class="Fa" style="white-space: nowrap;">epoch_t - epoch</var>);</p> -<p class="Pp"><var class="Ft">int</var> - <br/> - <code class="Fn">in_epoch_verbose</code>(<var class="Fa" style="white-space: nowrap;">epoch_t - epoch</var>, <var class="Fa" style="white-space: nowrap;">int - dump_onfail</var>);</p> -</section> -<section class="Sh"> -<h1 class="Sh" id="DESCRIPTION"><a class="permalink" href="#DESCRIPTION">DESCRIPTION</a></h1> -<p class="Pp">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.</p> -<p class="Pp" id="epoch_alloc">Epochs are allocated with - <a class="permalink" href="#epoch_alloc"><code class="Fn">epoch_alloc</code></a>(). - The <var class="Fa">name</var> argument is used for debugging convenience - when the <code class="Cd">EPOCH_TRACE</code> kernel option is configured. By - default, epochs do not allow preemption during sections. By default mutexes - cannot be held across - <a class="permalink" href="#epoch_wait_preempt"><code class="Fn" id="epoch_wait_preempt">epoch_wait_preempt</code></a>(). - The <var class="Fa">flags</var> specified are formed by - <a class="permalink" href="#OR"><i class="Em" id="OR">OR</i></a>'ing the - following values:</p> -<div class="Bd-indent"> -<dl class="Bl-tag"> - <dt id="EPOCH_LOCKED"><a class="permalink" href="#EPOCH_LOCKED"><code class="Dv">EPOCH_LOCKED</code></a></dt> - <dd>Permit holding mutexes across <code class="Fn">epoch_wait_preempt</code>() - (requires <code class="Dv">EPOCH_PREEMPT</code>). When doing this one must - be cautious of creating a situation where a deadlock is possible.</dd> - <dt id="EPOCH_PREEMPT"><a class="permalink" href="#EPOCH_PREEMPT"><code class="Dv">EPOCH_PREEMPT</code></a></dt> - <dd>The <var class="Vt">epoch</var> will allow preemption during sections. - Only non-sleepable locks may be acquired during a preemptible epoch. The - functions <code class="Fn">epoch_enter_preempt</code>(), - <code class="Fn">epoch_exit_preempt</code>(), and - <code class="Fn">epoch_wait_preempt</code>() must be used in place of - <code class="Fn">epoch_enter</code>(), - <code class="Fn">epoch_exit</code>(), and - <code class="Fn">epoch_wait</code>(), respectively.</dd> -</dl> -</div> -<p class="Pp" id="epoch_free"><var class="Vt">epoch</var>s are freed with - <a class="permalink" href="#epoch_free"><code class="Fn">epoch_free</code></a>().</p> -<p class="Pp" id="epoch_enter">Threads indicate the start of an epoch critical - section by calling - <a class="permalink" href="#epoch_enter"><code class="Fn">epoch_enter</code></a>() - (or - <a class="permalink" href="#epoch_enter_preempt"><code class="Fn" id="epoch_enter_preempt">epoch_enter_preempt</code></a>() - for preemptible epochs). Threads call - <a class="permalink" href="#epoch_exit"><code class="Fn" id="epoch_exit">epoch_exit</code></a>() - (or - <a class="permalink" href="#epoch_exit_preempt"><code class="Fn" id="epoch_exit_preempt">epoch_exit_preempt</code></a>() - for preemptible epochs) to indicate the end of a critical section. - <var class="Vt">struct epoch_tracker</var>s are stack objects whose pointers - are passed to <code class="Fn">epoch_enter_preempt</code>() and - <code class="Fn">epoch_exit_preempt</code>() (much like - <var class="Vt">struct rm_priotracker</var>).</p> -<p class="Pp" id="epoch_call">Threads can defer work until a grace period has - expired since any thread has entered the epoch either synchronously or - asynchronously. - <a class="permalink" href="#epoch_call"><code class="Fn">epoch_call</code></a>() - defers work asynchronously by invoking the provided - <var class="Fa">callback</var> at a later time. - <code class="Fn">epoch_wait</code>() (or - <code class="Fn">epoch_wait_preempt</code>()) blocks the current thread - until the grace period has expired and the work can be done safely.</p> -<p class="Pp" id="epoch_wait">Default, non-preemptible epoch wait - (<a class="permalink" href="#epoch_wait"><code class="Fn">epoch_wait</code></a>()) - is guaranteed to have much shorter completion times relative to preemptible - epoch wait - (<a class="permalink" href="#epoch_wait_preempt~2"><code class="Fn" id="epoch_wait_preempt~2">epoch_wait_preempt</code></a>()). - (In the default type, none of the threads in an epoch section will be - preempted before completing its section.)</p> -<p class="Pp" id="in_epoch">INVARIANTS can assert that a thread is in an epoch - by using - <a class="permalink" href="#in_epoch"><code class="Fn">in_epoch</code></a>(). - <code class="Fn">in_epoch</code>(<var class="Fa">epoch</var>) is equivalent - to invoking - <a class="permalink" href="#in_epoch_verbose"><code class="Fn" id="in_epoch_verbose">in_epoch_verbose</code></a>(<var class="Fa">epoch</var>, - <var class="Fa">0</var>). If <code class="Cd">EPOCH_TRACE</code> is enabled, - <code class="Fn">in_epoch_verbose</code>(<var class="Fa">epoch</var>, - <var class="Fa">1</var>) provides additional verbose debugging - information.</p> -<p class="Pp" id="epoch_wait~2">The epoch API currently does not support - sleeping in epoch_preempt sections. A caller should never call - <a class="permalink" href="#epoch_wait~2"><code class="Fn">epoch_wait</code></a>() - in the middle of an epoch section for the same epoch as this will lead to a - deadlock.</p> -<p class="Pp" id="epoch_drain_callbacks">The - <a class="permalink" href="#epoch_drain_callbacks"><code class="Fn">epoch_drain_callbacks</code></a>() - function is used to drain all pending callbacks which have been invoked by - prior <code class="Fn">epoch_call</code>() function calls on the same epoch. - This function is useful when there are shared memory structure(s) referred - to by the epoch callback(s) which are not refcounted and are rarely freed. - The typical place for calling this function is right before freeing or - invalidating the shared resource(s) used by the epoch callback(s). This - function can sleep and is not optimized for performance.</p> -</section> -<section class="Sh"> -<h1 class="Sh" id="RETURN_VALUES"><a class="permalink" href="#RETURN_VALUES">RETURN - VALUES</a></h1> -<p class="Pp"><code class="Fn">in_epoch</code>(<var class="Fa">curepoch</var>) - will return 1 if curthread is in curepoch, 0 otherwise.</p> -</section> -<section class="Sh"> -<h1 class="Sh" id="EXAMPLES"><a class="permalink" href="#EXAMPLES">EXAMPLES</a></h1> -<p class="Pp">Async free example: Thread 1:</p> -<div class="Bd Pp Li"> -<pre>int -in_pcbladdr(struct inpcb *inp, struct in_addr *faddr, struct in_laddr *laddr, - struct ucred *cred) -{ - /* ... */ - epoch_enter(net_epoch); - CK_STAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) { - sa = ifa->ifa_addr; - if (sa->sa_family != AF_INET) - continue; - sin = (struct sockaddr_in *)sa; - if (prison_check_ip4(cred, &sin->sin_addr) == 0) { - ia = (struct in_ifaddr *)ifa; - break; - } - } - epoch_exit(net_epoch); - /* ... */ -}</pre> -</div> -Thread 2: -<div class="Bd Pp Li"> -<pre>void -ifa_free(struct ifaddr *ifa) -{ - - if (refcount_release(&ifa->ifa_refcnt)) - epoch_call(net_epoch, ifa_destroy, &ifa->ifa_epoch_ctx); -} - -void -if_purgeaddrs(struct ifnet *ifp) -{ - - /* .... * - IF_ADDR_WLOCK(ifp); - CK_STAILQ_REMOVE(&ifp->if_addrhead, ifa, ifaddr, ifa_link); - IF_ADDR_WUNLOCK(ifp); - ifa_free(ifa); -}</pre> -</div> -<p class="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 call to <code class="Fn">epoch_wait</code>().</p> -</section> -<section class="Sh"> -<h1 class="Sh" id="SEE_ALSO"><a class="permalink" href="#SEE_ALSO">SEE - ALSO</a></h1> -<p class="Pp"><a class="Xr">callout(9)</a>, <a class="Xr">locking(9)</a>, - <a class="Xr">mtx_pool(9)</a>, <a class="Xr">mutex(9)</a>, - <a class="Xr">rwlock(9)</a>, <a class="Xr">sema(9)</a>, - <a class="Xr">sleep(9)</a>, <a class="Xr">sx(9)</a></p> -</section> -<section class="Sh"> -<h1 class="Sh" id="HISTORY"><a class="permalink" href="#HISTORY">HISTORY</a></h1> -<p class="Pp">The <code class="Nm">epoch</code> framework first appeared in - <span class="Ux">FreeBSD 11.0</span>.</p> -</section> -<section class="Sh"> -<h1 class="Sh" id="CAVEATS"><a class="permalink" href="#CAVEATS">CAVEATS</a></h1> -<p class="Pp">One must be cautious when using - <code class="Fn">epoch_wait_preempt</code>(). 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 indefinitely.</p> -<p class="Pp">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 and frees must be deferred - until after a grace period has elapsed.</p> -</section> -</div> -<table class="foot"> - <tr> - <td class="foot-date">March 25, 2024</td> - <td class="foot-os">FreeBSD 15.0</td> - </tr> -</table> |
