]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Replace the tcp_buffers memory pool with static per-loop buffer
authorOndřej Surý <ondrej@isc.org>
Tue, 4 Jun 2024 06:38:35 +0000 (08:38 +0200)
committerNicki Křížek <nicki@isc.org>
Mon, 10 Jun 2024 16:43:46 +0000 (18:43 +0200)
As a single thread can process only one TCP send at the time, we don't
really need a memory pool for the TCP buffers, but it's enough to have
a single per-loop (client manager) static buffer that's being used to
assemble the DNS message and then it gets copied into own sending
buffer.

In the future, this should get optimized by exposing the uv_try API
from the network manager, and first try to send the message directly
and allocate the sending buffer only if we need to send the data
asynchronously.

(cherry picked from commit 297cc840fbaf34b9dfa1d02d88a023cd5bf5dc4a)

lib/ns/client.c
lib/ns/include/ns/client.h

index e3cd815922af134946dd58258580844cc2d2b68e..7143e49249e73268fb9af86e9a69dac45a17269d 100644 (file)
@@ -343,7 +343,7 @@ static void
 client_setup_tcp_buffer(ns_client_t *client) {
        REQUIRE(client->tcpbuf == NULL);
 
-       client->tcpbuf = isc_mempool_get(client->manager->tcp_buffers);
+       client->tcpbuf = client->manager->tcp_buffer;
        client->tcpbuf_size = NS_CLIENT_TCP_BUFFER_SIZE;
 }
 
@@ -353,13 +353,12 @@ client_put_tcp_buffer(ns_client_t *client) {
                return;
        }
 
-       if (client->tcpbuf_size == NS_CLIENT_TCP_BUFFER_SIZE) {
-               isc_mempool_put(client->manager->tcp_buffers, client->tcpbuf);
-       } else {
+       if (client->tcpbuf != client->manager->tcp_buffer) {
                isc_mem_put(client->manager->send_mctx, client->tcpbuf,
                            client->tcpbuf_size);
        }
 
+       client->tcpbuf = NULL;
        client->tcpbuf_size = 0;
 }
 
