mirror of
https://gitlab.isc.org/isc-projects/bind9
synced 2025-08-22 01:59:26 +00:00
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.
This commit is contained in:
parent
f4d8841f0d
commit
d7801aec71
@ -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,
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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, header, link);
|
||||
ISC_LIST_UNLINK(resigned_list, resigned, link);
|
||||
|
||||
isc_mem_put(db->mctx, resigned, sizeof(*resigned));
|
||||
|
||||
nlock = qpzone_get_lock(HEADERNODE(header));
|
||||
NODE_WRLOCK(nlock, &nlocktype);
|
||||
|
@ -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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user