mirror of
https://github.com/NLnetLabs/unbound.git
synced 2025-12-20 23:00:56 -05:00
- speed up unbound (reports say it could be up to 10%), by reducing
lock contention on localzones.lock. It is changed to an rwlock. git-svn-id: file:///svn/unbound/trunk@3048 be551aaa-1e26-0410-a405-d3ace91eadb9
This commit is contained in:
parent
9a1e15776f
commit
1a24208658
5 changed files with 48 additions and 44 deletions
|
|
@ -981,7 +981,7 @@ do_zone_add(SSL* ssl, struct worker* worker, char* arg)
|
|||
free(nm);
|
||||
return;
|
||||
}
|
||||
lock_quick_lock(&worker->daemon->local_zones->lock);
|
||||
lock_rw_wrlock(&worker->daemon->local_zones->lock);
|
||||
if((z=local_zones_find(worker->daemon->local_zones, nm, nmlen,
|
||||
nmlabs, LDNS_RR_CLASS_IN))) {
|
||||
/* already present in tree */
|
||||
|
|
@ -989,17 +989,17 @@ do_zone_add(SSL* ssl, struct worker* worker, char* arg)
|
|||
z->type = t; /* update type anyway */
|
||||
lock_rw_unlock(&z->lock);
|
||||
free(nm);
|
||||
lock_quick_unlock(&worker->daemon->local_zones->lock);
|
||||
lock_rw_unlock(&worker->daemon->local_zones->lock);
|
||||
send_ok(ssl);
|
||||
return;
|
||||
}
|
||||
if(!local_zones_add_zone(worker->daemon->local_zones, nm, nmlen,
|
||||
nmlabs, LDNS_RR_CLASS_IN, t)) {
|
||||
lock_quick_unlock(&worker->daemon->local_zones->lock);
|
||||
lock_rw_unlock(&worker->daemon->local_zones->lock);
|
||||
ssl_printf(ssl, "error out of memory\n");
|
||||
return;
|
||||
}
|
||||
lock_quick_unlock(&worker->daemon->local_zones->lock);
|
||||
lock_rw_unlock(&worker->daemon->local_zones->lock);
|
||||
send_ok(ssl);
|
||||
}
|
||||
|
||||
|
|
@ -1013,13 +1013,13 @@ do_zone_remove(SSL* ssl, struct worker* worker, char* arg)
|
|||
struct local_zone* z;
|
||||
if(!parse_arg_name(ssl, arg, &nm, &nmlen, &nmlabs))
|
||||
return;
|
||||
lock_quick_lock(&worker->daemon->local_zones->lock);
|
||||
lock_rw_wrlock(&worker->daemon->local_zones->lock);
|
||||
if((z=local_zones_find(worker->daemon->local_zones, nm, nmlen,
|
||||
nmlabs, LDNS_RR_CLASS_IN))) {
|
||||
/* present in tree */
|
||||
local_zones_del_zone(worker->daemon->local_zones, z);
|
||||
}
|
||||
lock_quick_unlock(&worker->daemon->local_zones->lock);
|
||||
lock_rw_unlock(&worker->daemon->local_zones->lock);
|
||||
free(nm);
|
||||
send_ok(ssl);
|
||||
}
|
||||
|
|
@ -1974,7 +1974,7 @@ do_list_local_zones(SSL* ssl, struct worker* worker)
|
|||
struct local_zones* zones = worker->daemon->local_zones;
|
||||
struct local_zone* z;
|
||||
char buf[257];
|
||||
lock_quick_lock(&zones->lock);
|
||||
lock_rw_rdlock(&zones->lock);
|
||||
RBTREE_FOR(z, struct local_zone*, &zones->ztree) {
|
||||
lock_rw_rdlock(&z->lock);
|
||||
dname_str(z->name, buf);
|
||||
|
|
@ -1982,7 +1982,7 @@ do_list_local_zones(SSL* ssl, struct worker* worker)
|
|||
local_zone_type2str(z->type));
|
||||
lock_rw_unlock(&z->lock);
|
||||
}
|
||||
lock_quick_unlock(&zones->lock);
|
||||
lock_rw_unlock(&zones->lock);
|
||||
}
|
||||
|
||||
/** do the list_local_data command */
|
||||
|
|
@ -1995,7 +1995,7 @@ do_list_local_data(SSL* ssl, struct worker* worker)
|
|||
struct local_rrset* p;
|
||||
char* s = (char*)sldns_buffer_begin(worker->env.scratch_buffer);
|
||||
size_t slen = sldns_buffer_capacity(worker->env.scratch_buffer);
|
||||
lock_quick_lock(&zones->lock);
|
||||
lock_rw_rdlock(&zones->lock);
|
||||
RBTREE_FOR(z, struct local_zone*, &zones->ztree) {
|
||||
lock_rw_rdlock(&z->lock);
|
||||
RBTREE_FOR(d, struct local_data*, &z->data) {
|
||||
|
|
@ -2016,7 +2016,7 @@ do_list_local_data(SSL* ssl, struct worker* worker)
|
|||
}
|
||||
lock_rw_unlock(&z->lock);
|
||||
}
|
||||
lock_quick_unlock(&zones->lock);
|
||||
lock_rw_unlock(&zones->lock);
|
||||
}
|
||||
|
||||
/** tell other processes to execute the command */
|
||||
|
|
|
|||
|
|
@ -2,6 +2,8 @@
|
|||
- Change unbound-event.h to use void* buffer, length idiom.
|
||||
- iana portlist updated.
|
||||
- unbound-event.h is installed if you configure --enable-event-api.
|
||||
- speed up unbound (reports say it could be up to 10%), by reducing
|
||||
lock contention on localzones.lock. It is changed to an rwlock.
|
||||
|
||||
21 January 2014: Wouter
|
||||
- Fix #547: no trustanchor written if filesystem full, fclose checked.
|
||||
|
|
|
|||
|
|
@ -1125,23 +1125,23 @@ int ub_ctx_zone_add(struct ub_ctx* ctx, const char *zone_name,
|
|||
return UB_SYNTAX;
|
||||
}
|
||||
|
||||
lock_quick_lock(&ctx->local_zones->lock);
|
||||
lock_rw_wrlock(&ctx->local_zones->lock);
|
||||
if((z=local_zones_find(ctx->local_zones, nm, nmlen, nmlabs,
|
||||
LDNS_RR_CLASS_IN))) {
|
||||
/* already present in tree */
|
||||
lock_rw_wrlock(&z->lock);
|
||||
z->type = t; /* update type anyway */
|
||||
lock_rw_unlock(&z->lock);
|
||||
lock_quick_unlock(&ctx->local_zones->lock);
|
||||
lock_rw_unlock(&ctx->local_zones->lock);
|
||||
free(nm);
|
||||
return UB_NOERROR;
|
||||
}
|
||||
if(!local_zones_add_zone(ctx->local_zones, nm, nmlen, nmlabs,
|
||||
LDNS_RR_CLASS_IN, t)) {
|
||||
lock_quick_unlock(&ctx->local_zones->lock);
|
||||
lock_rw_unlock(&ctx->local_zones->lock);
|
||||
return UB_NOMEM;
|
||||
}
|
||||
lock_quick_unlock(&ctx->local_zones->lock);
|
||||
lock_rw_unlock(&ctx->local_zones->lock);
|
||||
return UB_NOERROR;
|
||||
}
|
||||
|
||||
|
|
@ -1160,13 +1160,13 @@ int ub_ctx_zone_remove(struct ub_ctx* ctx, const char *zone_name)
|
|||
return UB_SYNTAX;
|
||||
}
|
||||
|
||||
lock_quick_lock(&ctx->local_zones->lock);
|
||||
lock_rw_wrlock(&ctx->local_zones->lock);
|
||||
if((z=local_zones_find(ctx->local_zones, nm, nmlen, nmlabs,
|
||||
LDNS_RR_CLASS_IN))) {
|
||||
/* present in tree */
|
||||
local_zones_del_zone(ctx->local_zones, z);
|
||||
}
|
||||
lock_quick_unlock(&ctx->local_zones->lock);
|
||||
lock_rw_unlock(&ctx->local_zones->lock);
|
||||
free(nm);
|
||||
return UB_NOERROR;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -59,7 +59,7 @@ local_zones_create(void)
|
|||
if(!zones)
|
||||
return NULL;
|
||||
rbtree_init(&zones->ztree, &local_zone_cmp);
|
||||
lock_quick_init(&zones->lock);
|
||||
lock_rw_init(&zones->lock);
|
||||
lock_protect(&zones->lock, &zones->ztree, sizeof(zones->ztree));
|
||||
/* also lock protects the rbnode's in struct local_zone */
|
||||
return zones;
|
||||
|
|
@ -78,7 +78,7 @@ local_zones_delete(struct local_zones* zones)
|
|||
{
|
||||
if(!zones)
|
||||
return;
|
||||
lock_quick_destroy(&zones->lock);
|
||||
lock_rw_destroy(&zones->lock);
|
||||
/* walk through zones and delete them all */
|
||||
traverse_postorder(&zones->ztree, lzdel, NULL);
|
||||
free(zones);
|
||||
|
|
@ -174,16 +174,16 @@ lz_enter_zone_dname(struct local_zones* zones, uint8_t* nm, size_t len,
|
|||
}
|
||||
|
||||
/* add to rbtree */
|
||||
lock_quick_lock(&zones->lock);
|
||||
lock_rw_wrlock(&zones->lock);
|
||||
lock_rw_wrlock(&z->lock);
|
||||
if(!rbtree_insert(&zones->ztree, &z->node)) {
|
||||
log_warn("duplicate local-zone");
|
||||
lock_rw_unlock(&z->lock);
|
||||
local_zone_delete(z);
|
||||
lock_quick_unlock(&zones->lock);
|
||||
lock_rw_unlock(&zones->lock);
|
||||
return NULL;
|
||||
}
|
||||
lock_quick_unlock(&zones->lock);
|
||||
lock_rw_unlock(&zones->lock);
|
||||
return z;
|
||||
}
|
||||
|
||||
|
|
@ -490,14 +490,14 @@ lz_enter_rr_str(struct local_zones* zones, const char* rr)
|
|||
return 0;
|
||||
}
|
||||
labs = dname_count_size_labels(rr_name, &len);
|
||||
lock_quick_lock(&zones->lock);
|
||||
lock_rw_rdlock(&zones->lock);
|
||||
z = local_zones_lookup(zones, rr_name, len, labs, rr_class);
|
||||
if(!z) {
|
||||
lock_quick_unlock(&zones->lock);
|
||||
lock_rw_unlock(&zones->lock);
|
||||
fatal_exit("internal error: no zone for rr %s", rr);
|
||||
}
|
||||
lock_rw_wrlock(&z->lock);
|
||||
lock_quick_unlock(&zones->lock);
|
||||
lock_rw_unlock(&zones->lock);
|
||||
free(rr_name);
|
||||
r = lz_enter_rr_into_zone(z, rr);
|
||||
lock_rw_unlock(&z->lock);
|
||||
|
|
@ -530,13 +530,13 @@ lz_exists(struct local_zones* zones, const char* name)
|
|||
log_err("bad name %s", name);
|
||||
return 0;
|
||||
}
|
||||
lock_quick_lock(&zones->lock);
|
||||
lock_rw_rdlock(&zones->lock);
|
||||
if(rbtree_search(&zones->ztree, &z.node)) {
|
||||
lock_quick_unlock(&zones->lock);
|
||||
lock_rw_unlock(&zones->lock);
|
||||
free(z.name);
|
||||
return 1;
|
||||
}
|
||||
lock_quick_unlock(&zones->lock);
|
||||
lock_rw_unlock(&zones->lock);
|
||||
free(z.name);
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -693,7 +693,7 @@ init_parents(struct local_zones* zones)
|
|||
{
|
||||
struct local_zone* node, *prev = NULL, *p;
|
||||
int m;
|
||||
lock_quick_lock(&zones->lock);
|
||||
lock_rw_wrlock(&zones->lock);
|
||||
RBTREE_FOR(node, struct local_zone*, &zones->ztree) {
|
||||
lock_rw_wrlock(&node->lock);
|
||||
node->parent = NULL;
|
||||
|
|
@ -718,7 +718,7 @@ init_parents(struct local_zones* zones)
|
|||
prev = node;
|
||||
lock_rw_unlock(&node->lock);
|
||||
}
|
||||
lock_quick_unlock(&zones->lock);
|
||||
lock_rw_unlock(&zones->lock);
|
||||
}
|
||||
|
||||
/** enter implicit transparent zone for local-data: without local-zone: */
|
||||
|
|
@ -748,7 +748,7 @@ lz_setup_implicit(struct local_zones* zones, struct config_file* cfg)
|
|||
return 0;
|
||||
}
|
||||
labs = dname_count_size_labels(rr_name, &len);
|
||||
lock_quick_lock(&zones->lock);
|
||||
lock_rw_rdlock(&zones->lock);
|
||||
if(!local_zones_lookup(zones, rr_name, len, labs, rr_class)) {
|
||||
if(!have_name) {
|
||||
dclass = rr_class;
|
||||
|
|
@ -763,7 +763,7 @@ lz_setup_implicit(struct local_zones* zones, struct config_file* cfg)
|
|||
/* process other classes later */
|
||||
free(rr_name);
|
||||
have_other_classes = 1;
|
||||
lock_quick_unlock(&zones->lock);
|
||||
lock_rw_unlock(&zones->lock);
|
||||
continue;
|
||||
}
|
||||
/* find smallest shared topdomain */
|
||||
|
|
@ -774,7 +774,7 @@ lz_setup_implicit(struct local_zones* zones, struct config_file* cfg)
|
|||
match = m;
|
||||
}
|
||||
} else free(rr_name);
|
||||
lock_quick_unlock(&zones->lock);
|
||||
lock_rw_unlock(&zones->lock);
|
||||
}
|
||||
if(have_name) {
|
||||
uint8_t* n2;
|
||||
|
|
@ -919,7 +919,7 @@ local_zone_out(struct local_zone* z)
|
|||
void local_zones_print(struct local_zones* zones)
|
||||
{
|
||||
struct local_zone* z;
|
||||
lock_quick_lock(&zones->lock);
|
||||
lock_rw_rdlock(&zones->lock);
|
||||
log_info("number of auth zones %u", (unsigned)zones->ztree.count);
|
||||
RBTREE_FOR(z, struct local_zone*, &zones->ztree) {
|
||||
lock_rw_rdlock(&z->lock);
|
||||
|
|
@ -956,7 +956,7 @@ void local_zones_print(struct local_zones* zones)
|
|||
local_zone_out(z);
|
||||
lock_rw_unlock(&z->lock);
|
||||
}
|
||||
lock_quick_unlock(&zones->lock);
|
||||
lock_rw_unlock(&zones->lock);
|
||||
}
|
||||
|
||||
/** encode answer consisting of 1 rrset */
|
||||
|
|
@ -1106,15 +1106,15 @@ local_zones_answer(struct local_zones* zones, struct query_info* qinfo,
|
|||
struct local_data* ld;
|
||||
struct local_zone* z;
|
||||
int r;
|
||||
lock_quick_lock(&zones->lock);
|
||||
lock_rw_rdlock(&zones->lock);
|
||||
z = local_zones_lookup(zones, qinfo->qname,
|
||||
qinfo->qname_len, labs, qinfo->qclass);
|
||||
if(!z) {
|
||||
lock_quick_unlock(&zones->lock);
|
||||
lock_rw_unlock(&zones->lock);
|
||||
return 0;
|
||||
}
|
||||
lock_rw_rdlock(&z->lock);
|
||||
lock_quick_unlock(&zones->lock);
|
||||
lock_rw_unlock(&zones->lock);
|
||||
|
||||
if(local_data_answer(z, qinfo, edns, buf, temp, labs, &ld)) {
|
||||
lock_rw_unlock(&z->lock);
|
||||
|
|
@ -1238,20 +1238,22 @@ local_zones_add_RR(struct local_zones* zones, const char* rr)
|
|||
return 0;
|
||||
}
|
||||
labs = dname_count_size_labels(rr_name, &len);
|
||||
lock_quick_lock(&zones->lock);
|
||||
/* could first try readlock then get writelock if zone does not exist,
|
||||
* but we do not add enough RRs (from multiple threads) to optimize */
|
||||
lock_rw_wrlock(&zones->lock);
|
||||
z = local_zones_lookup(zones, rr_name, len, labs, rr_class);
|
||||
if(!z) {
|
||||
z = local_zones_add_zone(zones, rr_name, len, labs, rr_class,
|
||||
local_zone_transparent);
|
||||
if(!z) {
|
||||
lock_quick_unlock(&zones->lock);
|
||||
lock_rw_unlock(&zones->lock);
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
free(rr_name);
|
||||
}
|
||||
lock_rw_wrlock(&z->lock);
|
||||
lock_quick_unlock(&zones->lock);
|
||||
lock_rw_unlock(&zones->lock);
|
||||
r = lz_enter_rr_into_zone(z, rr);
|
||||
lock_rw_unlock(&z->lock);
|
||||
return r;
|
||||
|
|
@ -1297,15 +1299,15 @@ void local_zones_del_data(struct local_zones* zones,
|
|||
/* find zone */
|
||||
struct local_zone* z;
|
||||
struct local_data* d;
|
||||
lock_quick_lock(&zones->lock);
|
||||
lock_rw_rdlock(&zones->lock);
|
||||
z = local_zones_lookup(zones, name, len, labs, dclass);
|
||||
if(!z) {
|
||||
/* no such zone, we're done */
|
||||
lock_quick_unlock(&zones->lock);
|
||||
lock_rw_unlock(&zones->lock);
|
||||
return;
|
||||
}
|
||||
lock_rw_wrlock(&z->lock);
|
||||
lock_quick_unlock(&zones->lock);
|
||||
lock_rw_unlock(&zones->lock);
|
||||
|
||||
/* find the domain */
|
||||
d = lz_find_node(z, name, len, labs);
|
||||
|
|
|
|||
|
|
@ -78,7 +78,7 @@ enum localzone_type {
|
|||
*/
|
||||
struct local_zones {
|
||||
/** lock on the localzone tree */
|
||||
lock_quick_t lock;
|
||||
lock_rw_t lock;
|
||||
/** rbtree of struct local_zone */
|
||||
rbtree_t ztree;
|
||||
};
|
||||
|
|
|
|||
Loading…
Reference in a new issue