]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Remove purged adb names and entries from SIEVE list immediately
authorOndřej Surý <ondrej@isc.org>
Tue, 10 Feb 2026 05:16:31 +0000 (06:16 +0100)
committerOndřej Surý <ondrej@isc.org>
Wed, 25 Feb 2026 06:26:38 +0000 (07:26 +0100)
Both `expire_name()` and `expire_entry()` use the isc_async mechanism to
remove names and entries from the SIEVE-LRU lists on the matching
isc_loop.

Under heavy load when the cleaning mechanism didn't have the chance to
kick in yet, this delay could lead to double-counting the purged names
and entries when purging the SIEVE-LRU lists during an overmem
condition.  This would result in insufficient memory being cleaned up,
causing the ADB to never recover from the overmem condition and leading
to an OOM crash of `named`.

This patch resolves the issue by bypassing the async queue and executing
the removal synchronously if the target loop matches the current
isc_loop().

lib/dns/adb.c

index 2e61c7553411609d491e1291b15c4ebdf0af6cba..217356fd27b9c20925462555d50c474f76cf936a 100644 (file)
@@ -696,7 +696,12 @@ expire_name(dns_adbname_t *adbname, dns_adbstatus_t astat) {
 
        /* Remove the adbname from the hashtable... */
        if (cds_lfht_del(adb->names_ht, &adbname->ht_node) == 0) {
-               isc_async_run(adbname->loop, expire_name_async, adbname);
+               if (adbname->loop == isc_loop()) {
+                       expire_name_async(adbname);
+               } else {
+                       isc_async_run(adbname->loop, expire_name_async,
+                                     adbname);
+               }
        }
 }
 
@@ -1467,7 +1472,12 @@ expire_entry(dns_adbentry_t *adbentry) {
        dns_adb_t *adb = adbentry->adb;
 
        if (cds_lfht_del(adb->entries_ht, &adbentry->ht_node) == 0) {
-               isc_async_run(adbentry->loop, expire_entry_async, adbentry);
+               if (adbentry->loop == isc_loop()) {
+                       expire_entry_async(adbentry);
+               } else {
+                       isc_async_run(adbentry->loop, expire_entry_async,
+                                     adbentry);
+               }
        }
 }