Fix deadlock in the arenas.purge mallctl.

Fix deadlock in the arenas.purge mallctl due to recursive mutex
acquisition.
This commit is contained in:
Jason Evans 2012-11-03 21:18:28 -07:00
parent 12efefb195
commit 34457f5144

View File

@ -113,7 +113,7 @@ CTL_PROTO(opt_prof_final)
CTL_PROTO(opt_prof_leak) CTL_PROTO(opt_prof_leak)
CTL_PROTO(opt_prof_accum) CTL_PROTO(opt_prof_accum)
CTL_PROTO(arena_i_purge) CTL_PROTO(arena_i_purge)
static int arena_purge(unsigned arena_ind); static void arena_purge(unsigned arena_ind);
CTL_PROTO(arena_i_dss) CTL_PROTO(arena_i_dss)
INDEX_PROTO(arena_i) INDEX_PROTO(arena_i)
CTL_PROTO(arenas_bin_i_size) CTL_PROTO(arenas_bin_i_size)
@ -1274,13 +1274,10 @@ CTL_RO_NL_CGEN(config_prof, opt_prof_accum, opt_prof_accum, bool)
/******************************************************************************/ /******************************************************************************/
static int /* ctl_mutex must be held during execution of this function. */
static void
arena_purge(unsigned arena_ind) arena_purge(unsigned arena_ind)
{ {
int ret;
malloc_mutex_lock(&ctl_mtx);
{
VARIABLE_ARRAY(arena_t *, tarenas, ctl_stats.narenas); VARIABLE_ARRAY(arena_t *, tarenas, ctl_stats.narenas);
malloc_mutex_lock(&arenas_lock); malloc_mutex_lock(&arenas_lock);
@ -1298,11 +1295,6 @@ arena_purge(unsigned arena_ind)
if (tarenas[arena_ind] != NULL) if (tarenas[arena_ind] != NULL)
arena_purge_all(tarenas[arena_ind]); arena_purge_all(tarenas[arena_ind]);
} }
}
ret = 0;
malloc_mutex_unlock(&ctl_mtx);
return (ret);
} }
static int static int
@ -1313,8 +1305,11 @@ arena_i_purge_ctl(const size_t *mib, size_t miblen, void *oldp, size_t *oldlenp,
READONLY(); READONLY();
WRITEONLY(); WRITEONLY();
ret = arena_purge(mib[1]); malloc_mutex_lock(&ctl_mtx);
arena_purge(mib[1]);
malloc_mutex_unlock(&ctl_mtx);
ret = 0;
label_return: label_return:
return (ret); return (ret);
} }
@ -1483,7 +1478,8 @@ arenas_purge_ctl(const size_t *mib, size_t miblen, void *oldp, size_t *oldlenp,
else { else {
if (arena_ind == UINT_MAX) if (arena_ind == UINT_MAX)
arena_ind = ctl_stats.narenas; arena_ind = ctl_stats.narenas;
ret = arena_purge(arena_ind); arena_purge(arena_ind);
ret = 0;
} }
label_return: label_return: