From b754c6628fc0a69441afbd449890e6b9af0d092a Mon Sep 17 00:00:00 2001 From: Tony Finch Date: Wed, 17 May 2023 10:57:16 +0100 Subject: [PATCH] Acquire qpmulti->mutex during destruction Thread sanitizer warns that parts of the qp-trie are accessed both with and without the mutex; the unlocked accesses happen during destruction, so they should be benign, but there's no harm locking anyway to convince tsan it is clean. Also, ensure .tsan-suppress and .tsan-suppress-extra are in sync. --- .tsan-suppress-extra | 2 +- lib/dns/qp.c | 12 ++++++++++-- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/.tsan-suppress-extra b/.tsan-suppress-extra index 0f598bf36b..2e31db7e26 100644 --- a/.tsan-suppress-extra +++ b/.tsan-suppress-extra @@ -3,5 +3,5 @@ called_from_lib:libfstrm.so called_from_lib:libdummyrpz.so # be more selective with liburcu race:rcu_barrier -race:rcu_memb_barrier +race:rcu_*_barrier thread:* diff --git a/lib/dns/qp.c b/lib/dns/qp.c index 10d19e1b1b..afa513f559 100644 --- a/lib/dns/qp.c +++ b/lib/dns/qp.c @@ -1431,14 +1431,22 @@ static void qpmulti_destroy_cb(struct rcu_head *arg) { qp_rcuctx_t *rcuctx = isc_urcu_container(arg, qp_rcuctx_t, rcu_head); REQUIRE(QPRCU_VALID(rcuctx)); + /* only nonzero for reclaim_chunks_cb() */ + REQUIRE(rcuctx->count == 0); + dns_qpmulti_t *multi = rcuctx->multi; REQUIRE(QPMULTI_VALID(multi)); + + /* reassure thread sanitizer */ + LOCK(&multi->mutex); + dns_qp_t *qp = &multi->writer; REQUIRE(QP_VALID(qp)); - REQUIRE(rcuctx->count == 0); - destroy_guts(qp); + + UNLOCK(&multi->mutex); + isc_mutex_destroy(&multi->mutex); isc_mem_putanddetach(&rcuctx->mctx, rcuctx, STRUCT_FLEX_SIZE(rcuctx, chunk, rcuctx->count));