]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Move SIEVE-LRU to dns_slabtop_t structure
authorOndřej Surý <ondrej@isc.org>
Wed, 13 Aug 2025 07:30:45 +0000 (09:30 +0200)
committerOndřej Surý <ondrej@isc.org>
Mon, 18 Aug 2025 10:36:47 +0000 (12:36 +0200)
As the qpcache has only one active header at the time, we can move the
SIEVE-LRU members from dns_slabheader_t to dns_slabtop_t structure thus
saving a little bit of memory in each slabheader and using it only once
per type.

lib/dns/include/dns/rdataslab.h
lib/dns/include/dns/types.h
lib/dns/qpcache.c
lib/dns/qpzone.c
lib/dns/rdataslab.c

index d5b6fe53b5240fa6b6a1a0c2cf2411bd72b82956..45bff01d1a358f68e41810320946778f3fde0c72 100644 (file)
@@ -69,6 +69,11 @@ struct dns_slabtop {
        dns_slabtop_t    *next;
        dns_slabheader_t *header;
        dns_typepair_t    typepair;
+
+       /*% Used for SIEVE-LRU (cache) and changed_list (zone) */
+       ISC_LINK(struct dns_slabtop) link;
+       /*% Used for SIEVE-LRU */
+       bool visited;
 };
 
 struct dns_slabheader {
@@ -132,11 +137,6 @@ struct dns_slabheader {
 
        dns_gluelist_t *gluelist;
 
-       /*% Used for SIEVE-LRU (cache) and changed_list (zone) */
-       ISC_LINK(struct dns_slabheader) link;
-       /*% Used for SIEVE-LRU */
-       bool visited;
-
        /*%
         * Case vector.  If the bit is set then the corresponding
         * character in the owner name needs to be AND'd with 0x20,
index 619f3a779a1bbfb757bd9252b5384983e0eda239..11eab4baf73bc08de937367703e2a0c4f9d8b162 100644 (file)
@@ -154,23 +154,22 @@ typedef uint8_t                      dns_secproto_t;
 typedef struct dns_signature      dns_signature_t;
 typedef struct dns_skr            dns_skr_t;
 typedef struct dns_slabheader     dns_slabheader_t;
-typedef ISC_LIST(dns_slabheader_t) dns_slabheaderlist_t;
-typedef struct dns_ssurule       dns_ssurule_t;
-typedef struct dns_ssutable      dns_ssutable_t;
-typedef struct dns_stats         dns_stats_t;
-typedef uint32_t                 dns_rdatastatstype_t;
-typedef struct dns_tkeyctx       dns_tkeyctx_t;
-typedef struct dns_transport     dns_transport_t;
-typedef struct dns_transport_list dns_transport_list_t;
-typedef uint16_t                 dns_trust_t;
-typedef struct dns_tsigkeyring   dns_tsigkeyring_t;
-typedef struct dns_tsigkey       dns_tsigkey_t;
-typedef uint32_t                 dns_ttl_t;
-typedef uint32_t                 dns_typepair_t;
-typedef struct dns_unreachcache          dns_unreachcache_t;
-typedef struct dns_update_state          dns_update_state_t;
-typedef struct dns_validator     dns_validator_t;
-typedef struct dns_view                  dns_view_t;
+typedef struct dns_ssurule        dns_ssurule_t;
+typedef struct dns_ssutable       dns_ssutable_t;
+typedef struct dns_stats          dns_stats_t;
+typedef uint32_t                  dns_rdatastatstype_t;
+typedef struct dns_tkeyctx        dns_tkeyctx_t;
+typedef struct dns_transport      dns_transport_t;
+typedef struct dns_transport_list  dns_transport_list_t;
+typedef uint16_t                  dns_trust_t;
+typedef struct dns_tsigkeyring    dns_tsigkeyring_t;
+typedef struct dns_tsigkey        dns_tsigkey_t;
+typedef uint32_t                  dns_ttl_t;
+typedef uint32_t                  dns_typepair_t;
+typedef struct dns_unreachcache           dns_unreachcache_t;
+typedef struct dns_update_state           dns_update_state_t;
+typedef struct dns_validator      dns_validator_t;
+typedef struct dns_view                   dns_view_t;
 typedef ISC_LIST(dns_view_t) dns_viewlist_t;
 typedef struct dns_zone dns_zone_t;
 typedef ISC_LIST(dns_zone_t) dns_zonelist_t;
index 399037154107712784df11ffc574e2beb81dc358..5d31550258178f1bc7f3415dccc40bb63269fb9c 100644 (file)
@@ -201,13 +201,13 @@ typedef struct qpcache_bucket {
        isc_heap_t *heap;
 
        /* SIEVE-LRU cache cleaning state. */
-       ISC_SIEVE(dns_slabheader_t) sieve;
+       ISC_SIEVE(dns_slabtop_t) sieve;
 
        /* Padding to prevent false sharing between locks. */
        uint8_t __padding[ISC_OS_CACHELINE_SIZE -
                          (sizeof(isc_queue_t) + sizeof(isc_rwlock_t) +
                           sizeof(isc_heap_t *) +
-                          sizeof(ISC_SIEVE(dns_slabheader_t))) %
+                          sizeof(ISC_SIEVE(dns_slabtop_t))) %
                                  ISC_OS_CACHELINE_SIZE];
 
 } qpcache_bucket_t;
