bind9-next/bind-9.19-rbtdb-i686.patch

179 lines
5.5 KiB
Diff

From 0a423df93aa9b4a6391c0483518f2b2961b547e1 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Petr=20Men=C5=A1=C3=ADk?= <pemensik@redhat.com>
Date: Wed, 13 Sep 2023 15:37:57 +0200
Subject: [PATCH] Try to release cache size of complete slab
node used to store new header might be significantly bigger that
expired node from the cache. Count into freed size also node size used
to hold the cache. Mark it released only if it is the last reference.
---
lib/dns/include/dns/rbt.h | 5 +++++
lib/dns/rbt-cachedb.c | 34 ++++++++++++++++++----------------
lib/dns/rbt.c | 5 +++++
lib/dns/rbtdb.c | 2 +-
lib/dns/rbtdb_p.h | 3 ++-
5 files changed, 31 insertions(+), 18 deletions(-)
diff --git a/lib/dns/include/dns/rbt.h b/lib/dns/include/dns/rbt.h
index 08b4803ab99..79ab496842d 100644
--- a/lib/dns/include/dns/rbt.h
+++ b/lib/dns/include/dns/rbt.h
@@ -778,6 +778,11 @@ dns__rbtnode_getdistance(dns_rbtnode_t *node);
* has a distance of 2.
*/
+size_t
+dns__rbtnode_getsize(dns_rbtnode_t *node);
+/*%<
+ * Return allocated size for a node.
+ */
/*****
***** Chain Functions
*****/
diff --git a/lib/dns/rbt-cachedb.c b/lib/dns/rbt-cachedb.c
index d57eb2a6cc7..db3c09c9323 100644
--- a/lib/dns/rbt-cachedb.c
+++ b/lib/dns/rbt-cachedb.c
@@ -1534,7 +1534,7 @@ expiredata(dns_db_t *db, dns_dbnode_t *node, void *data) {
isc_rwlocktype_t tlocktype = isc_rwlocktype_none;
NODE_WRLOCK(&rbtdb->node_locks[rbtnode->locknum].lock, &nlocktype);
- dns__cachedb_expireheader(header, &tlocktype,
+ (void)dns__cachedb_expireheader(header, &tlocktype,
dns_expire_flush DNS__DB_FLARG_PASS);
NODE_UNLOCK(&rbtdb->node_locks[rbtnode->locknum].lock, &nlocktype);
INSIST(tlocktype == isc_rwlocktype_none);
@@ -1573,13 +1573,24 @@ dns_dbmethods_t dns__rbtdb_cachemethods = {
.deletedata = dns__rbtdb_deletedata,
};
+static size_t
+rdataset_size(dns_slabheader_t *header) {
+ if (!NONEXISTENT(header)) {
+ return (dns_rdataslab_size((unsigned char *)header,
+ sizeof(*header)));
+ }
+
+ return (sizeof(*header));
+}
+
/*
* Caller must hold the node (write) lock.
*/
-void
+size_t
dns__cachedb_expireheader(dns_slabheader_t *header,
isc_rwlocktype_t *tlocktypep,
dns_expire_t reason DNS__DB_FLARG) {
+ size_t freed = rdataset_size(header);
dns__rbtdb_setttl(header, 0);
dns__rbtdb_mark(header, DNS_SLABHEADERATTR_ANCIENT);
HEADER_NODE(header)->dirty = 1;
@@ -1593,13 +1604,14 @@ dns__cachedb_expireheader(dns_slabheader_t *header,
* We first need to gain a new reference to the node to meet a
* requirement of dns__rbtdb_decref().
*/
+ freed += dns__rbtnode_getsize(HEADER_NODE(header));
dns__rbtdb_newref(rbtdb, HEADER_NODE(header),
nlocktype DNS__DB_FLARG_PASS);
dns__rbtdb_decref(rbtdb, HEADER_NODE(header), 0, &nlocktype,
tlocktypep, true, false DNS__DB_FLARG_PASS);
if (rbtdb->cachestats == NULL) {
- return;
+ return freed;
}
switch (reason) {
@@ -1615,16 +1627,7 @@ dns__cachedb_expireheader(dns_slabheader_t *header,
break;
}
}
-}
-
-static size_t
-rdataset_size(dns_slabheader_t *header) {
- if (!NONEXISTENT(header)) {
- return (dns_rdataslab_size((unsigned char *)header,
- sizeof(*header)));
- }
-
- return (sizeof(*header));
+ return freed;
}
static size_t
@@ -1637,7 +1640,6 @@ expire_lru_headers(dns_rbtdb_t *rbtdb, unsigned int locknum,
for (header = ISC_LIST_TAIL(rbtdb->lru[locknum]);
header != NULL && purged <= purgesize; header = header_prev)
{
- size_t header_size = rdataset_size(header);
header_prev = ISC_LIST_PREV(header, link);
/*
@@ -1648,9 +1650,8 @@ expire_lru_headers(dns_rbtdb_t *rbtdb, unsigned int locknum,
* TTL was reset to 0.
*/
ISC_LIST_UNLINK(rbtdb->lru[locknum], header, link);
- dns__cachedb_expireheader(header, tlocktypep,
+ purged += dns__cachedb_expireheader(header, tlocktypep,
dns_expire_lru DNS__DB_FLARG_PASS);
- purged += header_size;
}
return (purged);
@@ -1676,6 +1677,7 @@ dns__cachedb_overmem(dns_rbtdb_t *rbtdb, dns_slabheader_t *newheader,
unsigned int locknum;
size_t purgesize = rdataset_size(newheader);
size_t purged = 0;
+ purgesize += dns__rbtnode_getsize(HEADER_NODE(newheader));
for (locknum = (locknum_start + 1) % rbtdb->node_lock_count;
locknum != locknum_start && purged <= purgesize;
diff --git a/lib/dns/rbt.c b/lib/dns/rbt.c
index 32e1c2cc3d4..fc47be84444 100644
--- a/lib/dns/rbt.c
+++ b/lib/dns/rbt.c
@@ -176,6 +176,11 @@ dns__rbtnode_getdistance(dns_rbtnode_t *node) {
return (nodes);
}
+size_t
+dns__rbtnode_getsize(dns_rbtnode_t *node) {
+ return (NODE_SIZE(node));
+}
+
/*
* Forward declarations.
*/
diff --git a/lib/dns/rbtdb.c b/lib/dns/rbtdb.c
index 78464170b06..344dd17bf42 100644
--- a/lib/dns/rbtdb.c
+++ b/lib/dns/rbtdb.c
@@ -3286,7 +3286,7 @@ dns__rbtdb_addrdataset(dns_db_t *db, dns_dbnode_t *node,
if (header != NULL && header->ttl + STALE_TTL(header, rbtdb) <
now - RBTDB_VIRTUAL)
{
- dns__cachedb_expireheader(
+ (void)dns__cachedb_expireheader(
header, &tlocktype,
dns_expire_ttl DNS__DB_FLARG_PASS);
}
diff --git a/lib/dns/rbtdb_p.h b/lib/dns/rbtdb_p.h
index ddc98fe7f2e..f9c711a966c 100644
--- a/lib/dns/rbtdb_p.h
+++ b/lib/dns/rbtdb_p.h
@@ -601,7 +601,8 @@ dns__zonedb_addwildcards(dns_rbtdb_t *rbtdb, const dns_name_t *name, bool lock);
/*
* Cache-specific functions that are called from rbtdb.c
*/
-void
+/* Returns number of released bytes. */
+size_t
dns__cachedb_expireheader(dns_slabheader_t *header,
isc_rwlocktype_t *tlocktypep,
dns_expire_t reason DNS__DB_FLARG);
--
2.41.0