]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Make ns_client mctxpool more thread-friendly by sharding it by netmgr threadid
authorWitold Kręcicki <wpk@isc.org>
Tue, 28 Jan 2020 10:05:07 +0000 (11:05 +0100)
committerWitold Kręcicki <wpk@isc.org>
Fri, 7 Feb 2020 09:13:53 +0000 (10:13 +0100)
bin/named/server.c
lib/ns/client.c
lib/ns/include/ns/client.h
lib/ns/include/ns/interfacemgr.h
lib/ns/interfacemgr.c
lib/ns/tests/nstest.c

index 6a818a31493d731fd1f89ec9f737fd0af745d541..d14f63c866e04cfb6b6cb3266fd0bcbb447feefb 100644 (file)
@@ -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,
index d0653d2fa7a739375503a6d655607a33e3456bb2..3f60bcee6e2a88c5cd4fac96fcdb0be8b8b5714d 100644 (file)
@@ -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");
index d1e4f28f335456d2a1c72ff92626e4b48e5b4f55..ce58ed3d4db6c6335e254ade28e2a4d4f185348c 100644 (file)
@@ -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.
index 0212460cc4d3cc351de4b499288199614adba834..2ff490a196e2b1d29977b33655e553f88104c651 100644 (file)
@@ -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.
  *
index df1fe63aab533454bd5da8b94d0c0cf92f2a454d..982a678bc9652ab5951af610e706c859c0346247 100644 (file)
@@ -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",
index d4314693d2ff6514b78530b6c28473a6b6208549..b4f1367596d9e8dc73831ffeb4927c71c52be2c0 100644 (file)
@@ -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);