mirror of
https://github.com/isc-projects/bind9.git
synced 2026-06-11 11:09:59 -04:00
Merge branch '4591-improve-ttl-based-cleaning-9.18' into 'bind-9.18'
[9.18] Remove expired rdataset headers from the heap See merge request isc-projects/bind9!8755
This commit is contained in:
commit
a5a094c0af
2 changed files with 59 additions and 15 deletions
5
CHANGES
5
CHANGES
|
|
@ -1,3 +1,8 @@
|
|||
6353. [bug] Improve the TTL-based cleaning by removing the expired
|
||||
headers from the heap, so they don't block the next
|
||||
cleaning round and clean more than a single item for
|
||||
each new addition to the RBTDB. [GL #4591]
|
||||
|
||||
6352. [bug] Revert change 6319 and decrease lock contention during
|
||||
RBTDB tree pruning by not cleaning up nodes recursively
|
||||
within a single prune_tree() call. [GL #4596]
|
||||
|
|
|
|||
|
|
@ -355,6 +355,14 @@ hash_32(uint32_t val, unsigned int bits) {
|
|||
#define DEFAULT_CACHE_NODE_LOCK_COUNT 17
|
||||
#endif /* DNS_RBTDB_CACHE_NODE_LOCK_COUNT */
|
||||
|
||||
/*
|
||||
* This defines the number of headers that we try to expire each time the
|
||||
* expire_ttl_headers() is run. The number should be small enough, so the
|
||||
* TTL-based header expiration doesn't take too long, but it should be large
|
||||
* enough, so we expire enough headers if their TTL is clustered.
|
||||
*/
|
||||
#define DNS_RBTDB_EXPIRE_TTL_COUNT 10
|
||||
|
||||
typedef struct {
|
||||
nodelock_t lock;
|
||||
/* Protected in the refcount routines. */
|
||||
|
|
@ -907,6 +915,10 @@ set_ttl(dns_rbtdb_t *rbtdb, rdatasetheader_t *header, dns_ttl_t newttl) {
|
|||
} else {
|
||||
isc_heap_decreased(heap, header->heap_index);
|
||||
}
|
||||
|
||||
if (newttl == 0) {
|
||||
isc_heap_delete(heap, header->heap_index);
|
||||
}
|
||||
}
|
||||
|
||||
static bool
|
||||
|
|
@ -6863,6 +6875,10 @@ rdataset_size(rdatasetheader_t *header) {
|
|||
return (sizeof(*header));
|
||||
}
|
||||
|
||||
static void
|
||||
expire_ttl_headers(dns_rbtdb_t *rbtdb, unsigned int locknum, bool tree_locked,
|
||||
isc_stdtime_t now);
|
||||
|
||||
static isc_result_t
|
||||
addrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
|
||||
isc_stdtime_t now, dns_rdataset_t *rdataset, unsigned int options,
|
||||
|
|
@ -6872,7 +6888,6 @@ addrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
|
|||
rbtdb_version_t *rbtversion = version;
|
||||
isc_region_t region;
|
||||
rdatasetheader_t *newheader;
|
||||
rdatasetheader_t *header;
|
||||
isc_result_t result;
|
||||
bool delegating;
|
||||
bool newnsec;
|
||||
|
|
@ -7045,20 +7060,7 @@ addrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
|
|||
cleanup_dead_nodes(rbtdb, rbtnode->locknum);
|
||||
}
|
||||
|
||||
header = isc_heap_element(rbtdb->heaps[rbtnode->locknum], 1);
|
||||
if (header != NULL) {
|
||||
dns_ttl_t rdh_ttl = header->rdh_ttl;
|
||||
|
||||
/* Only account for stale TTL if cache is not overmem */
|
||||
if (!cache_is_overmem) {
|
||||
rdh_ttl += STALE_TTL(header, rbtdb);
|
||||
}
|
||||
|
||||
if (rdh_ttl < now - RBTDB_VIRTUAL) {
|
||||
expire_header(rbtdb, header, tree_locked,
|
||||
expire_ttl);
|
||||
}
|
||||
}
|
||||
expire_ttl_headers(rbtdb, rbtnode->locknum, tree_locked, now);
|
||||
|
||||
/*
|
||||
* If we've been holding a write lock on the tree just for
|
||||
|
|
@ -10431,3 +10433,40 @@ expire_header(dns_rbtdb_t *rbtdb, rdatasetheader_t *header, bool tree_locked,
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Caller must be holding the node write lock.
|
||||
*/
|
||||
static void
|
||||
expire_ttl_headers(dns_rbtdb_t *rbtdb, unsigned int locknum, bool tree_locked,
|
||||
isc_stdtime_t now) {
|
||||
isc_heap_t *heap = rbtdb->heaps[locknum];
|
||||
|
||||
for (size_t i = 0; i < DNS_RBTDB_EXPIRE_TTL_COUNT; i++) {
|
||||
rdatasetheader_t *header = isc_heap_element(heap, 1);
|
||||
|
||||
if (header == NULL) {
|
||||
/* No headers left on this TTL heap; exit cleaning */
|
||||
return;
|
||||
}
|
||||
|
||||
dns_ttl_t ttl = header->rdh_ttl;
|
||||
|
||||
if (!isc_mem_isovermem(rbtdb->common.mctx)) {
|
||||
/* Only account for stale TTL if cache is not overmem */
|
||||
ttl += STALE_TTL(header, rbtdb);
|
||||
}
|
||||
|
||||
if (ttl >= now - RBTDB_VIRTUAL) {
|
||||
/*
|
||||
* The header at the top of this TTL heap is not yet
|
||||
* eligible for expiry, so none of the other headers on
|
||||
* the same heap can be eligible for expiry, either;
|
||||
* exit cleaning.
|
||||
*/
|
||||
return;
|
||||
}
|
||||
|
||||
expire_header(rbtdb, header, tree_locked, expire_ttl);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue