]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Create a second pruning task for rbtdb with unlimited quantum
authorOndřej Surý <ondrej@isc.org>
Fri, 1 Mar 2024 11:43:15 +0000 (12:43 +0100)
committerMichał Kępień <michal@isc.org>
Wed, 6 Mar 2024 18:09:10 +0000 (19:09 +0100)
Previously, rbtdb->task had quantum of 1 because it was originally used
just for freeing RBTDB contents, which can happen on a "best effort"
basis (does not need to be prioritized).  However, when tree pruning was
implemented, it also started sending events to that task, enabling the
latter to become clogged up with a significant event backlog because it
only pruned a single RBTDB node per event.

To prioritize tree pruning (as it is necessary for enforcing the
configured memory use limit for the cache memory context), create a
second task with a virtually unlimited quantum (UINT_MAX) and send the
tree-pruning events to this new task, to ensure that all nodes scheduled
for pruning will be processed before further nodes are queued in a
similar fashion.

This change enables dropping the prunenodes list and restoring the
originally-used logic that allocates and sends a separate event for each
node to prune.

(cherry picked from commit 231b2375e5b9b98096711f5e883911134adb6392)

bin/tests/system/dyndb/driver/db.c
lib/dns/cache.c
lib/dns/db.c
lib/dns/include/dns/db.h
lib/dns/rbtdb.c
lib/dns/sdb.c
lib/dns/sdlz.c
lib/dns/zone.c

index 334fd549de38a1c549d45461ee7fe62d70d36e8f..96857224c2cfdbe30ddcbe04a444ab3551f94ee5 100644 (file)
@@ -420,12 +420,12 @@ overmem(dns_db_t *db, bool over) {
 }
 
 static void
