From f240cba1dbadd0649f523953cd53fada508d82b5 Mon Sep 17 00:00:00 2001
From: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Date: Fri, 3 Jul 2026 09:53:52 -0400
Subject: [PATCH] Fix: call-rcu leaks mutexes on FreeBSD

Call rcu workers leak mutexes on FreeBSD. pthread_mutex_init without
matching destroy is effectless on Linux, but leaks memory on FreeBSD.

Within call_rcu_thread(), the internal mutex is never used because this
is a stack-local wfcq head/tail, so change the cbs_tmp_head type to
struct __cds_wfcq_head (no mutex), and initialize it with
__cds_wfcq_init which does not require any matching destroy.

Add the missing cds_wfcq_destroy in _call_rcu_data_free.

Fixes: #1442
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Change-Id: I4de4eb3b3b56083181141fcac0f2605607e73c44
---
 src/urcu-call-rcu-impl.h | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/src/urcu-call-rcu-impl.h b/src/urcu-call-rcu-impl.h
index 6db4ec01..0dfa53fe 100644
--- a/src/urcu-call-rcu-impl.h
+++ b/src/urcu-call-rcu-impl.h
@@ -354,7 +354,7 @@ static void *call_rcu_thread(void *arg)
 		cmm_smp_mb();
 	}
 	for (;;) {
-		struct cds_wfcq_head cbs_tmp_head;
+		struct __cds_wfcq_head cbs_tmp_head;
 		struct cds_wfcq_tail cbs_tmp_tail;
 		struct cds_wfcq_node *cbs, *cbs_tmp_n;
 		enum cds_wfcq_ret splice_ret;
@@ -379,7 +379,7 @@ static void *call_rcu_thread(void *arg)
 			rcu_register_thread();
 		}
 
-		cds_wfcq_init(&cbs_tmp_head, &cbs_tmp_tail);
+		__cds_wfcq_init(&cbs_tmp_head, &cbs_tmp_tail);
 		splice_ret = __cds_wfcq_splice_blocking(&cbs_tmp_head,
 			&cbs_tmp_tail, &crdp->cbs_head, &crdp->cbs_tail);
 		urcu_posix_assert(splice_ret != CDS_WFCQ_RET_WOULDBLOCK);
@@ -817,6 +817,7 @@ void _call_rcu_data_free(struct call_rcu_data *crdp, unsigned int flags)
 		if (ret)
 			urcu_die(ret);
 	}
+	cds_wfcq_destroy(&crdp->cbs_head, &crdp->cbs_tail);
 	free(crdp);
 }
 