@@ -486,13 +486,15 @@ expire_lru_headers(qpcache_t *qpdb, uint32_t idx, size_t requested,
        size_t expired = 0;
 
        do {
-               dns_slabheader_t *header =
-                       ISC_SIEVE_NEXT(qpdb->buckets[idx].sieve, visited, link);
-               if (header == NULL) {
+               dns_slabtop_t *top = ISC_SIEVE_NEXT(qpdb->buckets[idx].sieve,
+                                                   visited, link);
+               if (top == NULL) {
                        return;
                }
 
-               ISC_SIEVE_UNLINK(qpdb->buckets[idx].sieve, header, link);
+               ISC_SIEVE_UNLINK(qpdb->buckets[idx].sieve, top, link);
+
+               dns_slabheader_t *header = top->header;
 
                expired += rdataset_size(header);
 
@@ -529,7 +531,7 @@ qpcache_miss(qpcache_t *qpdb, dns_slabheader_t *newheader,
                                   tlocktypep DNS__DB_FLARG_PASS);
        }
 
-       ISC_SIEVE_INSERT(qpdb->buckets[idx].sieve, newheader, link);
+       ISC_SIEVE_INSERT(qpdb->buckets[idx].sieve, newheader->top, link);
 }
 
 static void
@@ -537,7 +539,7 @@ qpcache_hit(qpcache_t *qpdb ISC_ATTR_UNUSED, dns_slabheader_t *header) {
        /*
         * On cache hit, we only mark the header as seen.
         */
-       ISC_SIEVE_MARK(header, visited);
+       ISC_SIEVE_MARK(header->top, visited);
 }
 
 /*
@@ -586,6 +588,12 @@ clean_cache_node(qpcache_t *qpdb, qpcnode_t *node) {
                        } else {
                                node->data = top->next;
                        }
+
+                       if (ISC_LINK_LINKED(top, link)) {
+                               ISC_SIEVE_UNLINK(
+                                       qpdb->buckets[node->locknum].sieve, top,
+                                       link);
+                       }
                        dns_slabtop_destroy(((dns_db_t *)qpdb)->mctx, &top);
                } else {
                        top_prev = top;
@@ -2804,13 +2812,16 @@ find_header:
                        return DNS_R_UNCHANGED;
                }
 
-               qpcache_miss(qpdb, newheader, &nlocktype,
-                            &tlocktype DNS__DB_FLARG_PASS);
-
                top->header = newheader;
                newheader->top = top;
                newheader->down = header;
 
+               ISC_SIEVE_UNLINK(qpdb->buckets[qpnode->locknum].sieve, top,
+                                link);
+
+               qpcache_miss(qpdb, newheader, &nlocktype,
+                            &tlocktype DNS__DB_FLARG_PASS);
+
                mark_ancient(header);
                if (sigheader != NULL) {
                        mark_ancient(sigheader);
@@ -2827,12 +2838,12 @@ find_header:
 
                dns_slabtop_t *newtop = dns_slabtop_new(
                        ((dns_db_t *)qpdb)->mctx, newheader->typepair);
-               qpcache_miss(qpdb, newheader, &nlocktype,
-                            &tlocktype DNS__DB_FLARG_PASS);
-
                newtop->header = newheader;
                newheader->top = newtop;
 
+               qpcache_miss(qpdb, newheader, &nlocktype,
+                            &tlocktype DNS__DB_FLARG_PASS);
+
                if (prio_header(newtop)) {
                        /* This is a priority type, prepend it */
                        newtop->next = qpnode->data;
@@ -3755,7 +3766,6 @@ static void
 qpcnode_deletedata(dns_dbnode_t *node ISC_ATTR_UNUSED, void *data) {
        dns_slabheader_t *header = data;
        qpcache_t *qpdb = HEADERNODE(header)->qpdb;
-       int idx = HEADERNODE(header)->locknum;
 
        if (header->heap != NULL && header->heap_index != 0) {
                isc_heap_delete(header->heap, header->heap_index);
@@ -3767,10 +3777,6 @@ qpcnode_deletedata(dns_dbnode_t *node ISC_ATTR_UNUSED, void *data) {
        update_rrsetstats(qpdb->rrsetstats, header->typepair,
                          atomic_load_acquire(&header->attributes), false);
 
-       if (ISC_LINK_LINKED(header, link)) {
-               ISC_SIEVE_UNLINK(qpdb->buckets[idx].sieve, header, link);
-       }
-
        if (header->noqname != NULL) {
                dns_slabheader_freeproof(qpdb->common.mctx, &header->noqname);
        }
@@ -3855,7 +3861,7 @@ static dns_dbmethods_t qpdb_cachemethods = {
 static void
 qpcnode_destroy(qpcnode_t *qpnode) {
        dns_slabtop_t *top = NULL, *top_next = NULL;
-       dns_db_t *db = (dns_db_t *)qpnode->qpdb;
+       qpcache_t *qpdb = qpnode->qpdb;
 
        for (top = qpnode->data; top != NULL; top = top_next) {
                top_next = top->next;
@@ -3867,7 +3873,11 @@ qpcnode_destroy(qpcnode_t *qpnode) {
                }
                top->header = NULL;
 
-               dns_slabtop_destroy(db->mctx, &top);
+               if (ISC_LINK_LINKED(top, link)) {
+                       ISC_SIEVE_UNLINK(qpdb->buckets[qpnode->locknum].sieve,
+                                        top, link);
+               }
+               dns_slabtop_destroy(((dns_db_t *)qpdb)->mctx, &top);
        }
 
        dns_name_free(&qpnode->name, qpnode->mctx);
index 50d5260d1175ef8b7c626dcf79e3c335a5f495f6..e2cc089c75764e87be9630667b2acb002116b20c 100644 (file)
@@ -113,6 +113,13 @@ typedef struct qpz_changed {
 
 typedef ISC_LIST(qpz_changed_t) qpz_changedlist_t;
 
+typedef struct qpz_resigned {
+       dns_slabheader_t *header;
+       ISC_LINK(struct qpz_resigned) link;
+} qpz_resigned_t;
+
+typedef ISC_LIST(qpz_resigned_t) qpz_resignedlist_t;
+
 typedef struct qpz_version qpz_version_t;
 struct qpz_version {
        /* Not locked */
@@ -122,7 +129,7 @@ struct qpz_version {
        /* Locked by database lock. */
        bool writer;
        qpz_changedlist_t changed_list;
-       dns_slabheaderlist_t resigned_list;
+       qpz_resignedlist_t resigned_list;
        ISC_LINK(qpz_version_t) link;
        bool secure;
        bool havensec3;
@@ -1284,7 +1291,6 @@ newversion(dns_db_t *db, dns_dbversion_t **versionp) {
 static void
 resigninsert(dns_slabheader_t *newheader) {
        REQUIRE(newheader->heap_index == 0);
-       REQUIRE(!ISC_LINK_LINKED(newheader, link));
 
        LOCK(get_heap_lock(newheader));
        isc_heap_insert(HEADERNODE(newheader)->heap->heap, newheader);
@@ -1304,7 +1310,15 @@ resigndelete(qpzonedb_t *qpdb ISC_ATTR_UNUSED, qpz_version_t *version,
 
        header->heap_index = 0;
        qpznode_acquire(qpdb, HEADERNODE(header) DNS__DB_FLARG_PASS);
-       ISC_LIST_APPEND(version->resigned_list, header, link);
+
+       qpz_resigned_t *resigned = isc_mem_get(((dns_db_t *)qpdb)->mctx,
+                                              sizeof(*resigned));
+       *resigned = (qpz_resigned_t){
+               .header = header,
+               .link = ISC_LINK_INITIALIZER,
+       };
+
+       ISC_LIST_APPEND(version->resigned_list, resigned, link);
 }
 
 static void
@@ -1358,7 +1372,7 @@ closeversion(dns_db_t *db, dns_dbversion_t **versionp,
        qpznode_t *node = NULL;
        bool rollback = false;
        qpz_changedlist_t cleanup_list;
-       dns_slabheaderlist_t resigned_list;
+       qpz_resignedlist_t resigned_list;
        uint32_t serial, least_serial;
 
        REQUIRE(VALID_QPZONE(qpdb));
@@ -1532,11 +1546,14 @@ closeversion(dns_db_t *db, dns_dbversion_t **versionp,
        /*
         * Commit/rollback re-signed headers.
         */
-       ISC_LIST_FOREACH (resigned_list, header, link) {
+       ISC_LIST_FOREACH (resigned_list, resigned, link) {
                isc_rwlock_t *nlock = NULL;
                isc_rwlocktype_t nlocktype = isc_rwlocktype_none;
+               dns_slabheader_t *header = resigned->header;
+
+               ISC_LIST_UNLINK(resigned_list, resigned, link);
 
-               ISC_LIST_UNLINK(resigned_list, header, link);
+               isc_mem_put(db->mctx, resigned, sizeof(*resigned));
 
                nlock = qpzone_get_lock(HEADERNODE(header));
                NODE_WRLOCK(nlock, &nlocktype);
index be1d3e29bfbcd05162ed01628d74dd9460c28996..e2d054a5881a2a4a8df9431e9dc846de66637c6d 100644 (file)
@@ -346,7 +346,6 @@ dns_rdataslab_fromrdataset(dns_rdataset_t *rdataset, isc_mem_t *mctx,
                        .typepair = typepair,
                        .trust = rdataset->trust,
                        .ttl = rdataset->ttl,
-                       .link = ISC_LINK_INITIALIZER,
                };
        }
 
@@ -858,11 +857,9 @@ dns_slabheader_copycase(dns_slabheader_t *dest, dns_slabheader_t *src) {
 
 void
 dns_slabheader_reset(dns_slabheader_t *h, dns_dbnode_t *node) {
-       ISC_LINK_INIT(h, link);
        h->heap_index = 0;
        h->heap = NULL;
        h->node = node;
-       h->visited = false;
 
        atomic_init(&h->attributes, 0);
        atomic_init(&h->last_refresh_fail_ts, 0);
@@ -878,7 +875,6 @@ dns_slabheader_new(isc_mem_t *mctx, dns_dbnode_t *node) {
 
        h = isc_mem_get(mctx, sizeof(*h));
        *h = (dns_slabheader_t){
-               .link = ISC_LINK_INITIALIZER,
                .node = node,
        };
        return h;
@@ -1246,6 +1242,7 @@ dns_slabtop_new(isc_mem_t *mctx, dns_typepair_t typepair) {
        dns_slabtop_t *top = isc_mem_get(mctx, sizeof(*top));
        *top = (dns_slabtop_t){
                .typepair = typepair,
+               .link = ISC_LINK_INITIALIZER,
        };
 
        return top;