diff --git a/sysdeps/pthread/Makefile b/sysdeps/pthread/Makefile
index 48dba717a1..4a21abdc38 100644
--- a/sysdeps/pthread/Makefile
+++ b/sysdeps/pthread/Makefile
@@ -150,15 +150,17 @@ tests += tst-cancelx2 tst-cancelx3 tst-cancelx6 tst-cancelx8 tst-cancelx9 \
 	 tst-cleanupx0 tst-cleanupx1 tst-cleanupx2 tst-cleanupx3
 
 ifeq ($(build-shared),yes)
-tests += tst-atfork2 tst-pt-tls4 tst-_res1 tst-fini1
+tests += tst-atfork2 tst-pt-tls4 tst-_res1 tst-fini1 tst-create1
 tests-nolibpthread += tst-fini1
 endif
 
 modules-names += tst-atfork2mod tst-tls4moda tst-tls4modb \
-		 tst-_res1mod1 tst-_res1mod2 tst-fini1mod
+		 tst-_res1mod1 tst-_res1mod2 tst-fini1mod \
+		 tst-create1mod
 test-modules = $(addprefix $(objpfx),$(addsuffix .so,$(modules-names)))
 
 tst-atfork2mod.so-no-z-defs = yes
+tst-create1mod.so-no-z-defs = yes
 
 ifeq ($(build-shared),yes)
 # Build all the modules even when not actually running test programs.
@@ -277,4 +279,8 @@ LDFLAGS-tst-join7mod.so = -Wl,-soname,tst-join7mod.so
 
 CFLAGS-tst-unwind-thread.c += -funwind-tables
 
+LDFLAGS-tst-create1 = -Wl,-export-dynamic
+$(objpfx)tst-create1: $(shared-thread-library)
+$(objpfx)tst-create1.out: $(objpfx)tst-create1mod.so
+
 endif
diff --git a/sysdeps/pthread/tst-create1.c b/sysdeps/pthread/tst-create1.c
new file mode 100644
index 0000000000..44d1c0fc34
--- /dev/null
+++ b/sysdeps/pthread/tst-create1.c
@@ -0,0 +1,120 @@
+/* Verify that pthread_create does not deadlock when ctors take locks.
+   Copyright (C) 2021 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <https://www.gnu.org/licenses/>.  */
+
+#include <stdio.h>
+#include <support/xdlfcn.h>
+#include <support/xthread.h>
+
+/*
+Check if ctor and pthread_create deadlocks in
+
+thread 1: dlopen -> ctor -> lock(user_lock)
+thread 2: lock(user_lock) -> pthread_create
+
+or in
+
+thread 1: dlclose -> dtor -> lock(user_lock)
+thread 2: lock(user_lock) -> pthread_create
+*/
+
+static pthread_barrier_t bar_ctor;
+static pthread_barrier_t bar_dtor;
+static pthread_mutex_t user_lock = PTHREAD_MUTEX_INITIALIZER;
+
+void
+ctor (void)
+{
+  xpthread_barrier_wait (&bar_ctor);
+  dprintf (1, "thread 1: in ctor: started.\n");
+  xpthread_mutex_lock (&user_lock);
+  dprintf (1, "thread 1: in ctor: locked user_lock.\n");
+  xpthread_mutex_unlock (&user_lock);
+  dprintf (1, "thread 1: in ctor: unlocked user_lock.\n");
+  dprintf (1, "thread 1: in ctor: done.\n");
+}
+
+void
+dtor (void)
+{
+  xpthread_barrier_wait (&bar_dtor);
+  dprintf (1, "thread 1: in dtor: started.\n");
+  xpthread_mutex_lock (&user_lock);
+  dprintf (1, "thread 1: in dtor: locked user_lock.\n");
+  xpthread_mutex_unlock (&user_lock);
+  dprintf (1, "thread 1: in dtor: unlocked user_lock.\n");
+  dprintf (1, "thread 1: in dtor: done.\n");
+}
+
+static void *
+thread3 (void *a)
+{
+  dprintf (1, "thread 3: started.\n");
+  dprintf (1, "thread 3: done.\n");
+  return 0;
+}
+
+static void *
+thread2 (void *a)
+{
+  pthread_t t3;
+  dprintf (1, "thread 2: started.\n");
+
+  xpthread_mutex_lock (&user_lock);
+  dprintf (1, "thread 2: locked user_lock.\n");
+  xpthread_barrier_wait (&bar_ctor);
+  t3 = xpthread_create (0, thread3, 0);
+  xpthread_mutex_unlock (&user_lock);
+  dprintf (1, "thread 2: unlocked user_lock.\n");
+  xpthread_join (t3);
+
+  xpthread_mutex_lock (&user_lock);
+  dprintf (1, "thread 2: locked user_lock.\n");
+  xpthread_barrier_wait (&bar_dtor);
+  t3 = xpthread_create (0, thread3, 0);
+  xpthread_mutex_unlock (&user_lock);
+  dprintf (1, "thread 2: unlocked user_lock.\n");
+  xpthread_join (t3);
+
+  dprintf (1, "thread 2: done.\n");
+  return 0;
+}
+
+static void
+thread1 (void)
+{
+  dprintf (1, "thread 1: started.\n");
+  xpthread_barrier_init (&bar_ctor, NULL, 2);
+  xpthread_barrier_init (&bar_dtor, NULL, 2);
+  pthread_t t2 = xpthread_create (0, thread2, 0);
+  void *p = xdlopen ("tst-create1mod.so", RTLD_NOW | RTLD_GLOBAL);
+  dprintf (1, "thread 1: dlopen done.\n");
+  xdlclose (p);
+  dprintf (1, "thread 1: dlclose done.\n");
+  xpthread_join (t2);
+  dprintf (1, "thread 1: done.\n");
+}
+
+int
+do_test (void)
+{
+  thread1 ();
+  return 0;
+}
+
+#define TEST_FUNCTION do_test ()
+#include "../test-skeleton.c"
diff --git a/sysdeps/pthread/tst-create1mod.c b/sysdeps/pthread/tst-create1mod.c
new file mode 100644
index 0000000000..62c9006961
--- /dev/null
+++ b/sysdeps/pthread/tst-create1mod.c
@@ -0,0 +1,41 @@
+/* Verify that pthread_create does not deadlock when ctors take locks.
+   Copyright (C) 2021 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <https://www.gnu.org/licenses/>.  */
+
+#include <stdio.h>
+
+/* Require TLS setup for the module.  */
+__thread int tlsvar;
+
+void ctor (void);
+void dtor (void);
+
+static void __attribute__ ((constructor))
+do_init (void)
+{
+  dprintf (1, "constructor started: %d.\n", tlsvar++);
+  ctor ();
+  dprintf (1, "constructor done: %d.\n", tlsvar++);
+}
+
+static void __attribute__ ((destructor))
+do_end (void)
+{
+  dprintf (1, "destructor started: %d.\n", tlsvar++);
+  dtor ();
+  dprintf (1, "destructor done: %d.\n", tlsvar++);
+}
