58 lines
1.9 KiB
Diff
58 lines
1.9 KiB
Diff
|
|
From 11dcfc5e044f55941ffd3f1155bbda51ed05aff7 Mon Sep 17 00:00:00 2001
|
||
|
|
From: hewenliang <hewenliang4@huawei.com>
|
||
|
|
Date: Mon, 12 Aug 2019 22:30:20 +0000
|
||
|
|
Subject: [PATCH] urcu: fix deadlock issue using SIG_RCU
|
||
|
|
|
||
|
|
reason:
|
||
|
|
1.use a seperate thread(cds_lfht_workqueue) to handle hash table auto resize,
|
||
|
|
and this thread block all signal at initialization.
|
||
|
|
2.While in urcu-signal flavor, call_rcu_thread will send SIGRCU signal to all
|
||
|
|
the registed thread to make them do cmm_smp_mb.
|
||
|
|
3.Based on above, call_rcu_thread and workqueue thread will trapped into a dead
|
||
|
|
loop: where call_rcu_thread hold the rcu_registry_lock to waiting all the registed
|
||
|
|
thread to do cmm_smp_mb, while workqueue thread nerver do cmm_smp_mb and waiting to
|
||
|
|
get rcu_registry_lock to unregiter from rcu.
|
||
|
|
so we should not block SIGRCU in workqueue thread to avoid the dead lock.
|
||
|
|
|
||
|
|
Signed-off-by: hewenliang <hewenliang4@huawei.com>
|
||
|
|
---
|
||
|
|
src/rculfhash.c | 8 +++++++-
|
||
|
|
1 file changed, 7 insertions(+), 1 deletion(-)
|
||
|
|
|
||
|
|
diff --git a/src/rculfhash.c b/src/rculfhash.c
|
||
|
|
index fed33e4..fc3d610 100644
|
||
|
|
--- a/src/rculfhash.c
|
||
|
|
+++ b/src/rculfhash.c
|
||
|
|
@@ -273,6 +273,7 @@
|
||
|
|
#include <urcu/uatomic.h>
|
||
|
|
#include <urcu/compiler.h>
|
||
|
|
#include <urcu/rculfhash.h>
|
||
|
|
+#include <urcu.h>
|
||
|
|
#include <rculfhash-internal.h>
|
||
|
|
#include <stdio.h>
|
||
|
|
#include <pthread.h>
|
||
|
|
@@ -2112,7 +2113,7 @@ static void cds_lfht_worker_init(struct urcu_workqueue *workqueue,
|
||
|
|
{
|
||
|
|
int ret;
|
||
|
|
sigset_t mask;
|
||
|
|
-
|
||
|
|
+ sigset_t set;
|
||
|
|
/* Block signal for entire process, so only our thread processes it. */
|
||
|
|
ret = sigfillset(&mask);
|
||
|
|
if (ret)
|
||
|
|
@@ -2120,6 +2121,11 @@ static void cds_lfht_worker_init(struct urcu_workqueue *workqueue,
|
||
|
|
ret = pthread_sigmask(SIG_BLOCK, &mask, NULL);
|
||
|
|
if (ret)
|
||
|
|
urcu_die(ret);
|
||
|
|
+ sigemptyset(&set);
|
||
|
|
+ sigaddset(&set, SIGRCU);
|
||
|
|
+ ret = pthread_sigmask(SIG_UNBLOCK, &set, NULL);
|
||
|
|
+ if (ret)
|
||
|
|
+ urcu_die(ret);
|
||
|
|
}
|
||
|
|
|
||
|
|
static void cds_lfht_init_worker(const struct rcu_flavor_struct *flavor)
|
||
|
|
--
|
||
|
|
2.19.1
|
||
|
|
|