179 lines
5.5 KiB
Diff
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
|
|
|