2
0
mirror of https://gitlab.isc.org/isc-projects/bind9 synced 2025-08-30 14:07:59 +00:00

chg: dev: Use RCU for rad name

The RAD/agent domain is a functionality from RFC 9567 that provides
a suffix for reporting error messages. On every query context reset,
we need to check if a RAD is configured and, if so, copy it.

Since we allow the RAD to be changed by reconfiguring the zone,
this access is currently protected by a mutex, which causes contention.

This commit replaces the mutex with RCU to reduce contention. The
change results in a 3% performance improvement in the 1M delegation
test.

Merge branch 'alessio/rcu-rad' into 'main'

See merge request isc-projects/bind9!10616
This commit is contained in:
Alessio Podda
2025-06-25 08:30:28 +00:00

View File

@@ -261,6 +261,20 @@ struct dns_keymgmt {
*/ */
#define DNS_KEYMGMT_HASH_BITS 12 #define DNS_KEYMGMT_HASH_BITS 12
typedef struct dns_rad {
isc_mem_t *mctx;
struct rcu_head rcu_head;
dns_fixedname_t fname;
} dns_rad_t;
static void
free_rad_rcu(struct rcu_head *rcu_head) {
dns_rad_t *rad = caa_container_of(rcu_head, dns_rad_t, rcu_head);
dns_fixedname_invalidate(&rad->fname);
isc_mem_putanddetach(&rad->mctx, rad, sizeof(*rad));
}
struct dns_zone { struct dns_zone {
/* Unlocked */ /* Unlocked */
unsigned int magic; unsigned int magic;
@@ -283,7 +297,7 @@ struct dns_zone {
isc_timer_t *timer; isc_timer_t *timer;
isc_refcount_t irefs; isc_refcount_t irefs;
dns_name_t origin; dns_name_t origin;
dns_name_t rad; dns_rad_t *rad;
char *masterfile; char *masterfile;
char *initfile; char *initfile;
const FILE *stream; /* loading from a stream? */ const FILE *stream; /* loading from a stream? */
@@ -1173,7 +1187,6 @@ dns_zone_create(dns_zone_t **zonep, isc_mem_t *mctx, unsigned int tid) {
isc_refcount_init(&zone->references, 1); isc_refcount_init(&zone->references, 1);
isc_refcount_init(&zone->irefs, 0); isc_refcount_init(&zone->irefs, 0);
dns_name_init(&zone->origin); dns_name_init(&zone->origin);
dns_name_init(&zone->rad);
isc_sockaddr_any(&zone->notifysrc4); isc_sockaddr_any(&zone->notifysrc4);
isc_sockaddr_any6(&zone->notifysrc6); isc_sockaddr_any6(&zone->notifysrc6);
isc_sockaddr_any(&zone->parentalsrc4); isc_sockaddr_any(&zone->parentalsrc4);
@@ -1344,9 +1357,9 @@ zone_free(dns_zone_t *zone) {
if (dns_name_dynamic(&zone->origin)) { if (dns_name_dynamic(&zone->origin)) {
dns_name_free(&zone->origin, zone->mctx); dns_name_free(&zone->origin, zone->mctx);
} }
if (dns_name_dynamic(&zone->rad)) {
dns_name_free(&zone->rad, zone->mctx); dns_zone_setrad(zone, NULL);
}
if (zone->strnamerd != NULL) { if (zone->strnamerd != NULL) {
isc_mem_free(zone->mctx, zone->strnamerd); isc_mem_free(zone->mctx, zone->strnamerd);
} }
@@ -24520,12 +24533,15 @@ dns_zone_getrad(dns_zone_t *zone, dns_name_t *name) {
REQUIRE(DNS_ZONE_VALID(zone)); REQUIRE(DNS_ZONE_VALID(zone));
REQUIRE(DNS_NAME_VALID(name)); REQUIRE(DNS_NAME_VALID(name));
LOCK_ZONE(zone); rcu_read_lock();
if (dns_name_dynamic(&zone->rad)) { dns_rad_t *rad = rcu_dereference(zone->rad);
dns_name_copy(&zone->rad, name); if (rad != NULL) {
dns_name_t *inner = dns_fixedname_name(&rad->fname);
dns_name_copy(inner, name);
result = ISC_R_SUCCESS; result = ISC_R_SUCCESS;
} }
UNLOCK_ZONE(zone); rcu_read_unlock();
return result; return result;
} }
@@ -24534,12 +24550,20 @@ dns_zone_setrad(dns_zone_t *zone, dns_name_t *name) {
REQUIRE(DNS_ZONE_VALID(zone)); REQUIRE(DNS_ZONE_VALID(zone));
REQUIRE(name == NULL || DNS_NAME_VALID(name)); REQUIRE(name == NULL || DNS_NAME_VALID(name));
LOCK_ZONE(zone); rcu_read_lock();
if (dns_name_dynamic(&zone->rad)) { dns_rad_t *new_rad = NULL;
dns_name_free(&zone->rad, zone->mctx);
}
if (name != NULL) { if (name != NULL) {
dns_name_dup(name, zone->mctx, &zone->rad); new_rad = isc_mem_get(zone->mctx, sizeof(*new_rad));
*new_rad = (dns_rad_t){};
dns_fixedname_init(&new_rad->fname);
isc_mem_attach(zone->mctx, &new_rad->mctx);
dns_name_copy(name, dns_fixedname_name(&new_rad->fname));
} }
UNLOCK_ZONE(zone); dns_rad_t *xchg_rad = rcu_xchg_pointer(&zone->rad, new_rad);
if (xchg_rad != NULL) {
call_rcu(&xchg_rad->rcu_head, free_rad_rcu);
}
rcu_read_unlock();
} }