]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Make dns_dispatch bound to threads
authorOndřej Surý <ondrej@isc.org>
Fri, 15 Sep 2023 09:36:28 +0000 (11:36 +0200)
committerOndřej Surý <ondrej@isc.org>
Sat, 16 Sep 2023 05:32:17 +0000 (07:32 +0200)
Instead of high number of dispatches (4 * named_g_udpdisp)[1], make the
dispatches bound to threads and make dns_dispatchset_t create a dispatch
for each thread (event loop).

This required couple of other changes:

1. The dns_dispatch_createudp() must be called on loop, so the isc_tid()
   is already initialized - changes to nsupdate and mdig were required.

2. The dns_requestmgr had only a single dispatch per v4 and v6.  Instead
   of using single dispatch, use dns_dispatchset_t for each protocol -
   this is same as dns_resolver.

19 files changed:
bin/delv/delv.c
bin/named/include/named/globals.h
bin/named/main.c
bin/named/server.c
bin/nsupdate/nsupdate.c
bin/tools/mdig.c
lib/dns/client.c
lib/dns/dispatch.c
lib/dns/include/dns/dispatch.h
lib/dns/include/dns/resolver.h
lib/dns/include/dns/view.h
lib/dns/request.c
lib/dns/resolver.c
lib/dns/view.c
lib/isc/include/isc/tid.h
lib/isc/tid.c
lib/ns/include/ns/interfacemgr.h
tests/dns/dispatch_test.c
tests/dns/resolver_test.c

