From: Remi Gacogne Date: Wed, 21 Apr 2021 12:20:52 +0000 (+0200) Subject: dnsdist: Make the backend queryLoad and dropRate values atomic X-Git-Tag: dnsdist-1.6.0-rc2~10^2 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=refs%2Fpull%2F10323%2Fhead;p=thirdparty%2Fpdns.git dnsdist: Make the backend queryLoad and dropRate values atomic So that there is no race when these vaues are read by the SNMP or web threads and updated by the health check thread at the same time. Reported by Thread Sanitizer: WARNING: ThreadSanitizer: data race (pid=11167) Write of size 8 at 0x7b7400002558 by thread T18: #0 healthChecksThread() /opt/project/pdns/dnsdistdist/dnsdist.cc:1712:22 (dnsdist+0xf2a4a2) #1 void std::__invoke_impl(std::__invoke_other, void (*&&)()) /usr/bin/../lib/gcc/x86_64-linux-gnu/8/../../../../include/c++/8/bits/invoke.h:60:14 (dnsdist+0xf40ea2) #2 std::__invoke_result::type std::__invoke(void (*&&)()) /usr/bin/../lib/gcc/x86_64-linux-gnu/8/../../../../include/c++/8/bits/invoke.h:95:14 (dnsdist+0xf40e0d) #3 decltype(std::__invoke(_S_declval<0ul>())) std::thread::_Invoker >::_M_invoke<0ul>(std::_Index_tuple<0ul>) /usr/bin/../lib/gcc/x86_64-linux-gnu/8/../../../../include/c++/8/thread:244:13 (dnsdist+0xf40dd5) #4 std::thread::_Invoker >::operator()() /usr/bin/../lib/gcc/x86_64-linux-gnu/8/../../../../include/c++/8/thread:253:11 (dnsdist+0xf40d95) #5 std::thread::_State_impl > >::_M_run() /usr/bin/../lib/gcc/x86_64-linux-gnu/8/../../../../include/c++/8/thread:196:13 (dnsdist+0xf40c29) #6 (libstdc++.so.6+0xbbb2e) Previous read of size 8 at 0x7b7400002558 by thread T2: #0 backendStatTable_handler(netsnmp_mib_handler_s*, netsnmp_handler_registration_s*, netsnmp_agent_request_info_s*, netsnmp_request_info_s*) /opt/project/pdns/dnsdistdist/dnsdist-snmp.cc:356:62 (dnsdist+0xeccf98) #1 netsnmp_call_next_handler (libnetsnmpagent.so.30+0x2a0cc) #2 SNMPAgent::handleSNMPQueryCB(int, boost::any&) /opt/project/pdns/dnsdistdist/snmp-agent.cc:96:13 (dnsdist+0xfb0847) #3 boost::detail::function::void_function_invoker2::invoke(boost::detail::function::function_buffer&, int, boost::any&) /usr/include/boost/function/function_template.hpp:118:11 (dnsdist+0x8937d8) #4 boost::function2::operator()(int, boost::any&) const /usr/include/boost/function/function_template.hpp:768:14 (dnsdist+0xf9d56c) #5 EpollFDMultiplexer::run(timeval*, int) /opt/project/pdns/dnsdistdist/epollmplexer.cc:176:7 (dnsdist+0xfd041b) #6 SNMPAgent::worker() /opt/project/pdns/dnsdistdist/snmp-agent.cc:141:24 (dnsdist+0xfb0b6f) #7 void std::__invoke_impl(std::__invoke_memfun_deref, void (SNMPAgent::*&&)(), SNMPAgent*&&) /usr/bin/../lib/gcc/x86_64-linux-gnu/8/../../../../include/c++/8/bits/invoke.h:73:14 (dnsdist+0xf344c9) #8 std::__invoke_result::type std::__invoke(void (SNMPAgent::*&&)(), SNMPAgent*&&) /usr/bin/../lib/gcc/x86_64-linux-gnu/8/../../../../include/c++/8/bits/invoke.h:95:14 (dnsdist+0xf343c1) #9 decltype(std::__invoke(_S_declval<0ul>(), _S_declval<1ul>())) std::thread::_Invoker >::_M_invoke<0ul, 1ul>(std::_Index_tuple<0ul, 1ul>) /usr/bin/../lib/gcc/x86_64-linux-gnu/8/../../../../include/c++/8/thread:244:13 (dnsdist+0xf3436e) #10 std::thread::_Invoker >::operator()() /usr/bin/../lib/gcc/x86_64-linux-gnu/8/../../../../include/c++/8/thread:253:11 (dnsdist+0xf34315) #11 std::thread::_State_impl > >::_M_run() /usr/bin/../lib/gcc/x86_64-linux-gnu/8/../../../../include/c++/8/thread:196:13 (dnsdist+0xf34079) #12 (libstdc++.so.6+0xbbb2e) --- diff --git a/pdns/dnsdist.hh b/pdns/dnsdist.hh index f89734d2b3..e2448fab46 100644 --- a/pdns/dnsdist.hh +++ b/pdns/dnsdist.hh @@ -944,8 +944,8 @@ struct DownstreamState size_t socketsOffset{0}; size_t d_maxInFlightQueriesPerConn{1}; size_t d_tcpConcurrentConnectionsLimit{0}; - double queryLoad{0.0}; - double dropRate{0.0}; + pdns::stat_t_trait queryLoad{0.0}; + pdns::stat_t_trait dropRate{0.0}; double latencyUsec{0.0}; int order{1}; int weight{1};