The following TSAN report about accessing the mgr timers (mgr->init,
mgr->idle, mgr->keepalive and mgr->advertised) has been fixed in this
commit:
==================
WARNING: ThreadSanitizer: data race (pid=2746)
Read of size 4 at 0x7b440008a948 by thread T18:
#0 isc__nm_tcpdns_read /home/ondrej/Projects/bind9/lib/isc/netmgr/tcpdns.c:849:25 (libisc.so.1706+0x2ba0f)
#1 isc_nm_read /home/ondrej/Projects/bind9/lib/isc/netmgr/netmgr.c:1679:3 (libisc.so.1706+0x22258)
#2 tcpdns_connect_connect_cb /home/ondrej/Projects/bind9/lib/isc/tests/tcpdns_test.c:363:2 (tcpdns_test+0x4bc5fb)
#3 isc__nm_async_connectcb /home/ondrej/Projects/bind9/lib/isc/netmgr/netmgr.c:1816:2 (libisc.so.1706+0x228c9)
#4 isc__nm_connectcb /home/ondrej/Projects/bind9/lib/isc/netmgr/netmgr.c:1791:3 (libisc.so.1706+0x22713)
#5 tcpdns_connect_cb /home/ondrej/Projects/bind9/lib/isc/netmgr/tcpdns.c:343:2 (libisc.so.1706+0x2d89d)
#6 uv__stream_connect /home/ondrej/Projects/tsan/libuv/src/unix/stream.c:1381:5 (libuv.so.1+0x27c18)
#7 uv__stream_io /home/ondrej/Projects/tsan/libuv/src/unix/stream.c:1298:5 (libuv.so.1+0x25977)
#8 uv__io_poll /home/ondrej/Projects/tsan/libuv/src/unix/linux-core.c:462:11 (libuv.so.1+0x2e795)
#9 uv_run /home/ondrej/Projects/tsan/libuv/src/unix/core.c:385:5 (libuv.so.1+0x158ec)
#10 nm_thread /home/ondrej/Projects/bind9/lib/isc/netmgr/netmgr.c:530:11 (libisc.so.1706+0x1c94a)
Previous write of size 4 at 0x7b440008a948 by main thread:
#0 isc_nm_settimeouts /home/ondrej/Projects/bind9/lib/isc/netmgr/netmgr.c:490:12 (libisc.so.1706+0x1dda5)
#1 tcpdns_recv_two /home/ondrej/Projects/bind9/lib/isc/tests/tcpdns_test.c:601:2 (tcpdns_test+0x4bad0e)
#2 cmocka_run_one_test_or_fixture <null> (libcmocka.so.0+0x70be)
#3 __libc_start_main /build/glibc-vjB4T1/glibc-2.28/csu/../csu/libc-start.c:308:16 (libc.so.6+0x2409a)
Location is heap block of size 281 at 0x7b440008a840 allocated by main thread:
#0 malloc <null> (tcpdns_test+0x42864b)
#1 default_memalloc /home/ondrej/Projects/bind9/lib/isc/mem.c:713:8 (libisc.so.1706+0x6d261)
#2 mem_get /home/ondrej/Projects/bind9/lib/isc/mem.c:622:8 (libisc.so.1706+0x69b9c)
#3 isc___mem_get /home/ondrej/Projects/bind9/lib/isc/mem.c:1044:9 (libisc.so.1706+0x6d379)
#4 isc__mem_get /home/ondrej/Projects/bind9/lib/isc/mem.c:2432:10 (libisc.so.1706+0x6889e)
#5 isc_nm_start /home/ondrej/Projects/bind9/lib/isc/netmgr/netmgr.c:203:8 (libisc.so.1706+0x1c219)
#6 nm_setup /home/ondrej/Projects/bind9/lib/isc/tests/tcpdns_test.c:244:11 (tcpdns_test+0x4baaa4)
#7 cmocka_run_one_test_or_fixture <null> (libcmocka.so.0+0x70fd)
#8 __libc_start_main /build/glibc-vjB4T1/glibc-2.28/csu/../csu/libc-start.c:308:16 (libc.so.6+0x2409a)
Thread T18 'isc-net-0000' (tid=3513, running) created by main thread at:
#0 pthread_create <null> (tcpdns_test+0x429e7b)
#1 isc_thread_create /home/ondrej/Projects/bind9/lib/isc/pthreads/thread.c:73:8 (libisc.so.1706+0x8476a)
#2 isc_nm_start /home/ondrej/Projects/bind9/lib/isc/netmgr/netmgr.c:271:3 (libisc.so.1706+0x1c66a)
#3 nm_setup /home/ondrej/Projects/bind9/lib/isc/tests/tcpdns_test.c:244:11 (tcpdns_test+0x4baaa4)
#4 cmocka_run_one_test_or_fixture <null> (libcmocka.so.0+0x70fd)
#5 __libc_start_main /build/glibc-vjB4T1/glibc-2.28/csu/../csu/libc-start.c:308:16 (libc.so.6+0x2409a)
SUMMARY: ThreadSanitizer: data race /home/ondrej/Projects/bind9/lib/isc/netmgr/tcpdns.c:849:25 in isc__nm_tcpdns_read
==================
ThreadSanitizer: reported 1 warnings
(cherry picked from commit
2e1dd56d0ba70c6434a1afce0a5b785244cafd6a)
lex.@O@ lfsr.@O@ lib.@O@ log.@O@ \
md.@O@ mem.@O@ mutexblock.@O@ \
netmgr/netmgr.@O@ netmgr/tcp.@O@ netmgr/udp.@O@ \
- netmgr/tcpdns.@O@ netmgr/tlsdns.@O@ netmgr/uverr2result.@O@ netmgr/uv-compat.@O@ \
+ netmgr/tcpdns.@O@ netmgr/tls.@O@ netmgr/tlsdns.@O@ netmgr/uverr2result.@O@ netmgr/uv-compat.@O@ \
netaddr.@O@ netscope.@O@ nonce.@O@ openssl_shim.@O@ pool.@O@ \
parseint.@O@ portset.@O@ queue.@O@ quota.@O@ \
radix.@O@ random.@O@ ratelimiter.@O@ \
CWARNINGS =
# Alphabetically
-OBJS = netmgr.@O@ tcp.@O@ udp.@O@ tcpdns.@O@ tlsdns.@O@ uverr2result.@O@ uv-compat.@O@
+OBJS = netmgr.@O@ tcp.@O@ udp.@O@ tcpdns.@O@ tls.@O@ tlsdns.@O@ uverr2result.@O@ uv-compat.@O@
# Alphabetically
-SRCS = netmgr.c tcp.c udp.c tcpdns.c tlsdns.c uverr2result.c uv-compat.c
+SRCS = netmgr.c tcp.c udp.c tcpdns.c tls.c tlsdns.c uverr2result.c uv-compat.c
TARGETS = ${OBJS}
* milliseconds so they can be used directly with the libuv timer,
* but they are configured in tenths of seconds.
*/
- uint32_t init;
- uint32_t idle;
- uint32_t keepalive;
- uint32_t advertised;
+ atomic_uint_fast32_t init;
+ atomic_uint_fast32_t idle;
+ atomic_uint_fast32_t keepalive;
+ atomic_uint_fast32_t advertised;
#ifdef NETMGR_TRACE
ISC_LIST(isc_nmsocket_t) active_sockets;
* Default TCP timeout values.
* May be updated by isc_nm_tcptimeouts().
*/
- mgr->init = 30000;
- mgr->idle = 30000;
- mgr->keepalive = 30000;
- mgr->advertised = 30000;
+ atomic_init(&mgr->init, 30000);
+ atomic_init(&mgr->idle, 30000);
+ atomic_init(&mgr->keepalive, 30000);
+ atomic_init(&mgr->advertised, 30000);
isc_mutex_init(&mgr->reqlock);
isc_mempool_create(mgr->mctx, sizeof(isc__nm_uvreq_t), &mgr->reqpool);
uint32_t keepalive, uint32_t advertised) {
REQUIRE(VALID_NM(mgr));
- mgr->init = init * 100;
- mgr->idle = idle * 100;
- mgr->keepalive = keepalive * 100;
- mgr->advertised = advertised * 100;
+ atomic_store(&mgr->init, init * 100);
+ atomic_store(&mgr->idle, idle * 100);
+ atomic_store(&mgr->keepalive, keepalive * 100);
+ atomic_store(&mgr->advertised, advertised * 100);
}
void
REQUIRE(VALID_NM(mgr));
if (initial != NULL) {
- *initial = mgr->init / 100;
+ *initial = atomic_load(&mgr->init) / 100;
}
if (idle != NULL) {
- *idle = mgr->idle / 100;
+ *idle = atomic_load(&mgr->idle) / 100;
}
if (keepalive != NULL) {
- *keepalive = mgr->keepalive / 100;
+ *keepalive = atomic_load(&mgr->keepalive) / 100;
}
if (advertised != NULL) {
- *advertised = mgr->advertised / 100;
+ *advertised = atomic_load(&mgr->advertised) / 100;
}
}
sock->recv_cbarg = cbarg;
sock->recv_read = true;
if (sock->read_timeout == 0) {
- sock->read_timeout = (atomic_load(&sock->keepalive)
- ? sock->mgr->keepalive
- : sock->mgr->idle);
+ sock->read_timeout =
+ (atomic_load(&sock->keepalive)
+ ? atomic_load(&sock->mgr->keepalive)
+ : atomic_load(&sock->mgr->idle));
}
ievent = isc__nm_get_netievent_tcpstartread(sock->mgr, sock);
req->uvbuf.len = nread;
if (!atomic_load(&sock->client)) {
- sock->read_timeout = (atomic_load(&sock->keepalive)
- ? sock->mgr->keepalive
- : sock->mgr->idle);
+ sock->read_timeout =
+ (atomic_load(&sock->keepalive)
+ ? atomic_load(&sock->mgr->keepalive)
+ : atomic_load(&sock->mgr->idle));
}
isc__nm_readcb(sock, req, ISC_R_SUCCESS);
isc__nm_incstats(csock->mgr, csock->statsindex[STATID_ACCEPT]);
- csock->read_timeout = csock->mgr->init;
+ csock->read_timeout = atomic_load(&csock->mgr->init);
atomic_fetch_add(&ssock->parent->active_child_connections, 1);
sock->recv_cbarg = cbarg;
sock->recv_read = true;
if (sock->read_timeout == 0) {
- sock->read_timeout = (atomic_load(&sock->keepalive)
- ? sock->mgr->keepalive
- : sock->mgr->idle);
+ sock->read_timeout =
+ (atomic_load(&sock->keepalive)
+ ? atomic_load(&sock->mgr->keepalive)
+ : atomic_load(&sock->mgr->idle));
}
ievent = isc__nm_get_netievent_tcpdnsread(sock->mgr, sock);
sock->buf_len += len;
if (!atomic_load(&sock->client)) {
- sock->read_timeout = sock->mgr->idle;
+ sock->read_timeout = atomic_load(&sock->mgr->idle);
}
process_sock_buffer(sock);
isc__nm_incstats(csock->mgr, csock->statsindex[STATID_ACCEPT]);
- csock->read_timeout = csock->mgr->init;
+ csock->read_timeout = atomic_load(&csock->mgr->init);
csock->closehandle_cb = resume_processing;
* reads.
*/
csock->read_timeout = (atomic_load(&csock->keepalive)
- ? csock->mgr->keepalive
- : csock->mgr->idle);
+ ? atomic_load(&csock->mgr->keepalive)
+ : atomic_load(&csock->mgr->idle));
isc_nmhandle_detach(&handle);
isc__nmsocket_attach(tlslistensock, &tlssock->listener);
isc_nmhandle_attach(handle, &tlssock->outerhandle);
tlssock->peer = handle->sock->peer;
- tlssock->read_timeout = handle->sock->mgr->init;
+ tlssock->read_timeout = atomic_load(&handle->sock->mgr->init);
tlssock->tid = isc_nm_tid();
tlssock->tls.server = true;
tlssock->tls.state = TLS_INIT;
isc_nmhandle_attach(handle, &dnssock->outerhandle);
dnssock->peer = handle->sock->peer;
- dnssock->read_timeout = handle->sock->mgr->init;
+ dnssock->read_timeout = atomic_load(&handle->sock->mgr->init);
dnssock->tid = isc_nm_tid();
dnssock->closehandle_cb = resume_processing;
dnssock->buf_len += len;
dnssock->read_timeout = (atomic_load(&dnssock->keepalive)
- ? dnssock->mgr->keepalive
- : dnssock->mgr->idle);
+ ? atomic_load(&dnssock->mgr->keepalive)
+ : atomic_load(&dnssock->mgr->idle));
do {
isc_result_t result;
isc_nmhandle_attach(handle, &dnssock->outerhandle);
dnssock->peer = handle->sock->peer;
- dnssock->read_timeout = handle->sock->mgr->init;
+ dnssock->read_timeout = atomic_load(&handle->sock->mgr->init);
dnssock->tid = isc_nm_tid();
atomic_init(&dnssock->client, true);
sock->recv_cbarg = cbarg;
sock->read_timeout = (atomic_load(&sock->keepalive)
- ? sock->mgr->keepalive
- : sock->mgr->idle);
+ ? atomic_load(&sock->mgr->keepalive)
+ : atomic_load(&sock->mgr->idle));
/*
* Add a reference to the handle to keep it from being freed by