From: Remi Gacogne Date: Wed, 12 Jul 2017 20:46:43 +0000 (+0200) Subject: dnsdist: Add support for pinning listener threads to specific CPUs X-Git-Tag: rec-4.1.0-rc1~22^2~8 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f0e4dcba14eed0b5c5051e50b87018a41d7206a3;p=thirdparty%2Fpdns.git dnsdist: Add support for pinning listener threads to specific CPUs --- diff --git a/pdns/dnsdist-lua.cc b/pdns/dnsdist-lua.cc index 799c10eb1a..cd22d401e2 100644 --- a/pdns/dnsdist-lua.cc +++ b/pdns/dnsdist-lua.cc @@ -177,7 +177,7 @@ std::unordered_map>> getGenResponses(u return ret; } -void parseLocalBindVars(boost::optional vars, bool& doTCP, bool& reusePort, int& tcpFastOpenQueueSize, std::string& interface) +void parseLocalBindVars(boost::optional vars, bool& doTCP, bool& reusePort, int& tcpFastOpenQueueSize, std::string& interface, std::set& cpus) { if (vars) { if (vars->count("doTCP")) { @@ -192,6 +192,11 @@ void parseLocalBindVars(boost::optional vars, bool& doTCP, bool& re if (vars->count("interface")) { interface = boost::get((*vars)["interface"]); } + if (vars->count("cpus")) { + for (const auto cpu : boost::get>>((*vars)["cpus"])) { + cpus.insert(cpu.second); + } + } } } @@ -642,13 +647,14 @@ vector> setupLua(bool client, const std::string& confi bool reusePort = false; int tcpFastOpenQueueSize = 0; std::string interface; + std::set 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> setupLua(bool client, const std::string& confi bool reusePort = false; int tcpFastOpenQueueSize = 0; std::string interface; + std::set 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"; diff --git a/pdns/dnsdist-lua.hh b/pdns/dnsdist-lua.hh index 30a3f9a56e..ce2786bb0f 100644 --- a/pdns/dnsdist-lua.hh +++ b/pdns/dnsdist-lua.hh @@ -21,8 +21,8 @@ */ #pragma once -typedef std::unordered_map > localbind_t; -void parseLocalBindVars(boost::optional vars, bool& doTCP, bool& reusePort, int& tcpFastOpenQueueSize, std::string& interface); +typedef std::unordered_map > > > localbind_t; +void parseLocalBindVars(boost::optional vars, bool& doTCP, bool& reusePort, int& tcpFastOpenQueueSize, std::string& interface, std::set& cpus); typedef boost::variant>, std::shared_ptr, DNSName, vector > > luadnsrule_t; std::shared_ptr makeRule(const luadnsrule_t& var); diff --git a/pdns/dnsdist-lua2.cc b/pdns/dnsdist-lua2.cc index 26eeaebbaf..d896c16279 100644 --- a/pdns/dnsdist-lua2.cc +++ b/pdns/dnsdist-lua2.cc @@ -550,12 +550,13 @@ void moreLua(bool client) bool reusePort = false; int tcpFastOpenQueueSize = 0; std::string interface; + std::set 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()); diff --git a/pdns/dnsdist.cc b/pdns/dnsdist.cc index fa3293df17..8f3634a53f 100644 --- a/pdns/dnsdist.cc +++ b/pdns/dnsdist.cc @@ -78,9 +78,9 @@ bool g_syslog{true}; GlobalStateHolder g_ACL; string g_outputBuffer; -vector> g_locals; +vector>> g_locals; #ifdef HAVE_DNSCRYPT -std::vector> g_dnsCryptLocals; +std::vector>> g_dnsCryptLocals; #endif #ifdef HAVE_EBPF shared_ptr 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())); } 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())); 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(); } } diff --git a/pdns/dnsdist.hh b/pdns/dnsdist.hh index 01f9b7da20..a8d56fc335 100644 --- a/pdns/dnsdist.hh +++ b/pdns/dnsdist.hh @@ -488,6 +488,7 @@ extern QueryCount g_qcount; struct ClientState { + std::set cpus; ComboAddress local; #ifdef HAVE_DNSCRYPT DnsCryptContext* dnscryptCtx{0}; @@ -732,7 +733,7 @@ extern GlobalStateHolder g_ACL; extern ComboAddress g_serverControl; // not changed during runtime -extern std::vector> g_locals; // not changed at runtime (we hope XXX) +extern std::vector>> g_locals; // not changed at runtime (we hope XXX) extern vector 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> g_dnsCryptLocals; +extern std::vector>> g_dnsCryptLocals; int handleDnsCryptQuery(DnsCryptContext* ctx, char* packet, uint16_t len, std::shared_ptr& query, uint16_t* decryptedQueryLen, bool tcp, std::vector& response); bool encryptResponse(char* response, uint16_t* responseLen, size_t responseSize, bool tcp, std::shared_ptr dnsCryptQuery, dnsheader** dh, dnsheader* dhCopy); diff --git a/pdns/dnsdistdist/configure.ac b/pdns/dnsdistdist/configure.ac index c45ac70255..3378469738 100644 --- a/pdns/dnsdistdist/configure.ac +++ b/pdns/dnsdistdist/configure.ac @@ -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 index 0000000000..23ef305094 --- /dev/null +++ b/pdns/dnsdistdist/m4/pdns_check_pthread_np.m4 @@ -0,0 +1 @@ +../../../m4/pdns_check_pthread_np.m4 \ No newline at end of file