]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
dnsdist: Add an option to set the size of the TCP internal pipe's buffer
authorRemi Gacogne <remi.gacogne@powerdns.com>
Mon, 8 Feb 2021 15:01:07 +0000 (16:01 +0100)
committerRemi Gacogne <remi.gacogne@powerdns.com>
Tue, 2 Mar 2021 09:47:26 +0000 (10:47 +0100)
pdns/dnsdist-console.cc
pdns/dnsdist-lua.cc
pdns/dnsdist-tcp.cc
pdns/dnsdist.hh
pdns/dnsdistdist/docs/advanced/tuning.rst
pdns/dnsdistdist/docs/reference/tuning.rst

index 88e2de511ecf6b514bad51c1de55e8e256f5c9ee..55fdc7a6ca5700a9f5b4504b241b36f02d287368 100644 (file)
@@ -615,6 +615,7 @@ const std::vector<ConsoleKeyword> g_consoleKeywords{
   { "setStaleCacheEntriesTTL", true, "n", "allows using cache entries expired for at most n seconds when there is no backend available to answer for a query" },
   { "setSyslogFacility", true, "facility", "set the syslog logging facility to 'facility'. Defaults to LOG_DAEMON" },
   { "setTCPDownstreamCleanupInterval", true, "interval", "minimum interval in seconds between two cleanups of the idle TCP downstream connections" },
+  { "setTCPInternalPipeBufferSize", true, "size", "Set the size in bytes of the internal buffer of the pipes used internally to distribute connections to TCP (and DoT) workers threads" },
   { "setTCPUseSinglePipe", true, "bool", "whether the incoming TCP connections should be put into a single queue instead of using per-thread queues. Defaults to false" },
   { "setTCPRecvTimeout", true, "n", "set the read timeout on TCP connections from the client, in seconds" },
   { "setTCPSendTimeout", true, "n", "set the write timeout on TCP connections from the client, in seconds" },
index 7535c66ced2ecd2cce3b9c6923e031964d0aa579..77f12140d5607f398ba448be3410ca0cfdb256a8 100644 (file)
@@ -1817,6 +1817,8 @@ static void setupLuaConfig(LuaContext& luaCtx, bool client, bool configCheck)
       g_useTCPSinglePipe = flag;
     });
 
+  luaCtx.writeFunction("setTCPInternalPipeBufferSize", [](size_t size) { g_tcpInternalPipeBufferSize = size; });
+
   luaCtx.writeFunction("snmpAgent", [client,configCheck](bool enableTraps, boost::optional<std::string> daemonSocket) {
       if(client || configCheck)
         return;
index e4840fc9e1626e15956c7df5211a25a286aef275..e2f1aab0c69751b7d0d5201a608e4da4a5db9ea1 100644 (file)
@@ -62,6 +62,7 @@ uint64_t g_maxTCPQueuedConnections{1000};
 size_t g_maxTCPQueriesPerConn{0};
 size_t g_maxTCPConnectionDuration{0};
 size_t g_maxTCPConnectionsPerClient{0};
+size_t g_tcpInternalPipeBufferSize{0};
 uint16_t g_downstreamTCPCleanupInterval{60};
 bool g_useTCPSinglePipe{false};
 
@@ -212,7 +213,9 @@ TCPClientCollection::TCPClientCollection(size_t maxThreads, bool useSinglePipe):
       throw std::runtime_error("Error setting the TCP single communication pipe non-blocking: " + stringerror(err));
     }
 
-    setPipeBufferSize(d_singlePipe[0], 1048576);
+    if (g_tcpInternalPipeBufferSize > 0 && getPipeBufferSize(d_singlePipe[0]) < g_tcpInternalPipeBufferSize) {
+      setPipeBufferSize(d_singlePipe[0], g_tcpInternalPipeBufferSize);
+    }
   }
 }
 
@@ -247,6 +250,10 @@ void TCPClientCollection::addTCPClientThread()
       errlog("Error setting the TCP thread communication pipe non-blocking: %s", stringerror(err));
       return;
     }
+
+    if (g_tcpInternalPipeBufferSize > 0 && getPipeBufferSize(pipefds[0]) < g_tcpInternalPipeBufferSize) {
+      setPipeBufferSize(pipefds[0], g_tcpInternalPipeBufferSize);
+    }
   }
 
   {
index 81b1b3af52ded2d28d56a112fc40b142bfb7078b..9e7634fc74b54abd5dbf602911a944048d5b1457 100644 (file)
@@ -1183,6 +1183,7 @@ extern uint64_t g_maxTCPQueuedConnections;
 extern size_t g_maxTCPQueriesPerConn;
 extern size_t g_maxTCPConnectionDuration;
 extern size_t g_maxTCPConnectionsPerClient;
+extern size_t g_tcpInternalPipeBufferSize;
 extern pdns::stat16_t g_cacheCleaningDelay;
 extern pdns::stat16_t g_cacheCleaningPercentage;
 extern uint32_t g_staleCacheEntriesTTL;
index 692f14979d2f6edadc0e65619b228eccdaf70271..72454ad9e2661455b0e8e5ef5130889e6ce9c600 100644 (file)
@@ -21,7 +21,7 @@ If all the TCP threads are busy, new TCP connections are queued while they wait
 Before 1.4.0, a TCP thread could only handle a single incoming connection at a time. Starting with 1.4.0 the handling of TCP connections is now event-based, so a single TCP worker can handle a large number of TCP incoming connections simultaneously.
 Note that before 1.6.0 the TCP worker threads were created at runtime, adding a new thread when the existing ones seemed to struggle with the load, until the maximum number of threads had been reached. Starting with 1.6.0 the configured number of worker threads are immediately created at startup.
 
-The maximum number of queued connections can be configured with :func:`setMaxTCPQueuedConnections` and defaults to 1000.
+The maximum number of queued connections can be configured with :func:`setMaxTCPQueuedConnections` and defaults to 1000. Note that the size of the internal pipe used to distribute queries might need to be increased as well, using :func:`setTCPInternalPipeBufferSize`.
 Any value larger than 0 will cause new connections to be dropped if there are already too many queued.
 By default, every TCP worker thread has its own queue, and the incoming TCP connections are dispatched to TCP workers on a round-robin basis.
 This might cause issues if some connections are taking a very long time, since incoming ones will be waiting until the TCP worker they have been assigned to has finished handling its current query, while other TCP workers might be available.
index 015e37e00d65077454122d4e447a16c2321325d6..4ceaef264bb13490ffaabaab0e35f1d96c62cf7f 100644 (file)
@@ -63,6 +63,14 @@ Tuning related functions
 
   :param int num:
 
+.. function:: setTCPInternalPipeBufferSize(size)
+
+  .. versionadded:: 1.6.0
+
+  Set the size in bytes of the internal buffer of the pipes used internally to distribute connections to TCP (and DoT) workers threads. Requires support for ``F_SETPIPE_SZ`` which is present in Linux since 2.6.35. The actual size might be rounded up to a multiple of a page size. 0 means that the OS default size is used.
+
+  :param int size: The size in bytes.
+
 .. function:: setTCPUseSinglePipe(val)
 
   Whether the incoming TCP connections should be put into a single queue instead of using per-thread queues. Defaults to false