-settask(dns_db_t *db, isc_task_t *task) {
+settask(dns_db_t *db, isc_task_t *task, isc_task_t *prunetask) {
        sampledb_t *sampledb = (sampledb_t *)db;
 
        REQUIRE(VALID_SAMPLEDB(sampledb));
 
-       dns_db_settask(sampledb->rbtdb, task);
+       dns_db_settask(sampledb->rbtdb, task, prunetask);
 }
 
 static isc_result_t
index 7ffb6f85b823a0cf7f1bc87520175cbbc6251ef9..fd944bd46f8c59f5b24f429101256e9e0be8c614 100644 (file)
@@ -187,7 +187,6 @@ dns_cache_create(isc_mem_t *cmctx, isc_mem_t *hmctx, isc_taskmgr_t *taskmgr,
        isc_result_t result;
        dns_cache_t *cache;
        int i, extra = 0;
-       isc_task_t *dbtask;
 
        REQUIRE(cachep != NULL);
        REQUIRE(*cachep == NULL);
@@ -258,15 +257,25 @@ dns_cache_create(isc_mem_t *cmctx, isc_mem_t *hmctx, isc_taskmgr_t *taskmgr,
                goto cleanup_dbargv;
        }
        if (taskmgr != NULL) {
-               dbtask = NULL;
+               isc_task_t *dbtask = NULL;
+               isc_task_t *prunetask = NULL;
+
                result = isc_task_create(taskmgr, 1, &dbtask);
                if (result != ISC_R_SUCCESS) {
                        goto cleanup_db;
                }
-
                isc_task_setname(dbtask, "cache_dbtask", NULL);
-               dns_db_settask(cache->db, dbtask);
+
+               result = isc_task_create(taskmgr, UINT_MAX, &prunetask);
+               if (result != ISC_R_SUCCESS) {
+                       isc_task_detach(&dbtask);
+                       goto cleanup_db;
+               }
+               isc_task_setname(prunetask, "cache_prunetask", NULL);
+
+               dns_db_settask(cache->db, dbtask, prunetask);
                isc_task_detach(&dbtask);
+               isc_task_detach(&prunetask);
        }
 
        cache->magic = CACHE_MAGIC;
index c95d19ad1337e6fb8dd5886476424501b6394852..0fce3005fb711d71b3c430982ae7b0d13dadec74 100644 (file)
@@ -829,10 +829,10 @@ dns_db_hashsize(dns_db_t *db) {
 }
 
 void
-dns_db_settask(dns_db_t *db, isc_task_t *task) {
+dns_db_settask(dns_db_t *db, isc_task_t *task, isc_task_t *prunetask) {
        REQUIRE(DNS_DB_VALID(db));
 
-       (db->methods->settask)(db, task);
+       (db->methods->settask)(db, task, prunetask);
 }
 
 isc_result_t
index 9b53f0435f7d5bd445733e81027477318b87ccdf..bbae0e2991f65ec0aa7ef03a95d0f5de49511753 100644 (file)
@@ -139,7 +139,7 @@ typedef struct dns_dbmethods {
        unsigned int (*nodecount)(dns_db_t *db, dns_dbtree_t);
        bool (*ispersistent)(dns_db_t *db);
        void (*overmem)(dns_db_t *db, bool overmem);
-       void (*settask)(dns_db_t *db, isc_task_t *);
+       void (*settask)(dns_db_t *db, isc_task_t *, isc_task_t *);
        isc_result_t (*getoriginnode)(dns_db_t *db, dns_dbnode_t **nodep);
        void (*transfernode)(dns_db_t *db, dns_dbnode_t **sourcep,
                             dns_dbnode_t **targetp);
@@ -1389,13 +1389,14 @@ dns_db_hashsize(dns_db_t *db);
  */
 
 void
-dns_db_settask(dns_db_t *db, isc_task_t *task);
+dns_db_settask(dns_db_t *db, isc_task_t *task, isc_task_t *prunetask);
 /*%<
  * If task is set then the final detach maybe performed asynchronously.
  *
  * Requires:
  * \li 'db' is a valid database.
- * \li 'task' to be valid or NULL.
+ * \li 'task' to be valid or NULL (default task to send events to).
+ * \li 'prunetask' to be valid or NULL (task to send tree-pruning events to).
  */
 
 bool
index 3db5eb0f241d39d80088988d30856d1528269d6c..80c128b343a9d485e4ee8bd379c4bb58d4c480e6 100644 (file)
@@ -462,6 +462,7 @@ struct dns_rbtdb {
        rbtdb_version_t *future_version;
        rbtdb_versionlist_t open_versions;
        isc_task_t *task;
+       isc_task_t *prunetask;
        dns_dbnode_t *soanode;
        dns_dbnode_t *nsnode;
 
@@ -1163,6 +1164,9 @@ free_rbtdb(dns_rbtdb_t *rbtdb, bool log, isc_event_t *event) {
        if (rbtdb->task != NULL) {
                isc_task_detach(&rbtdb->task);
        }
+       if (rbtdb->prunetask != NULL) {
+               isc_task_detach(&rbtdb->prunetask);
+       }
 
        RBTDB_DESTROYLOCK(&rbtdb->lock);
        rbtdb->common.magic = 0;
@@ -1867,7 +1871,7 @@ send_to_prune_tree(dns_rbtdb_t *rbtdb, dns_rbtnode_t *node,
        db = NULL;
        attach((dns_db_t *)rbtdb, &db);
        ev->ev_sender = db;
-       isc_task_send(rbtdb->task, &ev);
+       isc_task_send(rbtdb->prunetask, &ev);
 }
 
 /*%
@@ -7763,7 +7767,7 @@ hashsize(dns_db_t *db) {
 }
 
 static void
-settask(dns_db_t *db, isc_task_t *task) {
+settask(dns_db_t *db, isc_task_t *task, isc_task_t *prunetask) {
        dns_rbtdb_t *rbtdb;
 
        rbtdb = (dns_rbtdb_t *)db;
@@ -7777,6 +7781,12 @@ settask(dns_db_t *db, isc_task_t *task) {
        if (task != NULL) {
                isc_task_attach(task, &rbtdb->task);
        }
+       if (rbtdb->prunetask != NULL) {
+               isc_task_detach(&rbtdb->prunetask);
+       }
+       if (prunetask != NULL) {
+               isc_task_attach(prunetask, &rbtdb->prunetask);
+       }
        RBTDB_UNLOCK(&rbtdb->lock, isc_rwlocktype_write);
 }
 
@@ -8454,6 +8464,7 @@ dns_rbtdb_create(isc_mem_t *mctx, const dns_name_t *origin, dns_dbtype_t type,
        isc_refcount_init(&rbtdb->references, 1);
        rbtdb->attributes = 0;
        rbtdb->task = NULL;
+       rbtdb->prunetask = NULL;
        rbtdb->serve_stale_ttl = 0;
 
        /*
index 317eeb0b215feac9dae2a2b99f6bae08b9a1ed06..b58080a2faed30ad6b47c9b9a32a649b2f352b46 100644 (file)
@@ -1263,9 +1263,10 @@ overmem(dns_db_t *db, bool over) {
 }
 
 static void
-settask(dns_db_t *db, isc_task_t *task) {
+settask(dns_db_t *db, isc_task_t *task, isc_task_t *prunetask) {
        UNUSED(db);
        UNUSED(task);
+       UNUSED(prunetask);
 }
 
 static dns_dbmethods_t sdb_methods = {
index 7ab08f6bc9874a93faca42e8bc0e7911f8243b7d..ff674488658b403308747f7898ffab262fc2e679 100644 (file)
@@ -1213,9 +1213,10 @@ overmem(dns_db_t *db, bool over) {
 }
 
 static void
-settask(dns_db_t *db, isc_task_t *task) {
+settask(dns_db_t *db, isc_task_t *task, isc_task_t *prunetask) {
        UNUSED(db);
        UNUSED(task);
+       UNUSED(prunetask);
 }
 
 /*
index 729adcb6e48929f800ca36d6a474193935b87f10..19c2ce3651b917eca2a8c3270c662662bf5b8e37 100644 (file)
@@ -2339,7 +2339,7 @@ zone_load(dns_zone_t *zone, unsigned int flags, bool locked) {
                              isc_result_totext(result));
                goto cleanup;
        }
-       dns_db_settask(db, zone->task);
+       dns_db_settask(db, zone->task, zone->task);
 
        if (zone->type == dns_zone_primary ||
            zone->type == dns_zone_secondary || zone->type == dns_zone_mirror)
@@ -14791,7 +14791,7 @@ ns_query(dns_zone_t *zone, dns_rdataset_t *soardataset, dns_stub_t *stub) {
                                             isc_result_totext(result));
                                goto cleanup;
                        }
-                       dns_db_settask(stub->db, zone->task);
+                       dns_db_settask(stub->db, zone->task, zone->task);
                }
 
                result = dns_db_newversion(stub->db, &stub->version);
@@ -16235,7 +16235,7 @@ dns_zone_settask(dns_zone_t *zone, isc_task_t *task) {
        isc_task_attach(task, &zone->task);
        ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
        if (zone->db != NULL) {
-               dns_db_settask(zone->db, zone->task);
+               dns_db_settask(zone->db, zone->task, zone->task);
        }
        ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
        UNLOCK_ZONE(zone);
@@ -17508,7 +17508,7 @@ zone_replacedb(dns_zone_t *zone, dns_db_t *db, bool dump) {
                zone_detachdb(zone);
        }
        zone_attachdb(zone, db);
-       dns_db_settask(zone->db, zone->task);
+       dns_db_settask(zone->db, zone->task, zone->task);
        DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED | DNS_ZONEFLG_NEEDNOTIFY);
        return (ISC_R_SUCCESS);