Merge branch 'ondrej/remove__tsan_acquire_release-hints' into 'main'

Cleanup the __tsan_acquire/__tsan_release

See merge request isc-projects/bind9!8114
This commit is contained in:
Ondřej Surý 2023-07-28 06:59:44 +00:00
commit 0fa8d8c191
8 changed files with 8 additions and 54 deletions

View file

@ -628,7 +628,7 @@ recycle(dns_qp_t *qp) {
*/
static void
reclaim_chunks_cb(struct rcu_head *arg) {
qp_rcuctx_t *rcuctx = isc_urcu_container(arg, qp_rcuctx_t, rcu_head);
qp_rcuctx_t *rcuctx = caa_container_of(arg, qp_rcuctx_t, rcu_head);
REQUIRE(QPRCU_VALID(rcuctx));
dns_qpmulti_t *multi = rcuctx->multi;
REQUIRE(QPMULTI_VALID(multi));
@ -710,7 +710,7 @@ reclaim_chunks(dns_qpmulti_t *multi) {
}
}
isc_urcu_cleanup(rcuctx, rcu_head, reclaim_chunks_cb);
call_rcu(&rcuctx->rcu_head, reclaim_chunks_cb);
LOG_STATS("qp will reclaim %u chunks", count);
}
@ -1429,7 +1429,7 @@ dns_qp_destroy(dns_qp_t **qptp) {
static void
qpmulti_destroy_cb(struct rcu_head *arg) {
qp_rcuctx_t *rcuctx = isc_urcu_container(arg, qp_rcuctx_t, rcu_head);
qp_rcuctx_t *rcuctx = caa_container_of(arg, qp_rcuctx_t, rcu_head);
REQUIRE(QPRCU_VALID(rcuctx));
/* only nonzero for reclaim_chunks_cb() */
REQUIRE(rcuctx->count == 0);
@ -1476,7 +1476,7 @@ dns_qpmulti_destroy(dns_qpmulti_t **qpmp) {
.multi = multi,
};
isc_mem_attach(qp->mctx, &rcuctx->mctx);
isc_urcu_cleanup(rcuctx, rcu_head, qpmulti_destroy_cb);
call_rcu(&rcuctx->rcu_head, qpmulti_destroy_cb);
}
/***********************************************************************

View file

@ -2390,7 +2390,6 @@ addglue(dns_db_t *db, dns_dbversion_t *version, dns_rdataset_t *rdataset,
dns__rbtdb_freeglue(glue);
glue = old_glue;
} else if (glue != NULL) {
__tsan_release(glue);
cds_wfs_push(&rbtversion->glue_stack,
&header->wfs_node);
}
@ -2411,7 +2410,6 @@ addglue(dns_db_t *db, dns_dbversion_t *version, dns_rdataset_t *rdataset,
* zone.
*/
if (glue != (void *)-1) {
__tsan_acquire(glue);
addglue_to_message(glue, msg);
}

View file

@ -4658,7 +4658,7 @@ dns__rbtdb_freeglue(dns_glue_t *glue_list) {
static void
free_gluelist_rcu(struct rcu_head *rcu_head) {
dns_glue_t *glue = isc_urcu_container(rcu_head, dns_glue_t, rcu_head);
dns_glue_t *glue = caa_container_of(rcu_head, dns_glue_t, rcu_head);
dns__rbtdb_freeglue(glue);
}
@ -4674,7 +4674,7 @@ free_gluetable(dns_rbtdb_version_t *rbtversion) {
caa_container_of(node, dns_slabheader_t, wfs_node);
dns_glue_t *glue = rcu_xchg_pointer(&header->glue_list, NULL);
isc_urcu_cleanup(glue, rcu_head, free_gluelist_rcu);
call_rcu(&glue->rcu_head, free_gluelist_rcu);
}
rcu_read_unlock();
}

View file

@ -57,7 +57,6 @@ isc_async_run(isc_loop_t *loop, isc_job_cb cb, void *cbarg) {
* The function returns 'false' in case the queue was empty - in such
* case we need to trigger the async callback.
*/
__tsan_release(job);
if (!cds_wfcq_enqueue(&loop->async_jobs.head, &loop->async_jobs.tail,
&job->wfcq_node))
{
@ -107,7 +106,7 @@ isc__async_cb(uv_async_t *handle) {
*/
struct cds_wfcq_node *node, *next;
__cds_wfcq_for_each_blocking_safe(&jobs.head, &jobs.tail, node, next) {
isc_job_t *job = isc_urcu_container(node, isc_job_t, wfcq_node);
isc_job_t *job = caa_container_of(node, isc_job_t, wfcq_node);
job->cb(job->cbarg);

View file

@ -36,35 +36,6 @@
#pragma GCC diagnostic pop
/*
* Help thread sanitizer to understand `call_rcu()`:
*
* The `rcu_head` argument to `call_rcu()` is expected to be embedded
* in a structure defined by the caller, which is named `_rcuctx` in
* these macros. The callback function uses `caa_container_of()` to
* recover the `rcuctx` pointer from the `_rcu_head` pointer that is
* passed to the callback.
*
* We explain the ordering dependency to tsan by releasing `_rcuctx`
* pointer before `call_rcu()` and acquiring it in the callback
* funtion. We pass the outer `_rcuctx` pointer to the `__tsan_`
* barriers, because it should match a pointer that is known by tsan
* to have been returned by `malloc()`.
*/
#define isc_urcu_cleanup(ptr, member, func) \
{ \
__tsan_release(ptr); \
call_rcu(&(ptr)->member, func); \
}
#define isc_urcu_container(ptr, type, member) \
({ \
type *_ptr = caa_container_of(ptr, type, member); \
__tsan_acquire(_ptr); \
_ptr; \
})
#if defined(RCU_QSBR)
/*

View file

@ -261,19 +261,9 @@
#endif /* if __has_feature(thread_sanitizer) */
#if __SANITIZE_THREAD__
/*
* We should rather be including <sanitizer/tsan_interface.h>, but GCC 10
* header is broken, so we just make the declarations by hand.
*/
void
__tsan_acquire(void *addr);
void
__tsan_release(void *addr);
#define ISC_NO_SANITIZE_THREAD __attribute__((no_sanitize("thread")))
#else /* if __SANITIZE_THREAD__ */
#define ISC_NO_SANITIZE_THREAD
#define __tsan_acquire(addr)
#define __tsan_release(addr)
#endif /* if __SANITIZE_THREAD__ */
#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR >= 6)

View file

@ -79,7 +79,7 @@ isc_quota_release(isc_quota_t *quota) {
return;
}
isc_job_t *job = isc_urcu_container(node, isc_job_t, wfcq_node);
isc_job_t *job = caa_container_of(node, isc_job_t, wfcq_node);
job->cb(job->cbarg);
}
@ -102,7 +102,6 @@ isc_quota_acquire_cb(isc_quota_t *quota, isc_job_t *job, isc_job_cb cb,
* The cds_wfcq_enqueue() is non-blocking (no internal
* mutex involved), so it offers a slight advantage.
*/
__tsan_release(job);
cds_wfcq_enqueue(&quota->jobs.head, &quota->jobs.tail,
&job->wfcq_node);
}

View file

@ -62,7 +62,6 @@ thread_wrap(isc_threadfunc_t func, void *arg) {
.func = func,
.arg = arg,
};
__tsan_release(wrap);
return (wrap);
}
@ -81,8 +80,6 @@ thread_body(struct thread_wrap *wrap) {
CMM_ACCESS_ONCE(jemalloc_enforce_init) = malloc(1);
free(jemalloc_enforce_init);
/* Reassure Thread Sanitizer that it is safe to free the wrapper */
__tsan_acquire(wrap);
free(wrap);
ret = func(arg);