HomeFreeBSD

epoch: Don't idle CPUs when there's pending epoch work

Description

epoch: Don't idle CPUs when there's pending epoch work

The epoch(9) subsystem implements per-CPU queues of object destructors
which get invoked once it is safe to do so. These queues are polled via
hardclock().

When a CPU is about to go idle, we reduce the hardclock frequency to 1Hz
by default, to avoid unneeded wakeups. This means that if there is any
garbage in these destructor queues, it won't be cleared for at least 1s
(and possibly longer) even if it would otherwise be safe to do so.

epoch_drain_callbacks() is used in some places to provide a barrier,
ensuring that all garbage present in the destructor queues is cleaned up
before returning. It's implemented by adding a fake destructor in the
queues and blocking until it gets run on all CPUs. The above-described
phenomenon means that it can take a long time for these calls to return,
even (especially) when some CPUs are idle. This causes long delays when
destroying VNET jails, for instance, as epoch_drain_callbacks() is
invoked each time a network interface is destroyed.

Work around this problem by not disabling the hardclock timer if there
is garbage present in the destructor queues. The implementation of
epoch_drain_callbacks() has other problems, but this small change on its
own gives a good improvement, especially when running networking
regression tests. Moreover, we should aim to invoke destructors in a
timely manner, so the change is generally beneficial.

Reviewed by: glebius
MFC after: 1 month
Differential Revision: https://reviews.freebsd.org/D56508

(cherry picked from commit dce56594991464c276f340ce963d0f5461566c78)

Details

Provenance
markjAuthored on Apr 21 2026, 2:28 PM
Reviewer
glebius
Differential Revision
D56508: epoch: Don't idle CPUs when there's pending epoch work
Parents
rG6e01ed2f4fa7: routing: Use a better error number in sysctl_fibs()
Branches
Unknown
Tags
Unknown