@@ -407,21 +406,14 @@ client_sendpkg(ns_client_t *client, isc_buffer_t *buffer) {
 
        if (isc_buffer_base(buffer) == client->tcpbuf) {
                size_t used = isc_buffer_usedlength(buffer);
-               const size_t threshold = (3 * NS_CLIENT_TCP_BUFFER_SIZE) / 4;
-
                INSIST(client->tcpbuf_size == NS_CLIENT_TCP_BUFFER_SIZE);
+
                /*
                 * Copy the data into a smaller buffer before sending,
                 * and keep the original big TCP send buffer for reuse
                 * by other clients.
                 */
-               if (used > threshold) {
-                       /*
-                        * The data in the buffer is very large, so there is
-                        * no point in using a smaller buffer.
-                        */
-                       r.base = buffer->base;
-               } else if (used > NS_CLIENT_SEND_BUFFER_SIZE) {
+               if (used > NS_CLIENT_SEND_BUFFER_SIZE) {
                        /*
                         * We can save space by allocating a new buffer with a
                         * correct size and freeing the big buffer.
@@ -1727,8 +1719,6 @@ ns__client_put_cb(void *client0) {
        client->magic = 0;
        client->shuttingdown = true;
 
-       isc_mem_put(client->manager->send_mctx, client->sendbuf,
-                   NS_CLIENT_SEND_BUFFER_SIZE);
        if (client->opt != NULL) {
                INSIST(dns_rdataset_isassociated(client->opt));
                dns_rdataset_disassociate(client->opt);
@@ -2405,9 +2395,6 @@ ns__client_setup(ns_client_t *client, ns_clientmgr_t *mgr, bool new) {
                dns_message_create(client->mctx, DNS_MESSAGE_INTENTPARSE,
                                   &client->message);
 
-               client->sendbuf = isc_mem_get(client->manager->send_mctx,
-                                             NS_CLIENT_SEND_BUFFER_SIZE);
-
                /*
                 * Set magic earlier than usual because ns_query_init()
                 * and the functions it calls will require it.
@@ -2424,7 +2411,6 @@ ns__client_setup(ns_client_t *client, ns_clientmgr_t *mgr, bool new) {
                ns_clientmgr_t *oldmgr = client->manager;
                ns_server_t *sctx = client->sctx;
                isc_task_t *task = client->task;
-               unsigned char *sendbuf = client->sendbuf;
                dns_message_t *message = client->message;
                isc_mem_t *oldmctx = client->mctx;
                ns_query_t query = client->query;
@@ -2439,7 +2425,6 @@ ns__client_setup(ns_client_t *client, ns_clientmgr_t *mgr, bool new) {
                                         .manager = oldmgr,
                                         .sctx = sctx,
                                         .task = task,
-                                        .sendbuf = sendbuf,
                                         .message = message,
                                         .query = query,
                                         .tid = tid };
@@ -2464,8 +2449,6 @@ ns__client_setup(ns_client_t *client, ns_clientmgr_t *mgr, bool new) {
        return (ISC_R_SUCCESS);
 
 cleanup:
-       isc_mem_put(client->manager->send_mctx, client->sendbuf,
-                   NS_CLIENT_SEND_BUFFER_SIZE);
        dns_message_detach(&client->message);
        isc_task_detach(&client->task);
        ns_clientmgr_detach(&client->manager);
@@ -2528,8 +2511,6 @@ clientmgr_destroy(ns_clientmgr_t *manager) {
        isc_task_detach(&manager->task);
        ns_server_detach(&manager->sctx);
 
-       isc_mempool_destroy(&manager->tcp_buffers);
-
        isc_mem_detach(&manager->send_mctx);
 
        isc_mem_putanddetach(&manager->mctx, manager, sizeof(*manager));
@@ -2623,13 +2604,6 @@ ns_clientmgr_create(ns_server_t *sctx, isc_taskmgr_t *taskmgr,
         */
        (void)isc_mem_arena_set_muzzy_decay_ms(manager->send_mctx, 0);
 
-       isc_mempool_create(manager->send_mctx,
-                          (size_t)NS_CLIENT_TCP_BUFFER_SIZE,
-                          &manager->tcp_buffers);
-       isc_mempool_setfillcount(manager->tcp_buffers, TCPBUFFERS_FILLCOUNT);
-       isc_mempool_setfreemax(manager->tcp_buffers, TCPBUFFERS_FREEMAX);
-       isc_mempool_setname(manager->tcp_buffers, "ns_clientmgr_tcp");
-
        manager->magic = MANAGER_MAGIC;
 
        MTRACE("create");
index 3570689c6493b79e2fe004219c4d0ab7183e9006..08ee1123a8f759b5637dad6280030d64aab48fac 100644 (file)
@@ -160,7 +160,7 @@ struct ns_clientmgr {
        isc_mutex_t   reclock;
        client_list_t recursing; /*%< Recursing clients */
 
-       isc_mempool_t *tcp_buffers;
+       uint8_t tcp_buffer[NS_CLIENT_TCP_BUFFER_SIZE];
 };
 
 /*% nameserver client structure */
@@ -189,7 +189,6 @@ struct ns_client {
        unsigned char  *tcpbuf;
        size_t          tcpbuf_size;
        dns_message_t  *message;
-       unsigned char  *sendbuf;
        dns_rdataset_t *opt;
        dns_ednsopt_t  *ede;
        uint16_t        udpsize;
@@ -242,6 +241,8 @@ struct ns_client {
         * bits will be used as the rcode in the response message.
         */
        int32_t rcode_override;
+
+       uint8_t sendbuf[NS_CLIENT_SEND_BUFFER_SIZE];
 };
 
 #define NS_CLIENT_MAGIC           ISC_MAGIC('N', 'S', 'C', 'c')