Instead of maintaining own set of resolver tasks use caller's task

Previously, the resolver has maintained many tasks that were randomly
used for resolution process.  After the last refactoring, this was
reduced to per-thread task.  Since the caller always needs to pass
the task for calling the callback, the resolver already have access
to the task object that's evenly distributed among the threads (via
ns_clientmgr), so change the logic to stop using the internal threads,
and use the task that has been passed when creating new fetch context.
This commit is contained in:
Ondřej Surý
2022-05-25 09:22:09 +02:00
parent ffb8f611d6
commit a6909a13c7
7 changed files with 57 additions and 107 deletions
+14 -28
View File
@@ -106,7 +106,6 @@ struct dns_adb {
dns_resolver_t *res;
isc_taskmgr_t *taskmgr;
isc_task_t *task;
isc_refcount_t references;
@@ -338,10 +337,10 @@ maybe_expire_namehooks(dns_adbname_t *, isc_stdtime_t);
static void
maybe_expire_entry(dns_adbentry_t **, isc_stdtime_t);
static isc_result_t
dbfind_name(dns_adbname_t *, isc_stdtime_t, dns_rdatatype_t);
dbfind_name(dns_adbname_t *, isc_task_t *task, isc_stdtime_t, dns_rdatatype_t);
static isc_result_t
fetch_name(dns_adbname_t *, bool, unsigned int, isc_counter_t *qc,
dns_rdatatype_t);
fetch_name(isc_task_t *task, dns_adbname_t *, bool, unsigned int,
isc_counter_t *qc, dns_rdatatype_t);
static void
destroy(dns_adb_t *);
static void
@@ -2079,7 +2078,6 @@ destroy(dns_adb_t *adb) {
isc_mutex_destroy(&adb->lock);
isc_task_detach(&adb->task);
isc_stats_detach(&adb->stats);
dns_resolver_detach(&adb->res);
dns_view_weakdetach(&adb->view);
@@ -2123,19 +2121,9 @@ dns_adb_create(isc_mem_t *mem, dns_view_t *view, isc_taskmgr_t *taskmgr,
isc_mutex_init(&adb->lock);
/*
* Allocate an internal task.
*/
result = isc_task_create(adb->taskmgr, 0, &adb->task, 0);
if (result != ISC_R_SUCCESS) {
goto free_lock;
}
isc_task_setname(adb->task, "ADB", adb);
result = isc_stats_create(adb->mctx, &adb->stats, dns_adbstats_max);
if (result != ISC_R_SUCCESS) {
goto free_task;
goto free_lock;
}
set_adbstat(adb, isc_ht_count(adb->namebuckets), dns_adbstats_nnames);
@@ -2149,9 +2137,6 @@ dns_adb_create(isc_mem_t *mem, dns_view_t *view, isc_taskmgr_t *taskmgr,
*newadb = adb;
return (ISC_R_SUCCESS);
free_task:
isc_task_detach(&adb->task);
free_lock:
isc_mutex_destroy(&adb->lock);
@@ -2367,7 +2352,7 @@ dns_adb_createfind(dns_adb_t *adb, isc_task_t *task, isc_taskaction_t action,
if (!NAME_HAS_V4(adbname) && EXPIRE_OK(adbname->expire_v4, now) &&
WANT_INET(wanted_addresses))
{
result = dbfind_name(adbname, now, dns_rdatatype_a);
result = dbfind_name(adbname, task, now, dns_rdatatype_a);
switch (result) {
case ISC_R_SUCCESS:
/* Found an A; now we proceed to check for AAAA */
@@ -2419,7 +2404,7 @@ dns_adb_createfind(dns_adb_t *adb, isc_task_t *task, isc_taskaction_t action,
if (!NAME_HAS_V6(adbname) && EXPIRE_OK(adbname->expire_v6, now) &&
WANT_INET6(wanted_addresses))
{
result = dbfind_name(adbname, now, dns_rdatatype_aaaa);
result = dbfind_name(adbname, task, now, dns_rdatatype_aaaa);
switch (result) {
case ISC_R_SUCCESS:
DP(DEF_LEVEL,
@@ -2482,7 +2467,7 @@ fetch:
* Start V4.
*/
if (WANT_INET(wanted_fetches) &&
fetch_name(adbname, start_at_zone, depth, qc,
fetch_name(task, adbname, start_at_zone, depth, qc,
dns_rdatatype_a) == ISC_R_SUCCESS)
{
DP(DEF_LEVEL,
@@ -2495,7 +2480,7 @@ fetch:
* Start V6.
*/
if (WANT_INET6(wanted_fetches) &&
fetch_name(adbname, start_at_zone, depth, qc,
fetch_name(task, adbname, start_at_zone, depth, qc,
dns_rdatatype_aaaa) == ISC_R_SUCCESS)
{
DP(DEF_LEVEL,
@@ -2968,7 +2953,8 @@ print_find_list(FILE *f, dns_adbname_t *name) {
}
static isc_result_t
dbfind_name(dns_adbname_t *adbname, isc_stdtime_t now, dns_rdatatype_t rdtype) {
dbfind_name(dns_adbname_t *adbname, isc_task_t *task, isc_stdtime_t now,
dns_rdatatype_t rdtype) {
isc_result_t result;
dns_rdataset_t rdataset;
dns_adb_t *adb = NULL;
@@ -2999,7 +2985,7 @@ dbfind_name(dns_adbname_t *adbname, isc_stdtime_t now, dns_rdatatype_t rdtype) {
* matching static-stub zone without looking into the cache to honor
* the configuration on which server we should send queries to.
*/
result = dns_view_find(adb->view, &adbname->name, rdtype, now,
result = dns_view_find(adb->view, task, &adbname->name, rdtype, now,
NAME_GLUEOK(adbname) ? DNS_DBFIND_GLUEOK : 0,
NAME_HINTOK(adbname),
((adbname->flags & NAME_STARTATZONE) != 0), NULL,
@@ -3297,8 +3283,8 @@ out:
}
static isc_result_t
fetch_name(dns_adbname_t *adbname, bool start_at_zone, unsigned int depth,
isc_counter_t *qc, dns_rdatatype_t type) {
fetch_name(isc_task_t *task, dns_adbname_t *adbname, bool start_at_zone,
unsigned int depth, isc_counter_t *qc, dns_rdatatype_t type) {
isc_result_t result;
dns_adbfetch_t *fetch = NULL;
dns_adb_t *adb = NULL;
@@ -3348,7 +3334,7 @@ fetch_name(dns_adbname_t *adbname, bool start_at_zone, unsigned int depth,
*/
result = dns_resolver_createfetch(
adb->res, &adbname->name, type, name, nameservers, NULL, NULL,
0, options, depth, qc, adb->task, fetch_callback, adbname,
0, options, depth, qc, task, fetch_callback, adbname,
&fetch->rdataset, NULL, &fetch->fetch);
if (result != ISC_R_SUCCESS) {
DP(ENTER_LEVEL, "fetch_name: createfetch failed with %s",
+2 -2
View File
@@ -564,8 +564,8 @@ view_find(resctx_t *rctx, dns_db_t **dbp, dns_dbnode_t **nodep,
type = rctx->type;
}
result = dns_view_find(rctx->view, name, type, 0, 0, false, false, dbp,
nodep, foundname, rctx->rdataset,
result = dns_view_find(rctx->view, rctx->task, name, type, 0, 0, false,
false, dbp, nodep, foundname, rctx->rdataset,
rctx->sigrdataset);
return (result);
+1 -1
View File
@@ -225,7 +225,7 @@ dns_resolver_freeze(dns_resolver_t *res);
*/
void
dns_resolver_prime(dns_resolver_t *res);
dns_resolver_prime(dns_resolver_t *res, isc_task_t *task);
/*%<
* Prime resolver.
*
+5 -5
View File
@@ -542,11 +542,11 @@ dns_view_thaw(dns_view_t *view);
*/
isc_result_t
dns_view_find(dns_view_t *view, const dns_name_t *name, dns_rdatatype_t type,
isc_stdtime_t now, unsigned int options, bool use_hints,
bool use_static_stub, dns_db_t **dbp, dns_dbnode_t **nodep,
dns_name_t *foundname, dns_rdataset_t *rdataset,
dns_rdataset_t *sigrdataset);
dns_view_find(dns_view_t *view, isc_task_t *task, const dns_name_t *name,
dns_rdatatype_t type, isc_stdtime_t now, unsigned int options,
bool use_hints, bool use_static_stub, dns_db_t **dbp,
dns_dbnode_t **nodep, dns_name_t *foundname,
dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset);
/*%<
* Find an rdataset whose owner name is 'name', and whose type is
* 'type'.
+22 -59
View File
@@ -331,8 +331,7 @@ struct fetchctx {
isc_mem_t *mctx;
isc_stdtime_t now;
isc_task_t *restask;
unsigned int tid;
isc_task_t *task;
/* Atomic */
isc_refcount_t references;
@@ -543,7 +542,6 @@ struct dns_resolver {
isc_ht_t *zonebuckets;
isc_rwlock_t zonehash_lock;
unsigned int ntasks;
isc_task_t **tasks;
uint32_t lame_ttl;
ISC_LIST(alternate_t) alternates;
uint16_t udpsize;
@@ -3367,10 +3365,10 @@ findname(fetchctx_t *fctx, const dns_name_t *name, in_port_t port,
* See what we know about this address.
*/
fctx_addref(fctx);
result = dns_adb_createfind(fctx->adb, fctx->restask, fctx_finddone,
fctx, name, fctx->name, fctx->type, options,
now, NULL, res->view->dstport,
fctx->depth + 1, fctx->qc, &find);
result = dns_adb_createfind(fctx->adb, fctx->task, fctx_finddone, fctx,
name, fctx->name, fctx->type, options, now,
NULL, res->view->dstport, fctx->depth + 1,
fctx->qc, &find);
isc_log_write(dns_lctx, DNS_LOGCATEGORY_RESOLVER,
DNS_LOGMODULE_RESOLVER, ISC_LOG_DEBUG(3),
@@ -4174,8 +4172,8 @@ fctx_try(fetchctx_t *fctx, bool retrying, bool badcache) {
result = dns_resolver_createfetch(
fctx->res, fctx->qminname, fctx->qmintype, fctx->domain,
&fctx->nameservers, NULL, NULL, 0, options, 0, fctx->qc,
fctx->restask, resume_qmin, fctx, &fctx->qminrrset,
NULL, &fctx->qminfetch);
fctx->task, resume_qmin, fctx, &fctx->qminrrset, NULL,
&fctx->qminfetch);
if (result != ISC_R_SUCCESS) {
fctx_unref(fctx);
fctx_done_detach(&fctx, DNS_R_SERVFAIL);
@@ -4403,6 +4401,7 @@ fctx_destroy(fetchctx_t *fctx) {
isc_timer_destroy(&fctx->timer);
isc_task_detach(&fctx->task);
dns_resolver_detach(&fctx->res);
isc_mem_free(fctx->mctx, fctx->info);
@@ -4435,7 +4434,7 @@ fctx_shutdown(fetchctx_t *fctx) {
if (fctx->state != fetchstate_init) {
FCTXTRACE("posting control event");
cevent = &fctx->control_event;
isc_task_send(fctx->restask, &cevent);
isc_task_send(fctx->task, &cevent);
}
}
@@ -4661,7 +4660,7 @@ fctx_create(dns_resolver_t *res, const dns_name_t *name, dns_rdatatype_t type,
const dns_name_t *domain, dns_rdataset_t *nameservers,
const isc_sockaddr_t *client, unsigned int options,
fctxbucket_t *bucket, unsigned int depth, isc_counter_t *qc,
fetchctx_t **fctxp) {
isc_task_t *task, fetchctx_t **fctxp) {
fetchctx_t *fctx = NULL;
isc_result_t result;
isc_result_t iresult;
@@ -4669,11 +4668,6 @@ fctx_create(dns_resolver_t *res, const dns_name_t *name, dns_rdatatype_t type,
unsigned int findoptions = 0;
char buf[DNS_NAME_FORMATSIZE + DNS_RDATATYPE_FORMATSIZE + 1];
size_t p;
int tid = isc_nm_tid();
if (tid == ISC_NETMGR_TID_UNKNOWN) {
tid = 0;
}
/*
* Caller must be holding the lock for 'bucket'
@@ -4686,8 +4680,6 @@ fctx_create(dns_resolver_t *res, const dns_name_t *name, dns_rdatatype_t type,
.qmintype = type,
.options = options,
.bucket = bucket,
.tid = tid,
.restask = res->tasks[tid],
.state = fetchstate_init,
.depth = depth,
.qmin_labels = 1,
@@ -4697,6 +4689,7 @@ fctx_create(dns_resolver_t *res, const dns_name_t *name, dns_rdatatype_t type,
};
dns_resolver_attach(res, &fctx->res);
isc_task_attach(task, &fctx->task);
if (qc != NULL) {
isc_counter_attach(qc, &fctx->qc);
@@ -4875,7 +4868,7 @@ fctx_create(dns_resolver_t *res, const dns_name_t *name, dns_rdatatype_t type,
* lifetime. It will be made active when the fetch is
* started.
*/
isc_timer_create(res->timermgr, fctx->restask, fctx_expired, fctx,
isc_timer_create(res->timermgr, fctx->task, fctx_expired, fctx,
&fctx->timer);
/*
@@ -4965,6 +4958,7 @@ cleanup_nameservers:
isc_counter_detach(&fctx->qc);
cleanup_fetch:
isc_task_detach(&fctx->task);
dns_resolver_detach(&fctx->res);
isc_mem_put(res->mctx, fctx, sizeof(*fctx));
@@ -6335,7 +6329,7 @@ cache_name(fetchctx_t *fctx, dns_name_t *name, dns_message_t *message,
fctx, message, addrinfo, name,
rdataset->type, rdataset,
sigrdataset, valoptions,
fctx->restask);
fctx->task);
}
} else if (CHAINING(rdataset)) {
if (rdataset->type == dns_rdatatype_cname) {
@@ -6442,7 +6436,7 @@ cache_name(fetchctx_t *fctx, dns_name_t *name, dns_message_t *message,
result = valcreate(fctx, message, addrinfo, name, vtype,
valrdataset, valsigrdataset, valoptions,
fctx->restask);
fctx->task);
}
if (result == ISC_R_SUCCESS && have_answer) {
@@ -6662,7 +6656,7 @@ ncache_message(fetchctx_t *fctx, dns_message_t *message,
* Do negative response validation.
*/
result = valcreate(fctx, message, addrinfo, name, fctx->type,
NULL, NULL, valoptions, fctx->restask);
NULL, NULL, valoptions, fctx->task);
/*
* If validation is necessary, return now. Otherwise
* continue to process the message, letting the
@@ -9700,7 +9694,7 @@ rctx_chaseds(respctx_t *rctx, dns_message_t *message,
fctx_addref(fctx);
result = dns_resolver_createfetch(
fctx->res, fctx->nsname, dns_rdatatype_ns, NULL, NULL, NULL,
NULL, 0, fctx->options, 0, NULL, fctx->restask, resume_dslookup,
NULL, 0, fctx->options, 0, NULL, fctx->task, resume_dslookup,
fctx, &fctx->nsrrset, NULL, &fctx->nsfetch);
if (result != ISC_R_SUCCESS) {
if (result == DNS_R_DUPLICATE) {
@@ -10076,11 +10070,6 @@ destroy(dns_resolver_t *res) {
isc_mutex_destroy(&res->primelock);
isc_mutex_destroy(&res->lock);
for (size_t i = 0; i < res->ntasks; i++) {
isc_task_detach(&res->tasks[i]);
}
isc_mem_put(res->mctx, res->tasks, res->ntasks * sizeof(res->tasks[0]));
isc_ht_iter_create(res->buckets, &it);
for (result = isc_ht_iter_first(it); result == ISC_R_SUCCESS;
result = isc_ht_iter_delcurrent_next(it))
@@ -10173,7 +10162,6 @@ dns_resolver_create(dns_view_t *view, isc_taskmgr_t *taskmgr,
dns_dispatch_t *dispatchv4, dns_dispatch_t *dispatchv6,
dns_resolver_t **resp) {
isc_result_t result = ISC_R_SUCCESS;
char name[sizeof("res4294967295")];
dns_resolver_t *res = NULL;
isc_task_t *task = NULL;
@@ -10222,23 +10210,6 @@ dns_resolver_create(dns_view_t *view, isc_taskmgr_t *taskmgr,
goto cleanup_res;
}
res->tasks = isc_mem_get(view->mctx,
res->ntasks * sizeof(res->tasks[0]));
memset(res->tasks, 0, res->ntasks * sizeof(res->tasks[0]));
for (uint32_t i = 0; i < res->ntasks; i++) {
/*
* Since we have a pool of tasks we bind them to task
* queues to spread the load evenly
*/
result = isc_task_create(taskmgr, 0, &res->tasks[i], i);
if (result != ISC_R_SUCCESS) {
goto cleanup_tasks;
}
snprintf(name, sizeof(name), "res%" PRIu32, i);
isc_task_setname(res->tasks[i], name, res);
}
isc_ht_init(&res->buckets, view->mctx, RES_DOMAIN_HASH_BITS,
ISC_HT_CASE_INSENSITIVE);
isc_rwlock_init(&res->hash_lock, 0, 0);
@@ -10293,15 +10264,6 @@ cleanup_primelock:
isc_rwlock_destroy(&res->hash_lock);
isc_ht_destroy(&res->buckets);
cleanup_tasks:
for (size_t i = 0; i < res->ntasks; i++) {
if (res->tasks[i] != NULL) {
isc_task_detach(&res->tasks[i]);
}
}
isc_mem_put(view->mctx, res->tasks,
res->ntasks * sizeof(res->tasks[0]));
dns_badcache_destroy(&res->badcache);
cleanup_res:
@@ -10363,7 +10325,7 @@ prime_done(isc_task_t *task, isc_event_t *event) {
}
void
dns_resolver_prime(dns_resolver_t *res) {
dns_resolver_prime(dns_resolver_t *res, isc_task_t *task) {
bool want_priming = false;
dns_rdataset_t *rdataset;
isc_result_t result;
@@ -10396,7 +10358,7 @@ dns_resolver_prime(dns_resolver_t *res) {
INSIST(res->primefetch == NULL);
result = dns_resolver_createfetch(
res, dns_rootname, dns_rdatatype_ns, NULL, NULL, NULL,
NULL, 0, DNS_FETCHOPT_NOFORWARD, 0, NULL, res->tasks[0],
NULL, 0, DNS_FETCHOPT_NOFORWARD, 0, NULL, task,
prime_done, res, rdataset, NULL, &res->primefetch);
UNLOCK(&res->primelock);
@@ -10754,7 +10716,8 @@ dns_resolver_createfetch(dns_resolver_t *res, const dns_name_t *name,
if (fctx == NULL) {
result = fctx_create(res, name, type, domain, nameservers,
client, options, bucket, depth, qc, &fctx);
client, options, bucket, depth, qc, task,
&fctx);
if (result != ISC_R_SUCCESS) {
goto unlock;
}
@@ -10783,7 +10746,7 @@ dns_resolver_createfetch(dns_resolver_t *res, const dns_name_t *name,
ISC_EVENT_INIT(event, sizeof(*event), 0, NULL,
DNS_EVENT_FETCHCONTROL, fctx_start, fctx,
NULL, NULL, NULL);
isc_task_send(fctx->restask, &event);
isc_task_send(fctx->task, &event);
} else {
dodestroy = true;
}
+3 -3
View File
@@ -974,9 +974,9 @@ view_find(dns_validator_t *val, dns_name_t *name, dns_rdatatype_t type) {
options = DNS_DBFIND_PENDINGOK;
foundname = dns_fixedname_initname(&fixedname);
result = dns_view_find(val->view, name, type, 0, options, false, false,
NULL, NULL, foundname, &val->frdataset,
&val->fsigrdataset);
result = dns_view_find(val->view, val->task, name, type, 0, options,
false, false, NULL, NULL, foundname,
&val->frdataset, &val->fsigrdataset);
if (result == DNS_R_NXDOMAIN) {
goto notfound;
+10 -9
View File
@@ -826,11 +826,11 @@ dns_view_findzone(dns_view_t *view, const dns_name_t *name,
}
isc_result_t
dns_view_find(dns_view_t *view, const dns_name_t *name, dns_rdatatype_t type,
isc_stdtime_t now, unsigned int options, bool use_hints,
bool use_static_stub, dns_db_t **dbp, dns_dbnode_t **nodep,
dns_name_t *foundname, dns_rdataset_t *rdataset,
dns_rdataset_t *sigrdataset) {
dns_view_find(dns_view_t *view, isc_task_t *task, const dns_name_t *name,
dns_rdatatype_t type, isc_stdtime_t now, unsigned int options,
bool use_hints, bool use_static_stub, dns_db_t **dbp,
dns_dbnode_t **nodep, dns_name_t *foundname,
dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset) {
isc_result_t result;
dns_db_t *db, *zdb;
dns_dbnode_t *node, *znode;
@@ -1003,7 +1003,7 @@ db_find:
* We just used a hint. Let the resolver know it
* should consider priming.
*/
dns_resolver_prime(view->resolver);
dns_resolver_prime(view->resolver, task);
dns_db_attach(view->hints, &db);
result = DNS_R_HINT;
} else if (result == DNS_R_NXRRSET) {
@@ -1069,9 +1069,10 @@ dns_view_simplefind(dns_view_t *view, const dns_name_t *name,
dns_fixedname_t foundname;
dns_fixedname_init(&foundname);
result = dns_view_find(view, name, type, now, options, use_hints, false,
NULL, NULL, dns_fixedname_name(&foundname),
rdataset, sigrdataset);
result = dns_view_find(view, view->task, name, type, now, options,
use_hints, false, NULL, NULL,
dns_fixedname_name(&foundname), rdataset,
sigrdataset);
if (result == DNS_R_NXDOMAIN) {
/*
* The rdataset and sigrdataset of the relevant NSEC record