]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
dnsdist: Add support for pinning listener threads to specific CPUs
authorRemi Gacogne <remi.gacogne@powerdns.com>
Wed, 12 Jul 2017 20:46:43 +0000 (22:46 +0200)
committerRemi Gacogne <remi.gacogne@powerdns.com>
Tue, 5 Sep 2017 14:44:54 +0000 (16:44 +0200)
pdns/dnsdist-lua.cc
pdns/dnsdist-lua.hh
pdns/dnsdist-lua2.cc
pdns/dnsdist.cc
pdns/dnsdist.hh
pdns/dnsdistdist/configure.ac
pdns/dnsdistdist/m4/pdns_check_pthread_np.m4 [new symlink]

index 799c10eb1acb114a78370b23066c2751298bed08..cd22d401e270e0530dcb42d4d8a1a75d03c27cb7 100644 (file)
@@ -177,7 +177,7 @@ std::unordered_map<int, vector<boost::variant<string,double>>> getGenResponses(u
   return ret;
 }
 
-void parseLocalBindVars(boost::optional<localbind_t> vars, bool& doTCP, bool& reusePort, int& tcpFastOpenQueueSize, std::string& interface)
+void parseLocalBindVars(boost::optional<localbind_t> vars, bool& doTCP, bool& reusePort, int& tcpFastOpenQueueSize, std::string& interface, std::set<int>& cpus)
 {
   if (vars) {
     if (vars->count("doTCP")) {
@@ -192,6 +192,11 @@ void parseLocalBindVars(boost::optional<localbind_t> vars, bool& doTCP, bool& re
     if (vars->count("interface")) {
       interface = boost::get<std::string>((*vars)["interface"]);
     }
+    if (vars->count("cpus")) {
+      for (const auto cpu : boost::get<std::vector<std::pair<int,int>>>((*vars)["cpus"])) {
+        cpus.insert(cpu.second);
+      }
+    }
   }
 }
 
@@ -642,13 +647,14 @@ vector<std::function<void(void)>> setupLua(bool client, const std::string& confi
       bool reusePort = false;
       int tcpFastOpenQueueSize = 0;
       std::string interface;
+      std::set<int> cpus;
 
-      parseLocalBindVars(vars, doTCP, reusePort, tcpFastOpenQueueSize, interface);
+      parseLocalBindVars(vars, doTCP, reusePort, tcpFastOpenQueueSize, interface, cpus);
 
       try {
        ComboAddress loc(addr, 53);
        g_locals.clear();
-       g_locals.push_back(std::make_tuple(loc, doTCP, reusePort, tcpFastOpenQueueSize, interface)); /// only works pre-startup, so no sync necessary
+       g_locals.push_back(std::make_tuple(loc, doTCP, reusePort, tcpFastOpenQueueSize, interface, cpus)); /// only works pre-startup, so no sync necessary
       }
       catch(std::exception& e) {
        g_outputBuffer="Error: "+string(e.what())+"\n";
@@ -667,12 +673,13 @@ vector<std::function<void(void)>> setupLua(bool client, const std::string& confi
       bool reusePort = false;
       int tcpFastOpenQueueSize = 0;
       std::string interface;
+      std::set<int> cpus;
 
-      parseLocalBindVars(vars, doTCP, reusePort, tcpFastOpenQueueSize, interface);
+      parseLocalBindVars(vars, doTCP, reusePort, tcpFastOpenQueueSize, interface, cpus);
 
       try {
        ComboAddress loc(addr, 53);
-       g_locals.push_back(std::make_tuple(loc, doTCP, reusePort, tcpFastOpenQueueSize, interface)); /// only works pre-startup, so no sync necessary
+       g_locals.push_back(std::make_tuple(loc, doTCP, reusePort, tcpFastOpenQueueSize, interface, cpus)); /// only works pre-startup, so no sync necessary
       }
       catch(std::exception& e) {
        g_outputBuffer="Error: "+string(e.what())+"\n";
index 30a3f9a56e84e7b7ebea803e79b27b5ebd9b894c..ce2786bb0ff9d76eb56a6bb0e7186b5c3e47f06a 100644 (file)
@@ -21,8 +21,8 @@
  */
 #pragma once
 
-typedef std::unordered_map<std::string, boost::variant<bool, int, std::string> > localbind_t;
-void parseLocalBindVars(boost::optional<localbind_t> vars, bool& doTCP, bool& reusePort, int& tcpFastOpenQueueSize, std::string& interface);
+typedef std::unordered_map<std::string, boost::variant<bool, int, std::string, std::vector<std::pair<int,int> > > > localbind_t;
+void parseLocalBindVars(boost::optional<localbind_t> vars, bool& doTCP, bool& reusePort, int& tcpFastOpenQueueSize, std::string& interface, std::set<int>& cpus);
 
 typedef boost::variant<string, vector<pair<int, string>>, std::shared_ptr<DNSRule>, DNSName, vector<pair<int, DNSName> > > luadnsrule_t;
 std::shared_ptr<DNSRule> makeRule(const luadnsrule_t& var);
index 26eeaebbaf7af0aae43ef8a6483a81283e7fbc4a..d896c16279910d35c91b2d5691ff5365ce81fe3c 100644 (file)
@@ -550,12 +550,13 @@ void moreLua(bool client)
       bool reusePort = false;
       int tcpFastOpenQueueSize = 0;
       std::string interface;
+      std::set<int> cpus;
 
-      parseLocalBindVars(vars, doTCP, reusePort, tcpFastOpenQueueSize, interface);
+      parseLocalBindVars(vars, doTCP, reusePort, tcpFastOpenQueueSize, interface, cpus);
 
       try {
         DnsCryptContext ctx(providerName, certFile, keyFile);
-        g_dnsCryptLocals.push_back(std::make_tuple(ComboAddress(addr, 443), ctx, reusePort, tcpFastOpenQueueSize, interface));
+        g_dnsCryptLocals.push_back(std::make_tuple(ComboAddress(addr, 443), ctx, reusePort, tcpFastOpenQueueSize, interface, cpus));
       }
       catch(std::exception& e) {
         errlog(e.what());
index fa3293df1782d316758c3da6cbe58ad004190975..8f3634a53f99b8b417080faec78fd2d30fb5cd78 100644 (file)
@@ -78,9 +78,9 @@ bool g_syslog{true};
 
 GlobalStateHolder<NetmaskGroup> g_ACL;
 string g_outputBuffer;
-vector<std::tuple<ComboAddress, bool, bool, int, string>> g_locals;
+vector<std::tuple<ComboAddress, bool, bool, int, string, std::set<int>>> g_locals;
 #ifdef HAVE_DNSCRYPT
-std::vector<std::tuple<ComboAddress,DnsCryptContext,bool, int, string>> g_dnsCryptLocals;
+std::vector<std::tuple<ComboAddress,DnsCryptContext,bool, int, string, std::set<int>>> g_dnsCryptLocals;
 #endif
 #ifdef HAVE_EBPF
 shared_ptr<BPFFilter> g_defaultBPFFilter;
@@ -2032,11 +2032,11 @@ try
   if(g_cmdLine.locals.size()) {
     g_locals.clear();
     for(auto loc : g_cmdLine.locals)
-      g_locals.push_back(std::make_tuple(ComboAddress(loc, 53), true, false, 0, ""));
+      g_locals.push_back(std::make_tuple(ComboAddress(loc, 53), true, false, 0, "", std::set<int>()));
   }
   
   if(g_locals.empty())
-    g_locals.push_back(std::make_tuple(ComboAddress("127.0.0.1", 53), true, false, 0, ""));
+    g_locals.push_back(std::make_tuple(ComboAddress("127.0.0.1", 53), true, false, 0, "", std::set<int>()));
 
   g_configurationDone = true;
 
@@ -2090,6 +2090,8 @@ try
     }
 #endif /* HAVE_EBPF */
 
+    cs->cpus = std::get<5>(local);
+
     SBind(cs->udpFD, cs->local);
     toLaunch.push_back(cs);
     g_frontends.push_back(cs);
@@ -2150,7 +2152,7 @@ try
       bindAny(cs->local.sin4.sin_family, cs->tcpFD);
     SBind(cs->tcpFD, cs->local);
     SListen(cs->tcpFD, 64);
-    warnlog("Listening on %s",cs->local.toStringWithPort());
+    warnlog("Listening on %s", cs->local.toStringWithPort());
 
     toLaunch.push_back(cs);
     g_frontends.push_back(cs);
@@ -2248,6 +2250,9 @@ try
       vinfolog("Attaching default BPF Filter to TCP DNSCrypt frontend %s", cs->local.toStringWithPort());
     }
 #endif /* HAVE_EBPF */
+
+    cs->cpus = std::get<5>(dcLocal);
+
     bindAny(cs->local.sin4.sin_family, cs->tcpFD);
     SBind(cs->tcpFD, cs->local);
     SListen(cs->tcpFD, 64);
@@ -2334,10 +2339,16 @@ try
   for(auto& cs : toLaunch) {
     if (cs->udpFD >= 0) {
       thread t1(udpClientThread, cs);
+      if (!cs->cpus.empty()) {
+        mapThreadToCPUList(t1.native_handle(), cs->cpus);
+      }
       t1.detach();
     }
     else if (cs->tcpFD >= 0) {
       thread t1(tcpAcceptorThread, cs);
+      if (!cs->cpus.empty()) {
+        mapThreadToCPUList(t1.native_handle(), cs->cpus);
+      }
       t1.detach();
     }
   }
index 01f9b7da20ea0b702a4a8c818168cab4bb8cc373..a8d56fc3359883144ee4acd7e8fc89dcaf6513a1 100644 (file)
@@ -488,6 +488,7 @@ extern QueryCount g_qcount;
 
 struct ClientState
 {
+  std::set<int> cpus;
   ComboAddress local;
 #ifdef HAVE_DNSCRYPT
   DnsCryptContext* dnscryptCtx{0};
@@ -732,7 +733,7 @@ extern GlobalStateHolder<NetmaskGroup> g_ACL;
 
 extern ComboAddress g_serverControl; // not changed during runtime
 
-extern std::vector<std::tuple<ComboAddress, bool, bool, int, std::string>> g_locals; // not changed at runtime (we hope XXX)
+extern std::vector<std::tuple<ComboAddress, bool, bool, int, std::string, std::set<int>>> g_locals; // not changed at runtime (we hope XXX)
 extern vector<ClientState*> g_frontends;
 extern std::string g_key; // in theory needs locking
 extern bool g_truncateTC;
@@ -823,7 +824,7 @@ bool fixUpResponse(char** response, uint16_t* responseLen, size_t* responseSize,
 void restoreFlags(struct dnsheader* dh, uint16_t origFlags);
 
 #ifdef HAVE_DNSCRYPT
-extern std::vector<std::tuple<ComboAddress,DnsCryptContext,bool,int, std::string>> g_dnsCryptLocals;
+extern std::vector<std::tuple<ComboAddress,DnsCryptContext,bool,int, std::string, std::set<int>>> g_dnsCryptLocals;
 
 int handleDnsCryptQuery(DnsCryptContext* ctx, char* packet, uint16_t len, std::shared_ptr<DnsCryptQuery>& query, uint16_t* decryptedQueryLen, bool tcp, std::vector<uint8_t>& response);
 bool encryptResponse(char* response, uint16_t* responseLen, size_t responseSize, bool tcp, std::shared_ptr<DnsCryptQuery> dnsCryptQuery, dnsheader** dh, dnsheader* dhCopy);
index c45ac70255570e311b1b547ef7a30f1a4c79b190..3378469738b9e158eac630e5e4cbfe9e636cbb62 100644 (file)
@@ -8,6 +8,7 @@ AC_CONFIG_HEADERS([config.h])
 AC_PROG_CC
 AC_PROG_CXX
 AC_LANG([C++])
+AC_GNU_SOURCE
 
 LT_PREREQ([2.2.2])
 LT_INIT([disable-static])
@@ -19,6 +20,7 @@ PDNS_CHECK_CLOCK_GETTIME
 
 PDNS_CHECK_OS
 PDNS_CHECK_NETWORK_LIBS
+PDNS_CHECK_PTHREAD_NP
 
 boost_required_version=1.35
 
diff --git a/pdns/dnsdistdist/m4/pdns_check_pthread_np.m4 b/pdns/dnsdistdist/m4/pdns_check_pthread_np.m4
new file mode 120000 (symlink)
index 0000000..23ef305
--- /dev/null
@@ -0,0 +1 @@
+../../../m4/pdns_check_pthread_np.m4
\ No newline at end of file