From: Ondřej Surý Date: Wed, 13 Aug 2025 07:30:45 +0000 (+0200) Subject: Move SIEVE-LRU to dns_slabtop_t structure X-Git-Tag: v9.21.12~40^2~4 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=d7801aec7172047936c11138ae4dd304af58a1f2;p=thirdparty%2Fbind9.git Move SIEVE-LRU to dns_slabtop_t structure 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. --- diff --git a/lib/dns/include/dns/rdataslab.h b/lib/dns/include/dns/rdataslab.h index d5b6fe53b52..45bff01d1a3 100644 --- a/lib/dns/include/dns/rdataslab.h +++ b/lib/dns/include/dns/rdataslab.h @@ -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, diff --git a/lib/dns/include/dns/types.h b/lib/dns/include/dns/types.h index 619f3a779a1..11eab4baf73 100644 --- a/lib/dns/include/dns/types.h +++ b/lib/dns/include/dns/types.h @@ -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; diff --git a/lib/dns/qpcache.c b/lib/dns/qpcache.c index 39903715410..5d315502581 100644 --- a/lib/dns/qpcache.c +++ b/lib/dns/qpcache.c @@ -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); diff --git a/lib/dns/qpzone.c b/lib/dns/qpzone.c index 50d5260d117..e2cc089c757 100644 --- a/lib/dns/qpzone.c +++ b/lib/dns/qpzone.c @@ -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); diff --git a/lib/dns/rdataslab.c b/lib/dns/rdataslab.c index be1d3e29bfb..e2d054a5881 100644 --- a/lib/dns/rdataslab.c +++ b/lib/dns/rdataslab.c @@ -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;