Merge "Fix fork deadlock issues." into main am: a5dcc7b744

Original change: https://android-review.googlesource.com/c/platform/external/jemalloc_new/+/3303655

Change-Id: I547e0f12d66e8c35d7097e534bd7cfaf76728a7a
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
diff --git a/include/jemalloc/internal/extent_externs.h b/include/jemalloc/internal/extent_externs.h
index b8a4d02..3575d61 100644
--- a/include/jemalloc/internal/extent_externs.h
+++ b/include/jemalloc/internal/extent_externs.h
@@ -69,5 +69,6 @@
     extent_hooks_t **r_extent_hooks, extent_t *a, extent_t *b);
 
 bool extent_boot(void);
+void extent_postfork_child(tsdn_t *tsdn);
 
 #endif /* JEMALLOC_INTERNAL_EXTENT_EXTERNS_H */
diff --git a/include/jemalloc/internal/private_namespace.h b/include/jemalloc/internal/private_namespace.h
index 8744f16..314f6f8 100644
--- a/include/jemalloc/internal/private_namespace.h
+++ b/include/jemalloc/internal/private_namespace.h
@@ -156,6 +156,7 @@
 #define extent_avail_remove_any JEMALLOC_N(extent_avail_remove_any)
 #define extent_avail_remove_first JEMALLOC_N(extent_avail_remove_first)
 #define extent_boot JEMALLOC_N(extent_boot)
+#define extent_postfork_child JEMALLOC_N(extent_postfork_child)
 #define extent_commit_wrapper JEMALLOC_N(extent_commit_wrapper)
 #define extent_dalloc JEMALLOC_N(extent_dalloc)
 #define extent_dalloc_gap JEMALLOC_N(extent_dalloc_gap)
diff --git a/include/jemalloc/internal/private_namespace_jet.h b/include/jemalloc/internal/private_namespace_jet.h
index c745f6e..a2c14f7 100644
--- a/include/jemalloc/internal/private_namespace_jet.h
+++ b/include/jemalloc/internal/private_namespace_jet.h
@@ -157,6 +157,7 @@
 #define extent_avail_remove_any JEMALLOC_N(extent_avail_remove_any)
 #define extent_avail_remove_first JEMALLOC_N(extent_avail_remove_first)
 #define extent_boot JEMALLOC_N(extent_boot)
+#define extent_postfork_child JEMALLOC_N(extent_postfork_child)
 #define extent_commit_wrapper JEMALLOC_N(extent_commit_wrapper)
 #define extent_dalloc JEMALLOC_N(extent_dalloc)
 #define extent_dalloc_gap JEMALLOC_N(extent_dalloc_gap)
diff --git a/src/arena.c b/src/arena.c
index 61b8083..1c25a5f 100644
--- a/src/arena.c
+++ b/src/arena.c
@@ -1944,6 +1944,9 @@
 arena_prefork1(tsdn_t *tsdn, arena_t *arena) {
 	if (config_stats) {
 		malloc_mutex_prefork(tsdn, &arena->tcache_ql_mtx);
+#ifndef JEMALLOC_ATOMIC_U64
+		malloc_mutex_prefork(tsdn, &arena->stats.mtx);
+#endif
 	}
 }
 
@@ -1991,13 +1994,16 @@
 	malloc_mutex_postfork_parent(tsdn, &arena->large_mtx);
 	base_postfork_parent(tsdn, arena->base);
 	malloc_mutex_postfork_parent(tsdn, &arena->extent_avail_mtx);
-	extents_postfork_parent(tsdn, &arena->extents_dirty);
-	extents_postfork_parent(tsdn, &arena->extents_muzzy);
 	extents_postfork_parent(tsdn, &arena->extents_retained);
+	extents_postfork_parent(tsdn, &arena->extents_muzzy);
+	extents_postfork_parent(tsdn, &arena->extents_dirty);
 	malloc_mutex_postfork_parent(tsdn, &arena->extent_grow_mtx);
 	malloc_mutex_postfork_parent(tsdn, &arena->decay_dirty.mtx);
 	malloc_mutex_postfork_parent(tsdn, &arena->decay_muzzy.mtx);
 	if (config_stats) {
+#ifndef JEMALLOC_ATOMIC_U64
+		malloc_mutex_postfork_parent(tsdn, &arena->stats.mtx);
+#endif
 		malloc_mutex_postfork_parent(tsdn, &arena->tcache_ql_mtx);
 	}
 }
@@ -2035,13 +2041,16 @@
 	malloc_mutex_postfork_child(tsdn, &arena->large_mtx);
 	base_postfork_child(tsdn, arena->base);
 	malloc_mutex_postfork_child(tsdn, &arena->extent_avail_mtx);
-	extents_postfork_child(tsdn, &arena->extents_dirty);
-	extents_postfork_child(tsdn, &arena->extents_muzzy);
 	extents_postfork_child(tsdn, &arena->extents_retained);
+	extents_postfork_child(tsdn, &arena->extents_muzzy);
+	extents_postfork_child(tsdn, &arena->extents_dirty);
 	malloc_mutex_postfork_child(tsdn, &arena->extent_grow_mtx);
 	malloc_mutex_postfork_child(tsdn, &arena->decay_dirty.mtx);
 	malloc_mutex_postfork_child(tsdn, &arena->decay_muzzy.mtx);
 	if (config_stats) {
+#ifndef JEMALLOC_ATOMIC_U64
+		malloc_mutex_postfork_child(tsdn, &arena->stats.mtx);
+#endif
 		malloc_mutex_postfork_child(tsdn, &arena->tcache_ql_mtx);
 	}
 }
diff --git a/src/extent.c b/src/extent.c
index da66a8e..1e94cf3 100644
--- a/src/extent.c
+++ b/src/extent.c
@@ -2191,3 +2191,14 @@
 
 	return false;
 }
+
+void
+extent_postfork_child(tsdn_t *tsdn) {
+	// There is the possibility that a thread is holding one of these locks
+	// when forking, but all of the other locks acquired during the prefork
+	// should prevent any corruption if this code resets the locks.
+	mutex_pool_init(&extent_mutex_pool, "extent_mutex_pool",
+	    WITNESS_RANK_EXTENT_POOL);
+
+	malloc_mutex_init(&extents_rtree.init_lock, "rtree", WITNESS_RANK_RTREE, malloc_mutex_rank_exclusive);
+}
diff --git a/src/jemalloc.c b/src/jemalloc.c
index c2efa76..0a1cad1 100644
--- a/src/jemalloc.c
+++ b/src/jemalloc.c
@@ -3322,6 +3322,7 @@
 	tsd = tsd_fetch();
 
 	witness_postfork_child(tsd_witness_tsdp_get(tsd));
+	extent_postfork_child(tsd_tsdn(tsd));
 	/* Release all mutexes, now that fork() has completed. */
 	for (i = 0, narenas = narenas_total_get(); i < narenas; i++) {
 		arena_t *arena;