Skip to content
This repository was archived by the owner on Feb 5, 2019. It is now read-only.

Commit 34457f5

Browse files
author
Jason Evans
committed
Fix deadlock in the arenas.purge mallctl.
Fix deadlock in the arenas.purge mallctl due to recursive mutex acquisition.
1 parent 12efefb commit 34457f5

File tree

1 file changed

+22
-26
lines changed

1 file changed

+22
-26
lines changed

src/ctl.c

Lines changed: 22 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ CTL_PROTO(opt_prof_final)
113113
CTL_PROTO(opt_prof_leak)
114114
CTL_PROTO(opt_prof_accum)
115115
CTL_PROTO(arena_i_purge)
116-
static int arena_purge(unsigned arena_ind);
116+
static void arena_purge(unsigned arena_ind);
117117
CTL_PROTO(arena_i_dss)
118118
INDEX_PROTO(arena_i)
119119
CTL_PROTO(arenas_bin_i_size)
@@ -1274,35 +1274,27 @@ CTL_RO_NL_CGEN(config_prof, opt_prof_accum, opt_prof_accum, bool)
12741274

12751275
/******************************************************************************/
12761276

1277-
static int
1277+
/* ctl_mutex must be held during execution of this function. */
1278+
static void
12781279
arena_purge(unsigned arena_ind)
12791280
{
1280-
int ret;
1281-
1282-
malloc_mutex_lock(&ctl_mtx);
1283-
{
1284-
VARIABLE_ARRAY(arena_t *, tarenas, ctl_stats.narenas);
1281+
VARIABLE_ARRAY(arena_t *, tarenas, ctl_stats.narenas);
12851282

1286-
malloc_mutex_lock(&arenas_lock);
1287-
memcpy(tarenas, arenas, sizeof(arena_t *) * ctl_stats.narenas);
1288-
malloc_mutex_unlock(&arenas_lock);
1283+
malloc_mutex_lock(&arenas_lock);
1284+
memcpy(tarenas, arenas, sizeof(arena_t *) * ctl_stats.narenas);
1285+
malloc_mutex_unlock(&arenas_lock);
12891286

1290-
if (arena_ind == ctl_stats.narenas) {
1291-
unsigned i;
1292-
for (i = 0; i < ctl_stats.narenas; i++) {
1293-
if (tarenas[i] != NULL)
1294-
arena_purge_all(tarenas[i]);
1295-
}
1296-
} else {
1297-
assert(arena_ind < ctl_stats.narenas);
1298-
if (tarenas[arena_ind] != NULL)
1299-
arena_purge_all(tarenas[arena_ind]);
1287+
if (arena_ind == ctl_stats.narenas) {
1288+
unsigned i;
1289+
for (i = 0; i < ctl_stats.narenas; i++) {
1290+
if (tarenas[i] != NULL)
1291+
arena_purge_all(tarenas[i]);
13001292
}
1293+
} else {
1294+
assert(arena_ind < ctl_stats.narenas);
1295+
if (tarenas[arena_ind] != NULL)
1296+
arena_purge_all(tarenas[arena_ind]);
13011297
}
1302-
1303-
ret = 0;
1304-
malloc_mutex_unlock(&ctl_mtx);
1305-
return (ret);
13061298
}
13071299

13081300
static int
@@ -1313,8 +1305,11 @@ arena_i_purge_ctl(const size_t *mib, size_t miblen, void *oldp, size_t *oldlenp,
13131305

13141306
READONLY();
13151307
WRITEONLY();
1316-
ret = arena_purge(mib[1]);
1308+
malloc_mutex_lock(&ctl_mtx);
1309+
arena_purge(mib[1]);
1310+
malloc_mutex_unlock(&ctl_mtx);
13171311

1312+
ret = 0;
13181313
label_return:
13191314
return (ret);
13201315
}
@@ -1483,7 +1478,8 @@ arenas_purge_ctl(const size_t *mib, size_t miblen, void *oldp, size_t *oldlenp,
14831478
else {
14841479
if (arena_ind == UINT_MAX)
14851480
arena_ind = ctl_stats.narenas;
1486-
ret = arena_purge(arena_ind);
1481+
arena_purge(arena_ind);
1482+
ret = 0;
14871483
}
14881484

14891485
label_return:

0 commit comments

Comments
 (0)