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;