index d8f71d7e248f402aefd2de1a6b54e77811dd8df2..26adc81266d7ae067beaeb4b3d54d86253a16913 100644 (file)
@@ -2165,7 +2165,7 @@ run_server(void *arg) {
        dns_view_initsecroots(view);
        CHECK(setup_dnsseckeys(NULL, view));
 
-       CHECK(dns_view_createresolver(view, loopmgr, 1, netmgr, 0,
+       CHECK(dns_view_createresolver(view, loopmgr, netmgr, 0,
                                      tlsctx_client_cache, dispatch, NULL));
 
        isc_stats_create(mctx, &resstats, dns_resstatscounter_max);
index 03e35f2cd4b9e075ac0cb082ac673cee62e523e8..1f6edbc09eede33d733f047d898249ac2046c4ef 100644 (file)
@@ -50,7 +50,6 @@
 
 EXTERN isc_mem_t *named_g_mctx               INIT(NULL);
 EXTERN unsigned int named_g_cpus             INIT(0);
-EXTERN unsigned int named_g_udpdisp          INIT(0);
 EXTERN isc_loop_t *named_g_mainloop          INIT(NULL);
 EXTERN isc_loopmgr_t *named_g_loopmgr        INIT(NULL);
 EXTERN bool named_g_loopmgr_running          INIT(false);
index 0e427a8b0e4e51b7f0a4393cf9c45ca61319a845..521536caa1166b652257c0bce04873f59896d807 100644 (file)
@@ -949,9 +949,7 @@ parse_command_line(int argc, char *argv[]) {
                        parse_T_opt(isc_commandline_argument);
                        break;
                case 'U':
-                       named_g_udpdisp = parse_int(isc_commandline_argument,
-                                                   "number of UDP listeners "
-                                                   "per interface");
+                       /* Obsolete.  No longer in use.  Ignore. */
                        break;
                case 'u':
                        named_g_username = isc_commandline_argument;
@@ -1044,16 +1042,6 @@ create_managers(void) {
                ISC_LOG_INFO, "found %u CPU%s, using %u worker thread%s",
                named_g_cpus_detected, named_g_cpus_detected == 1 ? "" : "s",
                named_g_cpus, named_g_cpus == 1 ? "" : "s");
-       if (named_g_udpdisp == 0) {
-               named_g_udpdisp = named_g_cpus_detected;
-       }
-       if (named_g_udpdisp > named_g_cpus) {
-               named_g_udpdisp = named_g_cpus;
-       }
-       isc_log_write(named_g_lctx, NAMED_LOGCATEGORY_GENERAL,
-                     NAMED_LOGMODULE_SERVER, ISC_LOG_INFO,
-                     "using %u UDP listener%s per interface", named_g_udpdisp,
-                     named_g_udpdisp == 1 ? "" : "s");
 
        isc_managers_create(&named_g_mctx, named_g_cpus, &named_g_loopmgr,
                            &named_g_netmgr);
index 714c1b10b3f2dc162d8e5dce3c4c3b712fc629d6..bd3ca9bb0e88c96c94c529afdbddf1358e98cf17 100644 (file)
@@ -4033,7 +4033,7 @@ configure_view(dns_view_t *view, dns_viewlist_t *viewlist, cfg_obj_t *config,
        named_cache_t *nsc;
        bool zero_no_soattl;
        dns_acl_t *clients = NULL, *mapped = NULL, *excluded = NULL;
-       unsigned int query_timeout, ndisp;
+       unsigned int query_timeout;
        bool old_rpz_ok = false;
        dns_dyndbctx_t *dctx = NULL;
        unsigned int resolver_param;
@@ -4685,9 +4685,8 @@ configure_view(dns_view_t *view, dns_viewlist_t *viewlist, cfg_obj_t *config,
                goto cleanup;
        }
 
-       ndisp = 4 * ISC_MIN(named_g_udpdisp, MAX_UDP_DISPATCH);
        CHECK(dns_view_createresolver(
-               view, named_g_loopmgr, ndisp, named_g_netmgr, resopts,
+               view, named_g_loopmgr, named_g_netmgr, resopts,
                named_g_server->tlsctx_client_cache, dispatch4, dispatch6));
 
        if (resstats == NULL) {
@@ -12148,10 +12147,6 @@ named_server_status(named_server_t *server, isc_buffer_t **text) {
        snprintf(line, sizeof(line), "worker threads: %u\n", named_g_cpus);
        CHECK(putstr(text, line));
 
-       snprintf(line, sizeof(line), "UDP listeners per interface: %u\n",
-                named_g_udpdisp);
-       CHECK(putstr(text, line));
-
        snprintf(line, sizeof(line), "number of zones: %u (%u automatic)\n",
                 zonecount, automatic);
        CHECK(putstr(text, line));
index 3e673f493da4e86f07e3546724e24d1e427025e8..5746933935708da53dfee16b6d9c0b127e193796 100644 (file)
@@ -798,7 +798,7 @@ create_name(const char *str, char *namedata, size_t len, dns_name_t *name) {
 }
 
 static void
-setup_system(void) {
+setup_system(void *arg ISC_ATTR_UNUSED) {
        isc_result_t result;
        isc_sockaddr_t bind_any, bind_any6;
        isc_sockaddrlist_t *nslist;
@@ -3475,8 +3475,7 @@ main(int argc, char **argv) {
        timeoutms = timeout * 1000;
        isc_nm_settimeouts(netmgr, timeoutms, timeoutms, timeoutms, timeoutms);
 
-       setup_system();
-
+       isc_loopmgr_setup(loopmgr, setup_system, NULL);
        isc_loopmgr_setup(loopmgr, getinput, NULL);
        isc_loopmgr_teardown(loopmgr, shutdown_program, NULL);
        isc_loopmgr_run(loopmgr);
index f88edf49f6f825c6f86af356481649faaf4fde44..6b2facf09b0c8ac0fa6596befa84103b0abed97f 100644 (file)
@@ -116,6 +116,12 @@ static unsigned char cookie_secret[33];
 static int onfly = 0;
 static char hexcookie[81];
 
+static isc_sockaddr_t bind_any;
+static isc_nm_t *netmgr = NULL;
+static dns_dispatchmgr_t *dispatchmgr = NULL;
+static dns_dispatch_t *dispatchvx = NULL;
+static dns_view_t *view = NULL;
+
 struct query {
        char textname[MXNAME]; /*% Name we're going to be
                                * looking up */
@@ -2069,29 +2075,33 @@ set_source_ports(dns_dispatchmgr_t *manager) {
 }
 
 static void
-teardown_view(void *arg) {
-       dns_view_t *view = arg;
+teardown(void *arg ISC_ATTR_UNUSED) {
        dns_view_detach(&view);
+       dns_requestmgr_shutdown(requestmgr);
+       dns_requestmgr_detach(&requestmgr);
+       dns_dispatch_detach(&dispatchvx);
+       dns_dispatchmgr_detach(&dispatchmgr);
 }
 
 static void
-teardown_requestmgr(void *arg) {
-       dns_requestmgr_t *mgr = arg;
+setup(void *arg ISC_ATTR_UNUSED) {
+       RUNCHECK(dns_dispatchmgr_create(mctx, netmgr, &dispatchmgr));
 
-       dns_requestmgr_shutdown(mgr);
-       dns_requestmgr_detach(&mgr);
-}
+       set_source_ports(dispatchmgr);
 
-static void
-teardown_dispatch(void *arg) {
-       dns_dispatch_t *dispatchv4 = arg;
-       dns_dispatch_detach(&dispatchv4);
-}
+       if (have_ipv4) {
+               isc_sockaddr_any(&bind_any);
+       } else {
+               isc_sockaddr_any6(&bind_any);
+       }
+       RUNCHECK(dns_dispatch_createudp(
+               dispatchmgr, have_src ? &srcaddr : &bind_any, &dispatchvx));
 
-static void
-teardown_dispatchmgr(void *arg) {
-       dns_dispatchmgr_t *dispatchmgr = arg;
-       dns_dispatchmgr_detach(&dispatchmgr);
+       RUNCHECK(dns_requestmgr_create(
+               mctx, loopmgr, dispatchmgr, have_ipv4 ? dispatchvx : NULL,
+               have_ipv6 ? dispatchvx : NULL, &requestmgr));
+
+       RUNCHECK(dns_view_create(mctx, NULL, 0, "_mdig", &view));
 }
 
 /*% Main processing routine for mdig */
@@ -2099,13 +2109,8 @@ int
 main(int argc, char *argv[]) {
        struct query *query = NULL;
        isc_result_t result;
-       isc_sockaddr_t bind_any;
        isc_log_t *lctx = NULL;
        isc_logconfig_t *lcfg = NULL;
-       isc_nm_t *netmgr = NULL;
-       dns_dispatchmgr_t *dispatchmgr = NULL;
-       dns_dispatch_t *dispatchvx = NULL;
-       dns_view_t *view = NULL;
        unsigned int i;
        int ns;
 
@@ -2151,30 +2156,10 @@ main(int argc, char *argv[]) {
                fatal("can't choose between IPv4 and IPv6");
        }
 
-       RUNCHECK(dns_dispatchmgr_create(mctx, netmgr, &dispatchmgr));
-
-       set_source_ports(dispatchmgr);
-
-       if (have_ipv4) {
-               isc_sockaddr_any(&bind_any);
-       } else {
-               isc_sockaddr_any6(&bind_any);
-       }
-       RUNCHECK(dns_dispatch_createudp(
-               dispatchmgr, have_src ? &srcaddr : &bind_any, &dispatchvx));
-
-       RUNCHECK(dns_requestmgr_create(
-               mctx, loopmgr, dispatchmgr, have_ipv4 ? dispatchvx : NULL,
-               have_ipv6 ? dispatchvx : NULL, &requestmgr));
-
-       RUNCHECK(dns_view_create(mctx, NULL, 0, "_mdig", &view));
-
        query = ISC_LIST_HEAD(queries);
+       isc_loopmgr_setup(loopmgr, setup, NULL);
        isc_loopmgr_setup(loopmgr, sendqueries, query);
-       isc_loopmgr_teardown(loopmgr, teardown_view, view);
-       isc_loopmgr_teardown(loopmgr, teardown_requestmgr, requestmgr);
-       isc_loopmgr_teardown(loopmgr, teardown_dispatch, dispatchvx);
-       isc_loopmgr_teardown(loopmgr, teardown_dispatchmgr, dispatchmgr);
+       isc_loopmgr_teardown(loopmgr, teardown, NULL);
 
        /*
         * Stall to the start of a new second.
index 205c9764bc1e5154b0fb1bb434cb4c853383d426..a8100f7ab6fa8e48728154ce15095ff73b6d7fdd 100644 (file)
@@ -215,9 +215,8 @@ createview(isc_mem_t *mctx, dns_rdataclass_t rdclass, isc_loopmgr_t *loopmgr,
        /* Initialize view security roots */
        dns_view_initsecroots(view);
 
-       CHECK(dns_view_createresolver(view, loopmgr, 1, nm, 0,
-                                     tlsctx_client_cache, dispatchv4,
-                                     dispatchv6));
+       CHECK(dns_view_createresolver(view, loopmgr, nm, 0, tlsctx_client_cache,
+                                     dispatchv4, dispatchv6));
        CHECK(dns_db_create(mctx, "rbt", dns_rootname, dns_dbtype_cache,
                            rdclass, 0, NULL, &view->cachedb));
 
index 01562839bf400292df486b21e8264d4f54c9baaa..38b6577ed762b30480b99f0c8bc4ba194648d65e 100644 (file)
@@ -19,7 +19,6 @@
 #include <sys/types.h>
 #include <unistd.h>
 
-#include <isc/atomic.h>
 #include <isc/hash.h>
 #include <isc/hashmap.h>
 #include <isc/loop.h>
@@ -119,8 +118,6 @@ struct dns_dispatch {
        /*% Locked by mgr->lock. */
        ISC_LINK(dns_dispatch_t) link;
 
-       /* Locked by "lock". */
-       isc_mutex_t lock; /*%< locks all below */
        isc_socktype_t socktype;
        dns_dispatchstate_t state;
        isc_refcount_t references;
@@ -130,7 +127,7 @@ struct dns_dispatch {
        dns_displist_t pending;
        dns_displist_t active;
 
-       unsigned int requests; /*%< how many requests we have */
+       uint_fast32_t requests; /*%< how many requests we have */
 
        unsigned int timedout;
 };
@@ -188,7 +185,7 @@ static void
 dispentry_cancel(dns_dispentry_t *resp, isc_result_t result);
 static isc_result_t
 dispatch_createudp(dns_dispatchmgr_t *mgr, const isc_sockaddr_t *localaddr,
-                  dns_dispatch_t **dispp);
+                  uint32_t tid, dns_dispatch_t **dispp);
 static void
 udp_startrecv(isc_nmhandle_t *handle, dns_dispentry_t *resp);
 static void
@@ -417,10 +414,8 @@ dispentry_destroy(dns_dispentry_t *resp) {
         */
        dispentry_cancel(resp, ISC_R_CANCELED);
 
-       LOCK(&disp->lock);
        INSIST(disp->requests > 0);
        disp->requests--;
-       UNLOCK(&disp->lock);
 
        isc_refcount_destroy(&resp->references);
 
@@ -504,7 +499,7 @@ udp_recv(isc_nmhandle_t *handle, isc_result_t eresult, isc_region_t *region,
 
        disp = resp->disp;
 
-       LOCK(&disp->lock);
+       REQUIRE(disp->tid == isc_tid());
        INSIST(resp->reading);
        resp->reading = false;
 
@@ -518,7 +513,7 @@ udp_recv(isc_nmhandle_t *handle, isc_result_t eresult, isc_region_t *region,
                eresult = ISC_R_CANCELED;
        }
 
-       dispentry_log(resp, LVL(90), "read callback:%s, requests %d",
+       dispentry_log(resp, LVL(90), "read callback:%s, requests %" PRIuFAST32,
                      isc_result_totext(eresult), disp->requests);
 
        if (eresult != ISC_R_SUCCESS) {
@@ -617,8 +612,6 @@ next:
        udp_dispatch_getnext(resp, timeout);
 
 done:
-       UNLOCK(&disp->lock);
-
        if (respond) {
                dispentry_log(resp, LVL(90), "UDP read callback on %p: %s",
                              handle, isc_result_totext(eresult));
@@ -781,11 +774,11 @@ tcp_recv(isc_nmhandle_t *handle, isc_result_t result, isc_region_t *region,
 
        REQUIRE(VALID_DISPATCH(disp));
 
-       LOCK(&disp->lock);
+       REQUIRE(disp->tid == isc_tid());
        INSIST(disp->reading);
        disp->reading = false;
 
-       dispatch_log(disp, LVL(90), "TCP read:%s:requests %u",
+       dispatch_log(disp, LVL(90), "TCP read:%s:requests %" PRIuFAST32,
                     isc_result_totext(result), disp->requests);
 
        peer = isc_nmhandle_peeraddr(handle);
@@ -886,7 +879,6 @@ tcp_recv(isc_nmhandle_t *handle, isc_result_t result, isc_region_t *region,
                isc_nmhandle_settimeout(handle, timeout);
        }
 
-       UNLOCK(&disp->lock);
        rcu_read_unlock();
 
        /*
@@ -1082,7 +1074,7 @@ dns_dispatchmgr_setstats(dns_dispatchmgr_t *mgr, isc_stats_t *stats) {
  * Allocate and set important limits.
  */
 static void
-dispatch_allocate(dns_dispatchmgr_t *mgr, isc_socktype_t type,
+dispatch_allocate(dns_dispatchmgr_t *mgr, isc_socktype_t type, uint32_t tid,
                  dns_dispatch_t **dispp) {
        dns_dispatch_t *disp = NULL;
 
@@ -1100,7 +1092,7 @@ dispatch_allocate(dns_dispatchmgr_t *mgr, isc_socktype_t type,
                .link = ISC_LINK_INITIALIZER,
                .active = ISC_LIST_INITIALIZER,
                .pending = ISC_LIST_INITIALIZER,
-               .tid = isc_tid(),
+               .tid = tid,
                .magic = DISPATCH_MAGIC,
        };
 
@@ -1110,7 +1102,6 @@ dispatch_allocate(dns_dispatchmgr_t *mgr, isc_socktype_t type,
                __func__, __FILE__, __LINE__, disp);
 #endif
        isc_refcount_init(&disp->references, 1); /* DISPATCH000 */
-       isc_mutex_init(&disp->lock);
 
        *dispp = disp;
 }
@@ -1125,7 +1116,7 @@ dns_dispatch_createtcp(dns_dispatchmgr_t *mgr, const isc_sockaddr_t *localaddr,
 
        LOCK(&mgr->lock);
 
-       dispatch_allocate(mgr, isc_socktype_tcp, &disp);
+       dispatch_allocate(mgr, isc_socktype_tcp, isc_tid(), &disp);
 
        disp->peer = *destaddr;
 
@@ -1181,13 +1172,12 @@ dns_dispatch_gettcp(dns_dispatchmgr_t *mgr, const isc_sockaddr_t *destaddr,
                isc_sockaddr_t sockname;
                isc_sockaddr_t peeraddr;
 
-               LOCK(&disp->lock);
-
                if (disp->tid != isc_tid()) {
-                       UNLOCK(&disp->lock);
                        continue;
                }
 
+               REQUIRE(disp->tid == isc_tid());
+
                if (disp->handle != NULL) {
                        sockname = isc_nmhandle_localaddr(disp->handle);
                        peeraddr = isc_nmhandle_peeraddr(disp->handle);
@@ -1207,7 +1197,6 @@ dns_dispatch_gettcp(dns_dispatchmgr_t *mgr, const isc_sockaddr_t *destaddr,
                    (localaddr != NULL &&
                     !isc_sockaddr_eqaddr(localaddr, &sockname)))
                {
-                       UNLOCK(&disp->lock);
                        continue;
                }
 
@@ -1240,8 +1229,6 @@ dns_dispatch_gettcp(dns_dispatchmgr_t *mgr, const isc_sockaddr_t *destaddr,
                        UNREACHABLE();
                }
 
-               UNLOCK(&disp->lock);
-
                if (disp_connected != NULL) {
                        break;
                }
@@ -1281,7 +1268,7 @@ dns_dispatch_createudp(dns_dispatchmgr_t *mgr, const isc_sockaddr_t *localaddr,
        REQUIRE(dispp != NULL && *dispp == NULL);
 
        LOCK(&mgr->lock);
-       result = dispatch_createudp(mgr, localaddr, &disp);
+       result = dispatch_createudp(mgr, localaddr, isc_tid(), &disp);
        if (result == ISC_R_SUCCESS) {
                *dispp = disp;
        }
@@ -1292,7 +1279,7 @@ dns_dispatch_createudp(dns_dispatchmgr_t *mgr, const isc_sockaddr_t *localaddr,
 
 static isc_result_t
 dispatch_createudp(dns_dispatchmgr_t *mgr, const isc_sockaddr_t *localaddr,
-                  dns_dispatch_t **dispp) {
+                  uint32_t tid, dns_dispatch_t **dispp) {
        isc_result_t result = ISC_R_SUCCESS;
        dns_dispatch_t *disp = NULL;
        isc_sockaddr_t sa_any;
@@ -1308,7 +1295,7 @@ dispatch_createudp(dns_dispatchmgr_t *mgr, const isc_sockaddr_t *localaddr,
                }
        }
 
-       dispatch_allocate(mgr, isc_socktype_udp, &disp);
+       dispatch_allocate(mgr, isc_socktype_udp, tid, &disp);
 
        if (isc_log_wouldlog(dns_lctx, 90)) {
                char addrbuf[ISC_SOCKADDR_FORMATSIZE];
@@ -1361,8 +1348,6 @@ dispatch_destroy(dns_dispatch_t *disp) {
                isc_nmhandle_detach(&disp->handle);
        }
 
-       isc_mutex_destroy(&disp->lock);
-
        isc_mem_put(mgr->mctx, disp, sizeof(*disp));
 
        /*
@@ -1401,10 +1386,9 @@ dns_dispatch_add(dns_dispatch_t *disp, isc_loop_t *loop, unsigned int options,
        REQUIRE(sent != NULL);
        REQUIRE(loop != NULL);
 
-       LOCK(&disp->lock);
+       REQUIRE(disp->tid == isc_tid());
 
        if (disp->state == DNS_DISPATCHSTATE_CANCELED) {
-               UNLOCK(&disp->lock);
                return (ISC_R_CANCELED);
        }
 
@@ -1436,7 +1420,6 @@ dns_dispatch_add(dns_dispatch_t *disp, isc_loop_t *loop, unsigned int options,
                result = setup_socket(disp, resp, dest, &localport);
                if (result != ISC_R_SUCCESS) {
                        isc_mem_put(disp->mgr->mctx, resp, sizeof(*resp));
-                       UNLOCK(&disp->lock);
                        inc_stats(disp->mgr, dns_resstatscounter_dispsockfail);
                        return (result);
                }
@@ -1496,7 +1479,6 @@ fail:
                                     : dns_resstatscounter_dispreqtcp);
 
        rcu_read_unlock();
-       UNLOCK(&disp->lock);
 
        *idp = resp->id;
        *respp = resp;
@@ -1521,7 +1503,7 @@ dns_dispatch_getnext(dns_dispentry_t *resp) {
                return (ISC_R_TIMEDOUT);
        }
 
-       LOCK(&disp->lock);
+       REQUIRE(disp->tid == isc_tid());
        switch (disp->socktype) {
        case isc_socktype_udp:
                udp_dispatch_getnext(resp, timeout);
@@ -1532,7 +1514,6 @@ dns_dispatch_getnext(dns_dispentry_t *resp) {
        default:
                UNREACHABLE();
        }
-       UNLOCK(&disp->lock);
 
        return (result);
 }
@@ -1549,10 +1530,10 @@ udp_dispentry_cancel(dns_dispentry_t *resp, isc_result_t result) {
        dns_dispatch_t *disp = resp->disp;
        bool respond = false;
 
-       LOCK(&disp->lock);
+       REQUIRE(disp->tid == isc_tid());
        dispentry_log(resp, LVL(90),
                      "canceling response: %s, %s/%s (%s/%s), "
-                     "requests %u",
+                     "requests %" PRIuFAST32,
                      isc_result_totext(result), state2str(resp->state),
                      resp->reading ? "reading" : "not reading",
                      state2str(disp->state),
@@ -1593,8 +1574,6 @@ udp_dispentry_cancel(dns_dispentry_t *resp, isc_result_t result) {
        resp->state = DNS_DISPATCHSTATE_CANCELED;
 
 unlock:
-       UNLOCK(&disp->lock);
-
        if (respond) {
                dispentry_log(resp, LVL(90), "read callback: %s",
                              isc_result_totext(result));
@@ -1614,10 +1593,10 @@ tcp_dispentry_cancel(dns_dispentry_t *resp, isc_result_t result) {
        dns_dispatch_t *disp = resp->disp;
        dns_displist_t resps = ISC_LIST_INITIALIZER;
 
-       LOCK(&disp->lock);
+       REQUIRE(disp->tid == isc_tid());
        dispentry_log(resp, LVL(90),
                      "canceling response: %s, %s/%s (%s/%s), "
-                     "requests %u",
+                     "requests %" PRIuFAST32,
                      isc_result_totext(result), state2str(resp->state),
                      resp->reading ? "reading" : "not reading",
                      state2str(disp->state),
@@ -1692,7 +1671,6 @@ tcp_dispentry_cancel(dns_dispentry_t *resp, isc_result_t result) {
        resp->state = DNS_DISPATCHSTATE_CANCELED;
 
 unlock:
-       UNLOCK(&disp->lock);
 
        /*
         * NOTE: Calling the response callback directly from here should be done
@@ -1797,7 +1775,7 @@ tcp_connected(isc_nmhandle_t *handle, isc_result_t eresult, void *arg) {
                             localbuf, peerbuf, isc_result_totext(eresult));
        }
 
-       LOCK(&disp->lock);
+       REQUIRE(disp->tid == isc_tid());
        INSIST(disp->state == DNS_DISPATCHSTATE_CONNECTING);
 
        /*
@@ -1833,8 +1811,6 @@ tcp_connected(isc_nmhandle_t *handle, isc_result_t eresult, void *arg) {
                disp->state = DNS_DISPATCHSTATE_NONE;
        }
 
-       UNLOCK(&disp->lock);
-
        for (resp = ISC_LIST_HEAD(resps); resp != NULL; resp = next) {
                next = ISC_LIST_NEXT(resp, rlink);
                ISC_LIST_UNLINK(resps, resp, rlink);
@@ -1856,8 +1832,7 @@ udp_connected(isc_nmhandle_t *handle, isc_result_t eresult, void *arg) {
        dispentry_log(resp, LVL(90), "connected: %s",
                      isc_result_totext(eresult));
 
-       LOCK(&disp->lock);
-
+       REQUIRE(disp->tid == isc_tid());
        switch (resp->state) {
        case DNS_DISPATCHSTATE_CANCELED:
                eresult = ISC_R_CANCELED;
@@ -1885,7 +1860,6 @@ udp_connected(isc_nmhandle_t *handle, isc_result_t eresult, void *arg) {
                /* probably a port collision; try a different one */
                result = setup_socket(disp, resp, &resp->peer, &localport);
                if (result == ISC_R_SUCCESS) {
-                       UNLOCK(&disp->lock);
                        udp_dispatch_connect(disp, resp);
                        goto detach;
                }
@@ -1897,7 +1871,6 @@ udp_connected(isc_nmhandle_t *handle, isc_result_t eresult, void *arg) {
                break;
        }
 unlock:
-       UNLOCK(&disp->lock);
 
        dispentry_log(resp, LVL(90), "connect callback: %s",
                      isc_result_totext(eresult));
@@ -1909,12 +1882,11 @@ detach:
 
 static void
 udp_dispatch_connect(dns_dispatch_t *disp, dns_dispentry_t *resp) {
-       LOCK(&disp->lock);
+       REQUIRE(disp->tid == isc_tid());
        resp->state = DNS_DISPATCHSTATE_CONNECTING;
        resp->start = isc_loop_now(resp->loop);
        dns_dispentry_ref(resp); /* DISPENTRY004 */
        ISC_LIST_APPEND(disp->pending, resp, plink);
-       UNLOCK(&disp->lock);
 
        isc_nm_udpconnect(disp->mgr->nm, &resp->local, &resp->peer,
                          udp_connected, resp, resp->timeout);
@@ -1944,7 +1916,7 @@ tcp_dispatch_connect(dns_dispatch_t *disp, dns_dispentry_t *resp) {
        }
 
        /* Check whether the dispatch is already connecting or connected. */
-       LOCK(&disp->lock);
+       REQUIRE(disp->tid == isc_tid());
        switch (disp->state) {
        case DNS_DISPATCHSTATE_NONE:
                /* First connection, continue with connecting */
@@ -1953,7 +1925,6 @@ tcp_dispatch_connect(dns_dispatch_t *disp, dns_dispentry_t *resp) {
                resp->start = isc_loop_now(resp->loop);
                dns_dispentry_ref(resp); /* DISPENTRY005 */
                ISC_LIST_APPEND(disp->pending, resp, plink);
-               UNLOCK(&disp->lock);
 
                char localbuf[ISC_SOCKADDR_FORMATSIZE];
                char peerbuf[ISC_SOCKADDR_FORMATSIZE];
@@ -1979,7 +1950,6 @@ tcp_dispatch_connect(dns_dispatch_t *disp, dns_dispentry_t *resp) {
                resp->start = isc_loop_now(resp->loop);
                dns_dispentry_ref(resp); /* DISPENTRY005 */
                ISC_LIST_APPEND(disp->pending, resp, plink);
-               UNLOCK(&disp->lock);
                break;
 
        case DNS_DISPATCHSTATE_CONNECTED:
@@ -1996,7 +1966,6 @@ tcp_dispatch_connect(dns_dispatch_t *disp, dns_dispentry_t *resp) {
                        tcp_startrecv(disp, resp);
                }
 
-               UNLOCK(&disp->lock);
                /* We are already connected; call the connected cb */
                dispentry_log(resp, LVL(90), "connect callback: %s",
                              isc_result_totext(ISC_R_SUCCESS));
@@ -2105,7 +2074,7 @@ dns_dispatch_resume(dns_dispentry_t *resp, uint16_t timeout) {
 
        dispentry_log(resp, LVL(90), "resume");
 
-       LOCK(&disp->lock);
+       REQUIRE(disp->tid == isc_tid());
        switch (disp->socktype) {
        case isc_socktype_udp: {
                udp_dispatch_getnext(resp, timeout);
@@ -2119,8 +2088,6 @@ dns_dispatch_resume(dns_dispentry_t *resp, uint16_t timeout) {
        default:
                UNREACHABLE();
        }
-
-       UNLOCK(&disp->lock);
 }
 
 void
@@ -2180,31 +2147,25 @@ dns_dispentry_getlocaladdress(dns_dispentry_t *resp, isc_sockaddr_t *addrp) {
 
 dns_dispatch_t *
 dns_dispatchset_get(dns_dispatchset_t *dset) {
-       dns_dispatch_t *disp = NULL;
+       uint32_t tid = isc_tid();
 
        /* check that dispatch set is configured */
        if (dset == NULL || dset->ndisp == 0) {
                return (NULL);
        }
 
-       LOCK(&dset->lock);
-       disp = dset->dispatches[dset->cur];
-       dset->cur++;
-       if (dset->cur == dset->ndisp) {
-               dset->cur = 0;
-       }
-       UNLOCK(&dset->lock);
+       INSIST(tid < dset->ndisp);
 
-       return (disp);
+       return (dset->dispatches[tid]);
 }
 
 isc_result_t
 dns_dispatchset_create(isc_mem_t *mctx, dns_dispatch_t *source,
-                      dns_dispatchset_t **dsetp, int n) {
+                      dns_dispatchset_t **dsetp, uint32_t ndisp) {
        isc_result_t result;
        dns_dispatchset_t *dset = NULL;
        dns_dispatchmgr_t *mgr = NULL;
-       int i, j;
+       size_t i;
 
        REQUIRE(VALID_DISPATCH(source));
        REQUIRE(source->socktype == isc_socktype_udp);
@@ -2213,21 +2174,19 @@ dns_dispatchset_create(isc_mem_t *mctx, dns_dispatch_t *source,
        mgr = source->mgr;
 
        dset = isc_mem_get(mctx, sizeof(dns_dispatchset_t));
-       *dset = (dns_dispatchset_t){ .ndisp = n };
-
-       isc_mutex_init(&dset->lock);
-
-       dset->dispatches = isc_mem_cget(mctx, n, sizeof(dns_dispatch_t *));
+       *dset = (dns_dispatchset_t){ .ndisp = ndisp };
 
        isc_mem_attach(mctx, &dset->mctx);
 
+       dset->dispatches = isc_mem_cget(dset->mctx, ndisp,
+                                       sizeof(dns_dispatch_t *));
+
        dset->dispatches[0] = NULL;
        dns_dispatch_attach(source, &dset->dispatches[0]); /* DISPATCH004 */
 
        LOCK(&mgr->lock);
-       for (i = 1; i < n; i++) {
-               dset->dispatches[i] = NULL;
-               result = dispatch_createudp(mgr, &source->local,
+       for (i = 1; i < dset->ndisp; i++) {
+               result = dispatch_createudp(mgr, &source->local, i,
                                            &dset->dispatches[i]);
                if (result != ISC_R_SUCCESS) {
                        goto fail;
@@ -2242,34 +2201,28 @@ dns_dispatchset_create(isc_mem_t *mctx, dns_dispatch_t *source,
 fail:
        UNLOCK(&mgr->lock);
 
-       for (j = 0; j < i; j++) {
+       for (size_t j = 0; j < i; j++) {
                dns_dispatch_detach(&(dset->dispatches[j])); /* DISPATCH004 */
        }
-       isc_mem_cput(mctx, dset->dispatches, n, sizeof(dns_dispatch_t *));
-       if (dset->mctx == mctx) {
-               isc_mem_detach(&dset->mctx);
-       }
+       isc_mem_cput(dset->mctx, dset->dispatches, ndisp,
+                    sizeof(dns_dispatch_t *));
 
-       isc_mutex_destroy(&dset->lock);
-       isc_mem_put(mctx, dset, sizeof(dns_dispatchset_t));
+       isc_mem_putanddetach(&dset->mctx, dset, sizeof(dns_dispatchset_t));
        return (result);
 }
 
 void
 dns_dispatchset_destroy(dns_dispatchset_t **dsetp) {
-       dns_dispatchset_t *dset = NULL;
-       int i;
-
        REQUIRE(dsetp != NULL && *dsetp != NULL);
 
-       dset = *dsetp;
+       dns_dispatchset_t *dset = *dsetp;
        *dsetp = NULL;
-       for (i = 0; i < dset->ndisp; i++) {
+
+       for (size_t i = 0; i < dset->ndisp; i++) {
                dns_dispatch_detach(&(dset->dispatches[i])); /* DISPATCH004 */
        }
        isc_mem_cput(dset->mctx, dset->dispatches, dset->ndisp,
                     sizeof(dns_dispatch_t *));
-       isc_mutex_destroy(&dset->lock);
        isc_mem_putanddetach(&dset->mctx, dset, sizeof(dns_dispatchset_t));
 }
 
index d5caf9af78916164682922cb07f007cf301bd010..0813224f8b96fc11f8a02510824542cb7bc10e2b 100644 (file)
@@ -69,9 +69,7 @@ ISC_LANG_BEGINDECLS
 struct dns_dispatchset {
        isc_mem_t       *mctx;
        dns_dispatch_t **dispatches;
-       int              ndisp;
-       int              cur;
-       isc_mutex_t      lock;
+       uint32_t         ndisp;
 };
 
 /*
@@ -358,7 +356,7 @@ dns_dispatchset_get(dns_dispatchset_t *dset);
 
 isc_result_t
 dns_dispatchset_create(isc_mem_t *mctx, dns_dispatch_t *source,
-                      dns_dispatchset_t **dsetp, int n);
+                      dns_dispatchset_t **dsetp, uint32_t n);
 /*%<
  * Given a valid dispatch 'source', create a dispatch set containing
  * 'n' UDP dispatches, with the remainder filled out by clones of the
index 0c6af9c816b427a07aeb1496690e54bca0f661b4..01725a13ec2e29f462ffe9e0cb8a5a09d220081b 100644 (file)
@@ -165,9 +165,8 @@ enum {
 #define DNS_QMIN_MAX_NO_DELEGATION 3
 
 isc_result_t
-dns_resolver_create(dns_view_t *view, isc_loopmgr_t *loopmgr,
-                   unsigned int ndisp, isc_nm_t *nm, unsigned int options,
-                   isc_tlsctx_cache_t *tlsctx_cache,
+dns_resolver_create(dns_view_t *view, isc_loopmgr_t *loopmgr, isc_nm_t *nm,
+                   unsigned int options, isc_tlsctx_cache_t *tlsctx_cache,
                    dns_dispatch_t *dispatchv4, dns_dispatch_t *dispatchv6,
                    dns_resolver_t **resp);
 
@@ -183,17 +182,15 @@ dns_resolver_create(dns_view_t *view, isc_loopmgr_t *loopmgr,
  *
  *\li  'view' is a valid view.
  *
- *\li  'ndisp' > 0.
- *
  *\li  'nm' is a valid network manager.
  *
  *\li  'tlsctx_cache' != NULL.
  *
  *\li  'dispatchv4' is a dispatch with an IPv4 UDP socket, or is NULL.
- *     If not NULL, 'ndisp' clones of it will be created by the resolver.
+ *     If not NULL, clones per loop of it will be created by the resolver.
  *
  *\li  'dispatchv6' is a dispatch with an IPv6 UDP socket, or is NULL.
- *     If not NULL, 'ndisp' clones of it will be created by the resolver.
+ *     If not NULL, clones per loop of it will be created by the resolver.
  *
  *\li  resp != NULL && *resp == NULL.
  *
index 7e1babaa163719674394a6b7f42385ce4efdbb01..8904a5a4856502f8048bb7d04957364352bfeeee 100644 (file)
@@ -365,8 +365,8 @@ dns_view_weakdetach(dns_view_t **targetp);
 
 isc_result_t
 dns_view_createresolver(dns_view_t *view, isc_loopmgr_t *loopmgr,
-                       unsigned int ndisp, isc_nm_t *netmgr,
-                       unsigned int options, isc_tlsctx_cache_t *tlsctx_cache,
+                       isc_nm_t *netmgr, unsigned int options,
+                       isc_tlsctx_cache_t *tlsctx_cache,
                        dns_dispatch_t *dispatchv4, dns_dispatch_t *dispatchv6);
 /*%<
  * Create a resolver and address database for the view.
index a5a729157073c568a33a2eac180028de61221212..46affed3f1e69eb4d1479ce6eb3a15bb6c716a69 100644 (file)
@@ -54,8 +54,8 @@ struct dns_requestmgr {
        atomic_bool shuttingdown;
 
        dns_dispatchmgr_t *dispatchmgr;
-       dns_dispatch_t *dispatchv4;
-       dns_dispatch_t *dispatchv6;
+       dns_dispatchset_t *dispatches4;
+       dns_dispatchset_t *dispatches6;
        dns_requestlist_t *requests;
 };
 
@@ -150,10 +150,14 @@ dns_requestmgr_create(isc_mem_t *mctx, isc_loopmgr_t *loopmgr,
        dns_dispatchmgr_attach(dispatchmgr, &requestmgr->dispatchmgr);
 
        if (dispatchv4 != NULL) {
-               dns_dispatch_attach(dispatchv4, &requestmgr->dispatchv4);
+               dns_dispatchset_create(requestmgr->mctx, dispatchv4,
+                                      &requestmgr->dispatches4,
+                                      isc_loopmgr_nloops(requestmgr->loopmgr));
        }
        if (dispatchv6 != NULL) {
-               dns_dispatch_attach(dispatchv6, &requestmgr->dispatchv6);
+               dns_dispatchset_create(requestmgr->mctx, dispatchv6,
+                                      &requestmgr->dispatches6,
+                                      isc_loopmgr_nloops(requestmgr->loopmgr));
        }
 
        isc_refcount_init(&requestmgr->references, 1);
@@ -232,11 +236,11 @@ requestmgr_destroy(dns_requestmgr_t *requestmgr) {
        isc_mem_cput(requestmgr->mctx, requestmgr->requests, nloops,
                     sizeof(requestmgr->requests[0]));
 
-       if (requestmgr->dispatchv4 != NULL) {
-               dns_dispatch_detach(&requestmgr->dispatchv4);
+       if (requestmgr->dispatches4 != NULL) {
+               dns_dispatchset_destroy(&requestmgr->dispatches4);
        }
-       if (requestmgr->dispatchv6 != NULL) {
-               dns_dispatch_detach(&requestmgr->dispatchv6);
+       if (requestmgr->dispatches6 != NULL) {
+               dns_dispatchset_destroy(&requestmgr->dispatches6);
        }
        if (requestmgr->dispatchmgr != NULL) {
                dns_dispatchmgr_detach(&requestmgr->dispatchmgr);
@@ -360,11 +364,11 @@ udp_dispatch(dns_requestmgr_t *requestmgr, const isc_sockaddr_t *srcaddr,
        if (srcaddr == NULL) {
                switch (isc_sockaddr_pf(destaddr)) {
                case PF_INET:
-                       disp = requestmgr->dispatchv4;
+                       disp = dns_dispatchset_get(requestmgr->dispatches4);
                        break;
 
                case PF_INET6:
-                       disp = requestmgr->dispatchv6;
+                       disp = dns_dispatchset_get(requestmgr->dispatches6);
                        break;
 
                default:
index c21513dda8d91aff90cdde6f7f99e2eb7e4208aa..f65b7e4a9267857c0478ed43f6a1e049439e770b 100644 (file)
@@ -9930,9 +9930,8 @@ spillattimer_countdown(void *arg) {
 }
 
 isc_result_t
-dns_resolver_create(dns_view_t *view, isc_loopmgr_t *loopmgr,
-                   unsigned int ndisp, isc_nm_t *nm, unsigned int options,
-                   isc_tlsctx_cache_t *tlsctx_cache,
+dns_resolver_create(dns_view_t *view, isc_loopmgr_t *loopmgr, isc_nm_t *nm,
+                   unsigned int options, isc_tlsctx_cache_t *tlsctx_cache,
                    dns_dispatch_t *dispatchv4, dns_dispatch_t *dispatchv6,
                    dns_resolver_t **resp) {
        dns_resolver_t *res = NULL;
@@ -9942,7 +9941,6 @@ dns_resolver_create(dns_view_t *view, isc_loopmgr_t *loopmgr,
         */
 
        REQUIRE(DNS_VIEW_VALID(view));
-       REQUIRE(ndisp > 0);
        REQUIRE(resp != NULL && *resp == NULL);
        REQUIRE(tlsctx_cache != NULL);
        REQUIRE(dispatchv4 != NULL || dispatchv6 != NULL);
@@ -9989,12 +9987,12 @@ dns_resolver_create(dns_view_t *view, isc_loopmgr_t *loopmgr,
 
        if (dispatchv4 != NULL) {
                dns_dispatchset_create(res->mctx, dispatchv4, &res->dispatches4,
-                                      ndisp);
+                                      isc_loopmgr_nloops(res->loopmgr));
        }
 
        if (dispatchv6 != NULL) {
                dns_dispatchset_create(res->mctx, dispatchv6, &res->dispatches6,
-                                      ndisp);
+                                      isc_loopmgr_nloops(res->loopmgr));
        }
 
        isc_mutex_init(&res->lock);
index 6855d02eda777f2be0d45beaa4623d05516f2102..e07ff434eb37511f720493b7eabdd06aa84febfa 100644 (file)
@@ -589,8 +589,8 @@ dns_view_weakdetach(dns_view_t **viewp) {
 
 isc_result_t
 dns_view_createresolver(dns_view_t *view, isc_loopmgr_t *loopmgr,
-                       unsigned int ndisp, isc_nm_t *netmgr,
-                       unsigned int options, isc_tlsctx_cache_t *tlsctx_cache,
+                       isc_nm_t *netmgr, unsigned int options,
+                       isc_tlsctx_cache_t *tlsctx_cache,
                        dns_dispatch_t *dispatchv4,
                        dns_dispatch_t *dispatchv6) {
        isc_result_t result;
@@ -601,7 +601,7 @@ dns_view_createresolver(dns_view_t *view, isc_loopmgr_t *loopmgr,
        REQUIRE(view->resolver == NULL);
        REQUIRE(view->dispatchmgr != NULL);
 
-       result = dns_resolver_create(view, loopmgr, ndisp, netmgr, options,
+       result = dns_resolver_create(view, loopmgr, netmgr, options,
                                     tlsctx_cache, dispatchv4, dispatchv6,
                                     &view->resolver);
        if (result != ISC_R_SUCCESS) {
index 20bafac59525aa4c9eff3cf6531b1c0e40738c7b..e630c4f24fdcfc71e576177eb351735b0816eda9 100644 (file)
@@ -28,11 +28,11 @@ isc_tid_count(void);
  * Returns the number of threads.
  */
 
-extern thread_local uint32_t tid_local;
+extern thread_local uint32_t isc__tid_local;
 
 static inline uint32_t
 isc_tid(void) {
-       return (tid_local);
+       return (isc__tid_local);
 }
 /*%<
  * Returns the thread ID of the currently-running loop.
index 397fac1c8fde5f9d4f23422d61f861ddd49ca191..d19a4135547b4065a4bdf210f85a08771aefaf70 100644 (file)
@@ -23,7 +23,7 @@
 /**
  * Private
  */
-thread_local uint32_t tid_local = ISC_TID_UNKNOWN;
+thread_local uint32_t isc__tid_local = ISC_TID_UNKNOWN;
 
 /*
  * Zero is a better nonsense value in this case than ISC_TID_UNKNOWN;
@@ -37,8 +37,8 @@ static uint32_t tid_count = 0;
 
 void
 isc__tid_init(uint32_t tid) {
-       REQUIRE(tid_local == ISC_TID_UNKNOWN || tid_local == tid);
-       tid_local = tid;
+       REQUIRE(isc__tid_local == ISC_TID_UNKNOWN || isc__tid_local == tid);
+       isc__tid_local = tid;
 }
 
 void
index 651f4d429b1a4c627c6269bf084fed5b285b8f93..aea5b2dfacbf61e5383b67b45b72a63fa4a56a50 100644 (file)
@@ -65,9 +65,6 @@
 
 #define NS_INTERFACEFLAG_ANYADDR   0x01U /*%< bound to "any" address */
 #define NS_INTERFACEFLAG_LISTENING 0x02U /*%< listening */
-#define MAX_UDP_DISPATCH                           \
-       128 /*%< Maximum number of UDP dispatchers \
-            *           to start per interface */
 /*% The nameserver interface structure */
 struct ns_interface {
        unsigned int       magic; /*%< Magic number. */
index 0780003bab8c4fbf8d1534ff8980a1b8fcd78e08..150ad405ac644815dd8b428ec4cae8e018be35ce 100644 (file)
@@ -261,11 +261,12 @@ ISC_LOOP_TEST_IMPL(dispatchset_create) {
        isc_loopmgr_shutdown(loopmgr);
 }
 
-/* test dispatch set round-robin */
+/* test dispatch set per-loop dispatch */
 ISC_LOOP_TEST_IMPL(dispatchset_get) {
        isc_result_t result;
        dns_dispatchset_t *dset = NULL;
        dns_dispatch_t *d1, *d2, *d3, *d4, *d5;
+       uint32_t tid_saved;
 
        UNUSED(arg);
 
@@ -291,10 +292,21 @@ ISC_LOOP_TEST_IMPL(dispatchset_get) {
        result = make_dispatchset(4, &dset);
        assert_int_equal(result, ISC_R_SUCCESS);
 
+       /*
+        * Temporarily modify and then restore the current thread's
+        * ID value, in order to confirm that different threads get
+        * different dispatch sets but the same thread gets the same
+        * one.
+        */
+       tid_saved = isc__tid_local;
        d1 = dns_dispatchset_get(dset);
+       isc__tid_local++;
        d2 = dns_dispatchset_get(dset);
+       isc__tid_local++;
        d3 = dns_dispatchset_get(dset);
+       isc__tid_local++;
        d4 = dns_dispatchset_get(dset);
+       isc__tid_local = tid_saved;
        d5 = dns_dispatchset_get(dset);
 
        assert_ptr_equal(d1, d5);
index 09106aadd6b4ccd91a08d025f68866bec7941403..3f53f9f3514e31bbb92a2edcaebdf208e4f01f8b 100644 (file)
@@ -76,7 +76,7 @@ mkres(dns_resolver_t **resolverp) {
        isc_result_t result;
 
        isc_tlsctx_cache_create(mctx, &tlsctx_cache);
-       result = dns_resolver_create(view, loopmgr, 1, netmgr, 0, tlsctx_cache,
+       result = dns_resolver_create(view, loopmgr, netmgr, 0, tlsctx_cache,
                                     dispatch, NULL, resolverp);
        assert_int_equal(result, ISC_R_SUCCESS);
 }