From: Witold Kręcicki Date: Tue, 28 Jan 2020 10:05:07 +0000 (+0100) Subject: Make ns_client mctxpool more thread-friendly by sharding it by netmgr threadid X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=3d9763b968e192ad105d0351c4d4f380a63c3d7f;p=thirdparty%2Fbind9.git Make ns_client mctxpool more thread-friendly by sharding it by netmgr threadid --- diff --git a/bin/named/server.c b/bin/named/server.c index 6a818a31493..d14f63c866e 100644 --- a/bin/named/server.c +++ b/bin/named/server.c @@ -9544,7 +9544,7 @@ run_server(isc_task_t *task, isc_event_t *event) { named_g_nm, named_g_dispatchmgr, server->task, named_g_udpdisp, geoip, - &server->interfacemgr), + named_g_cpus, &server->interfacemgr), "creating interface manager"); CHECKFATAL(isc_timer_create(named_g_timermgr, isc_timertype_inactive, diff --git a/lib/ns/client.c b/lib/ns/client.c index d0653d2fa7a..3f60bcee6e2 100644 --- a/lib/ns/client.c +++ b/lib/ns/client.c @@ -2214,34 +2214,16 @@ ns__client_tcpconn(isc_nmhandle_t *handle, isc_result_t result, void *arg) { static void get_clientmctx(ns_clientmgr_t *manager, isc_mem_t **mctxp) { isc_mem_t *clientmctx; -#if CLIENT_NMCTXS > 0 unsigned int nextmctx; -#endif - MTRACE("clientmctx"); -#if CLIENT_NMCTXS > 0 - LOCK(&manager->lock); - if (isc_nm_tid() >= 0) { - nextmctx = isc_nm_tid(); - } else { - nextmctx = manager->nextmctx++; - if (manager->nextmctx == CLIENT_NMCTXS) - manager->nextmctx = 0; - - INSIST(nextmctx < CLIENT_NMCTXS); + int tid = isc_nm_tid(); + if (tid < 0) { + tid = isc_random_uniform(manager->ncpus); } - + int rand = isc_random_uniform(CLIENT_NMCTXS_PERCPU); + nextmctx = (rand * manager->ncpus) + tid; clientmctx = manager->mctxpool[nextmctx]; - if (clientmctx == NULL) { - isc_mem_create(&clientmctx); - isc_mem_setname(clientmctx, "client", NULL); - manager->mctxpool[nextmctx] = clientmctx; - } - UNLOCK(&manager->lock); -#else - clientmctx = manager->mctx; -#endif isc_mem_attach(clientmctx, mctxp); } @@ -2399,21 +2381,18 @@ clientmgr_detach(ns_clientmgr_t **mp) { static void clientmgr_destroy(ns_clientmgr_t *manager) { -#if CLIENT_NMCTXS > 0 int i; -#endif MTRACE("clientmgr_destroy"); isc_refcount_destroy(&manager->references); manager->magic = 0; -#if CLIENT_NMCTXS > 0 - for (i = 0; i < CLIENT_NMCTXS; i++) { - if (manager->mctxpool[i] != NULL) - isc_mem_detach(&manager->mctxpool[i]); + for (i = 0; i < manager->ncpus * CLIENT_NMCTXS_PERCPU; i++) { + isc_mem_detach(&manager->mctxpool[i]); } -#endif + isc_mem_put(manager->mctx, manager->mctxpool, + manager->ncpus * CLIENT_NMCTXS_PERCPU * sizeof(isc_mem_t*)); if (manager->interface != NULL) { ns_interface_detach(&manager->interface); @@ -2440,13 +2419,12 @@ clientmgr_destroy(ns_clientmgr_t *manager) { isc_result_t ns_clientmgr_create(isc_mem_t *mctx, ns_server_t *sctx, isc_taskmgr_t *taskmgr, isc_timermgr_t *timermgr, ns_interface_t *interface, - ns_clientmgr_t **managerp) + int ncpus, ns_clientmgr_t **managerp) { ns_clientmgr_t *manager; isc_result_t result; -#if CLIENT_NMCTXS > 0 int i; -#endif + int npools; manager = isc_mem_get(mctx, sizeof(*manager)); *manager = (ns_clientmgr_t) { .magic = 0 }; @@ -2478,11 +2456,17 @@ ns_clientmgr_create(isc_mem_t *mctx, ns_server_t *sctx, isc_taskmgr_t *taskmgr, ns_server_attach(sctx, &manager->sctx); ISC_LIST_INIT(manager->recursing); -#if CLIENT_NMCTXS > 0 - manager->nextmctx = 0; - for (i = 0; i < CLIENT_NMCTXS; i++) - manager->mctxpool[i] = NULL; /* will be created on-demand */ -#endif + + manager->ncpus = ncpus; + npools = CLIENT_NMCTXS_PERCPU * manager->ncpus; + manager->mctxpool = isc_mem_get(manager->mctx, + npools * sizeof(isc_mem_t*)); + for (i = 0; i < npools; i++) { + manager->mctxpool[i] = NULL; + isc_mem_create(&manager->mctxpool[i]); + isc_mem_setname(manager->mctxpool[i], "client", NULL); + } + manager->magic = MANAGER_MAGIC; MTRACE("create"); diff --git a/lib/ns/include/ns/client.h b/lib/ns/include/ns/client.h index d1e4f28f335..ce58ed3d4db 100644 --- a/lib/ns/include/ns/client.h +++ b/lib/ns/include/ns/client.h @@ -85,7 +85,7 @@ #define NS_CLIENT_SEND_BUFFER_SIZE 4096 #define NS_CLIENT_RECV_BUFFER_SIZE 4096 -#define CLIENT_NMCTXS 100 +#define CLIENT_NMCTXS_PERCPU 8 /*%< * Number of 'mctx pools' for clients. (Should this be configurable?) * When enabling threads, we use a pool of memory contexts shared by @@ -166,6 +166,7 @@ struct ns_clientmgr { isc_timermgr_t * timermgr; isc_task_t * excl; isc_refcount_t references; + int ncpus; /* Attached by clients, needed for e.g. recursion */ isc_task_t ** taskpool; @@ -180,11 +181,8 @@ struct ns_clientmgr { isc_mutex_t reclock; client_list_t recursing; /*%< Recursing clients */ -#if CLIENT_NMCTXS > 0 /*%< mctx pool for clients. */ - unsigned int nextmctx; - isc_mem_t * mctxpool[CLIENT_NMCTXS]; -#endif + isc_mem_t ** mctxpool; }; /*% nameserver client structure */ @@ -364,7 +362,7 @@ ns_client_settimeout(ns_client_t *client, unsigned int seconds); isc_result_t ns_clientmgr_create(isc_mem_t *mctx, ns_server_t *sctx, isc_taskmgr_t *taskmgr, - isc_timermgr_t *timermgr, ns_interface_t *ifp, + isc_timermgr_t *timermgr, ns_interface_t *ifp, int ncpus, ns_clientmgr_t **managerp); /*%< * Create a client manager. diff --git a/lib/ns/include/ns/interfacemgr.h b/lib/ns/include/ns/interfacemgr.h index 0212460cc4d..2ff490a196e 100644 --- a/lib/ns/include/ns/interfacemgr.h +++ b/lib/ns/include/ns/interfacemgr.h @@ -103,7 +103,7 @@ ns_interfacemgr_create(isc_mem_t *mctx, ns_server_t *sctx, isc_socketmgr_t *socketmgr, isc_nm_t *nm, dns_dispatchmgr_t *dispatchmgr, isc_task_t *task, unsigned int udpdisp, dns_geoip_databases_t *geoip, - ns_interfacemgr_t **mgrp); + int ncpus, ns_interfacemgr_t **mgrp); /*%< * Create a new interface manager. * diff --git a/lib/ns/interfacemgr.c b/lib/ns/interfacemgr.c index df1fe63aab5..982a678bc96 100644 --- a/lib/ns/interfacemgr.c +++ b/lib/ns/interfacemgr.c @@ -75,6 +75,7 @@ struct ns_interfacemgr { isc_timermgr_t * timermgr; /*%< Timer manager. */ isc_socketmgr_t * socketmgr; /*%< Socket manager. */ isc_nm_t * nm; /*%< Net manager. */ + int ncpus; /*%< Number of workers . */ dns_dispatchmgr_t * dispatchmgr; unsigned int generation; /*%< Current generation no. */ ns_listenlist_t * listenon4; @@ -181,6 +182,7 @@ ns_interfacemgr_create(isc_mem_t *mctx, isc_task_t *task, unsigned int udpdisp, dns_geoip_databases_t *geoip, + int ncpus, ns_interfacemgr_t **mgrp) { isc_result_t result; @@ -219,6 +221,7 @@ ns_interfacemgr_create(isc_mem_t *mctx, mgr->listenon4 = NULL; mgr->listenon6 = NULL; mgr->udpdisp = udpdisp; + mgr->ncpus = ncpus; atomic_init(&mgr->shuttingdown, false); ISC_LIST_INIT(mgr->interfaces); @@ -425,7 +428,7 @@ ns_interface_create(ns_interfacemgr_t *mgr, isc_sockaddr_t *addr, result = ns_clientmgr_create(mgr->mctx, mgr->sctx, mgr->taskmgr, mgr->timermgr, ifp, - &ifp->clientmgr); + mgr->ncpus, &ifp->clientmgr); if (result != ISC_R_SUCCESS) { isc_log_write(IFMGR_COMMON_LOGARGS, ISC_LOG_ERROR, "ns_clientmgr_create() failed: %s", diff --git a/lib/ns/tests/nstest.c b/lib/ns/tests/nstest.c index d4314693d2f..b4f1367596d 100644 --- a/lib/ns/tests/nstest.c +++ b/lib/ns/tests/nstest.c @@ -237,7 +237,7 @@ create_managers(void) { CHECK(ns_interfacemgr_create(mctx, sctx, taskmgr, timermgr, socketmgr, nm, dispatchmgr, maintask, - ncpus, NULL, &interfacemgr)); + ncpus, NULL, 1, &interfacemgr)); CHECK(ns_listenlist_default(mctx, port, -1, true, &listenon)); ns_interfacemgr_setlistenon4(interfacemgr, listenon);