mirror of
https://github.com/isc-projects/bind9.git
synced 2026-05-28 04:34:54 -04:00
Create list of dirty dirty headers that needs cleaning
Instead of just flagging the qpcache node to be dirty, add the headers to be cleaned to the dirty list and when cleaning the node, only walk through the dirty node, not all the slabtops.
This commit is contained in:
parent
758c5973ef
commit
e93eed28f7
3 changed files with 33 additions and 15 deletions
|
|
@ -113,6 +113,11 @@ struct dns_slabheader {
|
|||
dns_slabheader_proof_t *noqname;
|
||||
dns_slabheader_proof_t *closest;
|
||||
|
||||
/*%
|
||||
* Used for cleaning.
|
||||
*/
|
||||
ISC_LINK(dns_slabheader_t) dirtylink;
|
||||
|
||||
/*%
|
||||
* Points to the top slabtop structure for the type.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@
|
|||
#include <isc/file.h>
|
||||
#include <isc/heap.h>
|
||||
#include <isc/hex.h>
|
||||
#include <isc/list.h>
|
||||
#include <isc/log.h>
|
||||
#include <isc/loop.h>
|
||||
#include <isc/mem.h>
|
||||
|
|
@ -152,15 +153,7 @@ struct qpcnode {
|
|||
struct cds_list_head types_list;
|
||||
struct cds_list_head *data;
|
||||
|
||||
/*%
|
||||
* NOTE: The 'dirty' flag is protected by the node lock, so
|
||||
* this bitfield has to be separated from the one above.
|
||||
* We don't want it to share the same qword with bits
|
||||
* that can be accessed without the node lock.
|
||||
*/
|
||||
uint8_t : 0;
|
||||
uint8_t dirty : 1;
|
||||
uint8_t : 0;
|
||||
ISC_LIST(dns_slabheader_t) dirty;
|
||||
|
||||
/*%
|
||||
* Used for dead nodes cleaning. This linked list is used to mark nodes
|
||||
|
|
@ -579,7 +572,17 @@ clean_cache_node(qpcache_t *qpdb, qpcnode_t *node) {
|
|||
* Caller must be holding the node lock.
|
||||
*/
|
||||
|
||||
DNS_SLABTOP_FOREACH(top, node->data) {
|
||||
/*
|
||||
* We can't use ordinary loop because multiple headers to be cleaned can
|
||||
* be stashed under a single slabtop.
|
||||
*/
|
||||
for (dns_slabheader_t *dirty = ISC_LIST_HEAD(node->dirty);
|
||||
dirty != NULL; dirty = ISC_LIST_HEAD(node->dirty))
|
||||
{
|
||||
dns_slabtop_t *top = dirty->top;
|
||||
|
||||
ISC_LIST_UNLINK(node->dirty, dirty, dirtylink);
|
||||
|
||||
clean_cache_headers(top);
|
||||
|
||||
/*
|
||||
|
|
@ -617,8 +620,6 @@ clean_cache_node(qpcache_t *qpdb, qpcnode_t *node) {
|
|||
dns_slabtop_destroy(((dns_db_t *)qpdb)->mctx, &top);
|
||||
}
|
||||
}
|
||||
|
||||
node->dirty = false;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -767,7 +768,7 @@ qpcnode_release(qpcache_t *qpdb, qpcnode_t *node, isc_rwlocktype_t *nlocktypep,
|
|||
}
|
||||
|
||||
/* Handle easy and typical case first. */
|
||||
if (!node->dirty && !cds_list_empty(node->data)) {
|
||||
if (ISC_LIST_EMPTY(node->dirty) && !cds_list_empty(node->data)) {
|
||||
goto unref;
|
||||
}
|
||||
|
||||
|
|
@ -794,7 +795,7 @@ qpcnode_release(qpcache_t *qpdb, qpcnode_t *node, isc_rwlocktype_t *nlocktypep,
|
|||
}
|
||||
}
|
||||
|
||||
if (node->dirty) {
|
||||
if (!ISC_LIST_EMPTY(node->dirty)) {
|
||||
clean_cache_node(qpdb, node);
|
||||
}
|
||||
|
||||
|
|
@ -926,7 +927,9 @@ static void
|
|||
mark_ancient(dns_slabheader_t *header) {
|
||||
setttl(header, 0);
|
||||
mark(header, DNS_SLABHEADERATTR_ANCIENT);
|
||||
HEADERNODE(header)->dirty = 1;
|
||||
if (!ISC_LINK_LINKED(header, dirtylink)) {
|
||||
ISC_LIST_APPEND(HEADERNODE(header)->dirty, header, dirtylink);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -2425,6 +2428,7 @@ new_qpcnode(qpcache_t *qpdb, const dns_name_t *name, dns_namespace_t nspace) {
|
|||
.nspace = nspace,
|
||||
.references = ISC_REFCOUNT_INITIALIZER(1),
|
||||
.locknum = isc_random_uniform(qpdb->buckets_count),
|
||||
.dirty = ISC_LIST_INITIALIZER,
|
||||
};
|
||||
|
||||
isc_mem_attach(qpdb->common.mctx, &newdata->mctx);
|
||||
|
|
@ -3741,6 +3745,10 @@ qpcnode_deletedata(dns_dbnode_t *node ISC_ATTR_UNUSED, void *data) {
|
|||
dns_slabheader_t *header = data;
|
||||
qpcache_t *qpdb = HEADERNODE(header)->qpdb;
|
||||
|
||||
if (ISC_LINK_LINKED(header, dirtylink)) {
|
||||
ISC_LIST_UNLINK(HEADERNODE(header)->dirty, header, dirtylink);
|
||||
}
|
||||
|
||||
if (header->heap != NULL && header->heap_index != 0) {
|
||||
isc_heap_delete(header->heap, header->heap_index);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@
|
|||
|
||||
#include <isc/ascii.h>
|
||||
#include <isc/atomic.h>
|
||||
#include <isc/list.h>
|
||||
#include <isc/mem.h>
|
||||
#include <isc/region.h>
|
||||
#include <isc/result.h>
|
||||
|
|
@ -327,6 +328,7 @@ dns_rdataslab_fromrdataset(dns_rdataset_t *rdataset, isc_mem_t *mctx,
|
|||
.typepair = typepair,
|
||||
.trust = rdataset->trust,
|
||||
.ttl = rdataset->ttl,
|
||||
.dirtylink = ISC_LINK_INITIALIZER,
|
||||
};
|
||||
}
|
||||
|
||||
|
|
@ -833,6 +835,8 @@ dns_slabheader_reset(dns_slabheader_t *h, dns_dbnode_t *node) {
|
|||
atomic_init(&h->attributes, 0);
|
||||
atomic_init(&h->last_refresh_fail_ts, 0);
|
||||
|
||||
ISC_LINK_INIT(h, dirtylink);
|
||||
|
||||
STATIC_ASSERT(sizeof(h->attributes) == 2,
|
||||
"The .attributes field of dns_slabheader_t needs to be "
|
||||
"16-bit int type exactly.");
|
||||
|
|
@ -845,6 +849,7 @@ dns_slabheader_new(isc_mem_t *mctx, dns_dbnode_t *node) {
|
|||
h = isc_mem_get(mctx, sizeof(*h));
|
||||
*h = (dns_slabheader_t){
|
||||
.node = node,
|
||||
.dirtylink = ISC_LINK_INITIALIZER,
|
||||
};
|
||||
return h;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue