Compare commits

...

2 Commits

Author SHA1 Message Date
Evan Hunt
40c8a04fe0 fixup! Add .up pointer to slabheader 2025-02-13 15:27:26 -08:00
Ondřej Surý
d7c329f79d Add .up pointer to slabheader 2025-02-13 15:27:25 -08:00
4 changed files with 95 additions and 85 deletions

View File

@@ -102,12 +102,16 @@ struct dns_slabheader {
* both head and tail pointers, and is doubly linked.
*/
struct dns_slabheader *next;
union {
struct dns_slabheader *next;
struct dns_slabheader *up;
};
/*%<
* If this is the top header for an rdataset, 'next' points
* to the top header for the next rdataset (i.e., the next type).
* Otherwise, it points up to the header whose down pointer points
* at this header.
*
* Otherwise 'up' points up to the header whose down pointer points at
* this header.
*/
struct dns_slabheader *down;
@@ -322,3 +326,9 @@ dns_slabheader_freeproof(isc_mem_t *mctx, dns_slabheader_proof_t **proof);
/*%<
* Free all memory associated with a nonexistence proof.
*/
dns_slabheader_t *
dns_slabheader_top(dns_slabheader_t *header);
/*%<
* Return the top header for the type or the negtype
*/

View File

@@ -3133,7 +3133,7 @@ find_header:
} else {
qpnode->data = newheader;
}
newheader->next = topheader->next;
newheader->next = header->next;
dns_slabheader_destroy(&header);
} else {
idx = HEADERNODE(newheader)->locknum;
@@ -3152,9 +3152,9 @@ find_header:
} else {
qpnode->data = newheader;
}
newheader->next = topheader->next;
newheader->down = topheader;
topheader->next = newheader;
newheader->next = header->next;
newheader->down = header;
header->up = newheader;
mark_ancient(header);
if (sigheader != NULL) {
mark_ancient(sigheader);
@@ -3202,14 +3202,12 @@ find_header:
}
newheader->next = topheader->next;
newheader->down = topheader;
topheader->next = newheader;
topheader->up = newheader;
qpnode->dirty = 1;
} else {
/*
* No rdatasets of the given type exist at the node.
*/
INSIST(newheader->down == NULL);
if (prio_header(newheader)) {
/* This is a priority type, prepend it */
newheader->next = qpnode->data;
@@ -3779,9 +3777,8 @@ rdatasetiter_next(dns_rdatasetiter_t *it DNS__DB_FLARG) {
qpc_rditer_t *iterator = (qpc_rditer_t *)it;
qpcache_t *qpdb = (qpcache_t *)(iterator->common.db);
qpcnode_t *qpnode = (qpcnode_t *)iterator->common.node;
dns_slabheader_t *header = NULL, *top_next = NULL;
dns_typepair_t type, negtype;
dns_rdatatype_t rdtype, covers;
dns_slabheader_t *header = NULL;
dns_slabheader_t *topheader = NULL, *topheader_next = NULL;
isc_rwlocktype_t nlocktype = isc_rwlocktype_none;
isc_rwlock_t *nlock = &qpdb->buckets[qpnode->locknum].lock;
bool expiredok = EXPIREDOK(iterator);
@@ -3793,36 +3790,23 @@ rdatasetiter_next(dns_rdatasetiter_t *it DNS__DB_FLARG) {
NODE_RDLOCK(nlock, &nlocktype);
type = header->type;
rdtype = DNS_TYPEPAIR_TYPE(header->type);
if (NEGATIVE(header)) {
covers = DNS_TYPEPAIR_COVERS(header->type);
negtype = DNS_TYPEPAIR_VALUE(covers, 0);
} else {
negtype = DNS_TYPEPAIR_VALUE(0, rdtype);
}
/*
* Find the start of the header chain for the next type
* by walking back up the list.
* Find the start of the header chain for the next type.
*/
top_next = header->next;
while (top_next != NULL &&
(top_next->type == type || top_next->type == negtype))
{
top_next = top_next->next;
}
if (expiredok) {
topheader = dns_slabheader_top(header);
topheader_next = topheader->next;
if (expiredok && header->down != NULL) {
/*
* Keep walking down the list if possible or
* start the next type.
*/
header = header->down != NULL ? header->down : top_next;
header = header->down;
} else {
header = top_next;
header = topheader->next;
}
for (; header != NULL; header = top_next) {
top_next = header->next;
for (; header != NULL; header = topheader_next) {
topheader_next = header->next;
do {
if (expiredok) {
if (!NONEXISTENT(header)) {
@@ -3841,15 +3825,12 @@ rdatasetiter_next(dns_rdatasetiter_t *it DNS__DB_FLARG) {
if (header != NULL) {
break;
}
/*
* Find the start of the header chain for the next type
* by walking back up the list.
* Find the start of the header chain for the next type.
*/
while (top_next != NULL &&
(top_next->type == type || top_next->type == negtype))
{
top_next = top_next->next;
}
topheader = topheader->next;
header = topheader;
}
NODE_UNLOCK(nlock, &nlocktype);

View File

@@ -775,7 +775,7 @@ qpznode_acquire(qpzonedb_t *qpdb, qpznode_t *node DNS__DB_FLARG) {
static void
clean_zone_node(qpznode_t *node, uint32_t least_serial) {
dns_slabheader_t *current = NULL, *dcurrent = NULL;
dns_slabheader_t *down_next = NULL, *dparent = NULL;
dns_slabheader_t *dcurrent_down = NULL, *dparent = NULL;
dns_slabheader_t *top_prev = NULL, *top_next = NULL;
bool still_dirty = false;
@@ -794,17 +794,17 @@ clean_zone_node(qpznode_t *node, uint32_t least_serial) {
*/
dparent = current;
for (dcurrent = current->down; dcurrent != NULL;
dcurrent = down_next)
dcurrent = dcurrent_down)
{
down_next = dcurrent->down;
dcurrent_down = dcurrent->down;
INSIST(dcurrent->serial <= dparent->serial);
if (dcurrent->serial == dparent->serial ||
IGNORE(dcurrent))
{
if (down_next != NULL) {
down_next->next = dparent;
if (dcurrent_down != NULL) {
dcurrent_down->up = dparent;
}
dparent->down = down_next;
dparent->down = dcurrent_down;
dns_slabheader_destroy(&dcurrent);
} else {
dparent = dcurrent;
@@ -815,9 +815,10 @@ clean_zone_node(qpznode_t *node, uint32_t least_serial) {
* We've now eliminated all IGNORE datasets with the possible
* exception of current, which we now check.
*/
if (IGNORE(current)) {
down_next = current->down;
if (down_next == NULL) {
dcurrent = current;
if (IGNORE(dcurrent)) {
dcurrent_down = current->down;
if (dcurrent_down == NULL) {
if (top_prev != NULL) {
top_prev->next = current->next;
} else {
@@ -835,13 +836,13 @@ clean_zone_node(qpznode_t *node, uint32_t least_serial) {
* current.
*/
if (top_prev != NULL) {
top_prev->next = down_next;
top_prev->next = dcurrent_down;
} else {
node->data = down_next;
node->data = dcurrent_down;
}
down_next->next = top_next;
dcurrent_down->next = top_next;
dns_slabheader_destroy(&current);
current = down_next;
current = dcurrent_down;
}
}
@@ -851,9 +852,9 @@ clean_zone_node(qpznode_t *node, uint32_t least_serial) {
*/
dparent = current;
for (dcurrent = current->down; dcurrent != NULL;
dcurrent = down_next)
dcurrent = dcurrent_down)
{
down_next = dcurrent->down;
dcurrent_down = dcurrent->down;
if (dcurrent->serial < least_serial) {
break;
}
@@ -866,10 +867,10 @@ clean_zone_node(qpznode_t *node, uint32_t least_serial) {
*/
if (dcurrent != NULL) {
do {
down_next = dcurrent->down;
dcurrent_down = dcurrent->down;
INSIST(dcurrent->serial <= least_serial);
dns_slabheader_destroy(&dcurrent);
dcurrent = down_next;
dcurrent = dcurrent_down;
} while (dcurrent != NULL);
dparent->down = NULL;
}
@@ -1980,7 +1981,7 @@ add(qpzonedb_t *qpdb, qpznode_t *node, const dns_name_t *nodename,
}
newheader->next = topheader->next;
newheader->down = topheader;
topheader->next = newheader;
topheader->up = newheader;
node->dirty = true;
if (changed != NULL) {
changed->dirty = true;
@@ -2023,7 +2024,7 @@ add(qpzonedb_t *qpdb, qpznode_t *node, const dns_name_t *nodename,
}
newheader->next = topheader->next;
newheader->down = topheader;
topheader->next = newheader;
topheader->up = newheader;
if (changed != NULL) {
changed->dirty = true;
}
@@ -4109,9 +4110,8 @@ rdatasetiter_next(dns_rdatasetiter_t *iterator DNS__DB_FLARG) {
qpzonedb_t *qpdb = (qpzonedb_t *)(qrditer->common.db);
qpznode_t *node = (qpznode_t *)qrditer->common.node;
qpz_version_t *version = (qpz_version_t *)qrditer->common.version;
dns_slabheader_t *header = NULL, *top_next = NULL;
dns_typepair_t type, negtype;
dns_rdatatype_t rdtype;
dns_slabheader_t *header = NULL;
dns_slabheader_t *topheader, *topheader_next = NULL;
isc_rwlocktype_t nlocktype = isc_rwlocktype_none;
isc_rwlock_t *nlock = &qpdb->buckets[node->locknum].lock;
@@ -4122,22 +4122,14 @@ rdatasetiter_next(dns_rdatasetiter_t *iterator DNS__DB_FLARG) {
NODE_RDLOCK(nlock, &nlocktype);
type = header->type;
rdtype = DNS_TYPEPAIR_TYPE(header->type);
negtype = DNS_TYPEPAIR_VALUE(0, rdtype);
/*
* Find the start of the header chain for the next type
* by walking back up the list.
* Find the start of the header chain for the next type.
*/
top_next = header->next;
while (top_next != NULL &&
(top_next->type == type || top_next->type == negtype))
{
top_next = top_next->next;
}
for (header = top_next; header != NULL; header = top_next) {
top_next = header->next;
topheader = dns_slabheader_top(header);
topheader_next = topheader->next;
for (header = topheader_next; header != NULL; header = topheader_next) {
topheader_next = header->next;
do {
if (header->serial <= version->serial &&
!IGNORE(header))
@@ -4153,15 +4145,12 @@ rdatasetiter_next(dns_rdatasetiter_t *iterator DNS__DB_FLARG) {
if (header != NULL) {
break;
}
/*
* Find the start of the header chain for the next type
* by walking back up the list.
* Find the start of the header chain for the next type.
*/
while (top_next != NULL &&
(top_next->type == type || top_next->type == negtype))
{
top_next = top_next->next;
}
topheader = topheader->next;
header = topheader;
}
NODE_UNLOCK(nlock, &nlocktype);

View File

@@ -39,6 +39,9 @@
#define NONEXISTENT(header) \
((atomic_load_acquire(&(header)->attributes) & \
DNS_SLABHEADERATTR_NONEXISTENT) != 0)
#define NEGATIVE(header) \
((atomic_load_acquire(&(header)->attributes) & \
DNS_SLABHEADERATTR_NEGATIVE) != 0)
/*
* The rdataslab structure allows iteration to occur in both load order
@@ -1188,3 +1191,30 @@ rdataset_getownercase(const dns_rdataset_t *rdataset, dns_name_t *name) {
unlock:
dns_db_unlocknode(header->db, header->node, isc_rwlocktype_read);
}
dns_slabheader_t *
dns_slabheader_top(dns_slabheader_t *header) {
dns_typepair_t type, negtype;
dns_rdatatype_t rdtype, covers;
type = header->type;
rdtype = DNS_TYPEPAIR_TYPE(header->type);
if (NEGATIVE(header)) {
covers = DNS_TYPEPAIR_COVERS(header->type);
negtype = DNS_TYPEPAIR_VALUE(covers, 0);
} else {
negtype = DNS_TYPEPAIR_VALUE(0, rdtype);
}
/*
* Find the start of the header chain for the next type
* by walking back up the list.
*/
while (header->up != NULL &&
(header->up->type == type || header->up->type == negtype))
{
header = header->up;
}
return header;
}