[Bug 290201] Freed UMA keg (rtentry) was not empty (6 items). Lost 4 pages of memory.
[email protected] Thu, 09 Jul 2026 13:42:36 +0000
| Newsgroups | gmane.os.freebsd.bugs |
|---|---|
| Message-ID | <[email protected]/bugzilla/> |
https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=290201 --- Comment #2 from [email protected] --- A commit in branch main references this bug: URL: https://cgit.FreeBSD.org/src/commit/?id=7bf11a2f0c9ad7af00996105fd34e61f1040402b commit 7bf11a2f0c9ad7af00996105fd34e61f1040402b Author: Mark Johnston <[email protected]> AuthorDate: 2026-07-08 17:13:01 +0000 Commit: Mark Johnston <[email protected]> CommitDate: 2026-07-09 13:41:27 +0000 epoch: Fix epoch_drain_callbacks() This function is supposed to wait until all pending callbacks have been executed. This is useful in some contexts where we tear down some context (like a VNET jail and its associated UMA zones) synchronously, and we want to make sure that all pending asynchronous callbacks (which may free objects to said UMA zones) have run first. The implementation schedules a callback on each CPU and waits for them all to run. This assumes that, on a given CPU, callbacks are executed in the order that they are pushed. This assumption depends on the implementation of epoch_call_task() and ck_epoch_poll_deferred(), and it is not true in general. Callbacks are pushed onto a per-CPU stack in LIFO order. ck_epoch_poll_deferred() first pulls out the callbacks from epoch - 2, which are always safe to execute, and in so doing reorders them such that the oldest callback as at the top of the stack, so in this case, epoch_call_task() will execute them in order. However, ck_epoch_poll_deferred() may determine that it is safe to execute callbacks from epoch - 1 (or even from the current epoch if there are no active readers), and in this case it will push those callbacks onto the returned stack. This means that epoch_call_task() will invoke those newer destructors before the older ones, which means that epoch_drain_callbacks() may return early. Fix the correctness problem by simply doing all of this twice: once the first callback is invoked, we know that all of the callbacks that were pending at the time that epoch_drain_callbacks() was called are scheduled to be executed, so when the second callback is executed we know that they must be finished. This is slow, but it is already slow, and the slowness is less noticeable after commit dce56594991. I note that in an ideal world, this function would not exist, and all of the teardown would happen asynchronously, rather than the current mismash of synchronous and asynchronous cleanup. PR: 290201 Reviewed by: glebius MFC after: 1 month Differential Revision: https://reviews.freebsd.org/D58030 sys/kern/subr_epoch.c | 50 ++++++++++++++++++++++++++++++-------------------- 1 file changed, 30 insertions(+), 20 deletions(-) -- You are receiving this mail because: You are the assignee for the bug.