summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOran Agra <oran@redislabs.com>2019-09-09 14:35:06 +0300
committerOran Agra <oran@redislabs.com>2019-10-02 15:39:44 +0300
commit2e19b941136ebd4e1d9c4766a040d3148a55d24e (patch)
treefd9b3b28c18f0fa5e9ac63f367a64b1b894d9248
parent09f99c2a925a0351985e799c106614082d6053cf (diff)
downloadredis-2e19b941136ebd4e1d9c4766a040d3148a55d24e.tar.gz
RED-31295 - redis: avoid race between dlopen and thread creation
It seeems that since I added the creation of the jemalloc thread redis sometimes fails to start with the following error: Inconsistency detected by ld.so: dl-tls.c: 493: _dl_allocate_tls_init: Assertion `listp->slotinfo[cnt].gen <= GL(dl_tls_generation)' failed! This seems to be due to a race bug in ld.so, in which TLS creation on the thread, collide with dlopen. Move the creation of BIO and jemalloc threads to after modules are loaded. plus small bugfix when trying to disable the jemalloc thread at runtime
-rw-r--r--src/server.c10
-rw-r--r--src/zmalloc.c6
2 files changed, 12 insertions, 4 deletions
diff --git a/src/server.c b/src/server.c
index fa2c7b1ee..8e99431f9 100644
--- a/src/server.c
+++ b/src/server.c
@@ -2865,6 +2865,14 @@ void initServer(void) {
scriptingInit(1);
slowlogInit();
latencyMonitorInit();
+}
+
+/* Some steps in server initialization need to be done last (after modules
+ * are loaded).
+ * Specifically, creation of threads due to a race bug in ld.so, in which
+ * Thread Local Storage initialization collides with dlopen call.
+ * see: https://sourceware.org/bugzilla/show_bug.cgi?id=19329 */
+void InitServerLast() {
bioInit();
initThreadedIO();
set_jemalloc_bg_thread(server.jemalloc_bg_thread);
@@ -4876,6 +4884,7 @@ int main(int argc, char **argv) {
#endif
moduleLoadFromQueue();
ACLLoadUsersAtStartup();
+ InitServerLast();
loadDataFromDisk();
if (server.cluster_enabled) {
if (verifyClusterConfigWithData() == C_ERR) {
@@ -4890,6 +4899,7 @@ int main(int argc, char **argv) {
if (server.sofd > 0)
serverLog(LL_NOTICE,"The server is now ready to accept connections at %s", server.unixsocket);
} else {
+ InitServerLast();
sentinelIsRunning();
}
diff --git a/src/zmalloc.c b/src/zmalloc.c
index 58896a727..437f43b64 100644
--- a/src/zmalloc.c
+++ b/src/zmalloc.c
@@ -332,10 +332,8 @@ int zmalloc_get_allocator_info(size_t *allocated,
void set_jemalloc_bg_thread(int enable) {
/* let jemalloc do purging asynchronously, required when there's no traffic
* after flushdb */
- if (enable) {
- char val = 1;
- je_mallctl("background_thread", NULL, 0, &val, 1);
- }
+ char val = !!enable;
+ je_mallctl("background_thread", NULL, 0, &val, 1);
}
int jemalloc_purge() {