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 {
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,
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;
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;
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);
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
/*
* On cache hit, we only mark the header as seen.
*/
- ISC_SIEVE_MARK(header, visited);
+ ISC_SIEVE_MARK(header->top, visited);
}
/*
} 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;
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);
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;
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);
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);
}
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;
}
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);
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 */
/* 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;
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);
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
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));
/*
* 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, resigned, link);
- ISC_LIST_UNLINK(resigned_list, header, link);
+ isc_mem_put(db->mctx, resigned, sizeof(*resigned));
nlock = qpzone_get_lock(HEADERNODE(header));
NODE_WRLOCK(nlock, &nlocktype);
.typepair = typepair,
.trust = rdataset->trust,
.ttl = rdataset->ttl,
- .link = ISC_LINK_INITIALIZER,
};
}
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);
h = isc_mem_get(mctx, sizeof(*h));
*h = (dns_slabheader_t){
- .link = ISC_LINK_INITIALIZER,
.node = node,
};
return h;
dns_slabtop_t *top = isc_mem_get(mctx, sizeof(*top));
*top = (dns_slabtop_t){
.typepair = typepair,
+ .link = ISC_LINK_INITIALIZER,
};
return top;