9 Commits
2.2.3 ... 2.2.5

Author SHA1 Message Date
Jason Evans
fc1bb70e5f Merge branch '2_2_5_bp' 2011-11-14 17:15:59 -08:00
Jason Evans
196c7b7e6d Update ChangeLog for 2.2.5. 2011-11-14 17:14:43 -08:00
Jason Evans
f1cc61b93a Fix malloc_stats_print(..., "a") output.
Fix the logic in stats_print() such that if the "a" flag is passed in
without the "m" flag, merged statistics will be printed even if only one
arena is initialized.
2011-11-14 17:14:13 -08:00
Jason Evans
115704dcdb Fix huge_ralloc to maintain chunk statistics.
Fix huge_ralloc() to properly maintain chunk statistics when using
mremap(2).
2011-11-14 17:13:49 -08:00
Jason Evans
03bf7a7a26 Fix huge_ralloc() race when using mremap(2).
Fix huge_ralloc() to remove the old memory region from tree of huge
allocations *before* calling mremap(2), in order to make sure that no
other thread acquires the old memory region via mmap() and encounters
stale metadata in the tree.

Reported by: Rich Prohaska
2011-11-14 17:13:33 -08:00
Jason Evans
d1c526d53b Merge branch '2_2_4_bp' 2011-11-05 21:50:15 -07:00
Jason Evans
45e040a82c Update ChangeLog for 2.2.4. 2011-11-05 21:48:43 -07:00
Jason Evans
dd2cb6484b Fix rallocm() test to support >4KiB pages. 2011-11-05 21:48:27 -07:00
Jason Evans
c87f10a325 Initialize arenas_tsd before setting it.
Reported by: Ethan Burns, Rich Prohaska, Tudor Bosman
2011-11-05 21:48:06 -07:00
8 changed files with 64 additions and 30 deletions

View File

@@ -6,6 +6,21 @@ found in the git revision history:
http://www.canonware.com/cgi-bin/gitweb.cgi?p=jemalloc.git http://www.canonware.com/cgi-bin/gitweb.cgi?p=jemalloc.git
git://canonware.com/jemalloc.git git://canonware.com/jemalloc.git
* 2.2.5 (November 14, 2011)
Bug fixes:
- Fix huge_ralloc() race when using mremap(2). This is a serious bug that
could cause memory corruption and/or crashes.
- Fix huge_ralloc() to maintain chunk statistics.
- Fix malloc_stats_print(..., "a") output.
* 2.2.4 (November 5, 2011)
Bug fixes:
- Initialize arenas_tsd before using it. This bug existed for 2.2.[0-3], as
well as for --disable-tls builds in earlier releases.
- Do not assume a 4 KiB page size in test/rallocm.c.
* 2.2.3 (August 31, 2011) * 2.2.3 (August 31, 2011)
This version fixes numerous bugs related to heap profiling. This version fixes numerous bugs related to heap profiling.

View File

@@ -50,7 +50,7 @@ extern size_t map_bias; /* Number of arena chunk header pages. */
extern size_t arena_maxclass; /* Max size class for arenas. */ extern size_t arena_maxclass; /* Max size class for arenas. */
void *chunk_alloc(size_t size, bool base, bool *zero); void *chunk_alloc(size_t size, bool base, bool *zero);
void chunk_dealloc(void *chunk, size_t size); void chunk_dealloc(void *chunk, size_t size, bool unmap);
bool chunk_boot(void); bool chunk_boot(void);
#endif /* JEMALLOC_H_EXTERNS */ #endif /* JEMALLOC_H_EXTERNS */

View File

@@ -569,7 +569,7 @@ arena_chunk_dealloc(arena_t *arena, arena_chunk_t *chunk)
arena->ndirty -= spare->ndirty; arena->ndirty -= spare->ndirty;
} }
malloc_mutex_unlock(&arena->lock); malloc_mutex_unlock(&arena->lock);
chunk_dealloc((void *)spare, chunksize); chunk_dealloc((void *)spare, chunksize, true);
malloc_mutex_lock(&arena->lock); malloc_mutex_lock(&arena->lock);
#ifdef JEMALLOC_STATS #ifdef JEMALLOC_STATS
arena->stats.mapped -= chunksize; arena->stats.mapped -= chunksize;

View File

@@ -70,7 +70,7 @@ RETURN:
#ifdef JEMALLOC_IVSALLOC #ifdef JEMALLOC_IVSALLOC
if (base == false && ret != NULL) { if (base == false && ret != NULL) {
if (rtree_set(chunks_rtree, (uintptr_t)ret, ret)) { if (rtree_set(chunks_rtree, (uintptr_t)ret, ret)) {
chunk_dealloc(ret, size); chunk_dealloc(ret, size, true);
return (NULL); return (NULL);
} }
} }
@@ -108,7 +108,7 @@ RETURN:
} }
void void
chunk_dealloc(void *chunk, size_t size) chunk_dealloc(void *chunk, size_t size, bool unmap)
{ {
assert(chunk != NULL); assert(chunk != NULL);
@@ -125,15 +125,17 @@ chunk_dealloc(void *chunk, size_t size)
malloc_mutex_unlock(&chunks_mtx); malloc_mutex_unlock(&chunks_mtx);
#endif #endif
if (unmap) {
#ifdef JEMALLOC_SWAP #ifdef JEMALLOC_SWAP
if (swap_enabled && chunk_dealloc_swap(chunk, size) == false) if (swap_enabled && chunk_dealloc_swap(chunk, size) == false)
return; return;
#endif #endif
#ifdef JEMALLOC_DSS #ifdef JEMALLOC_DSS
if (chunk_dealloc_dss(chunk, size) == false) if (chunk_dealloc_dss(chunk, size) == false)
return; return;
#endif #endif
chunk_dealloc_mmap(chunk, size); chunk_dealloc_mmap(chunk, size);
}
} }
bool bool

View File

@@ -110,12 +110,12 @@ huge_palloc(size_t size, size_t alignment, bool zero)
if (offset == 0) { if (offset == 0) {
/* Trim trailing space. */ /* Trim trailing space. */
chunk_dealloc((void *)((uintptr_t)ret + chunk_size), alloc_size chunk_dealloc((void *)((uintptr_t)ret + chunk_size), alloc_size
- chunk_size); - chunk_size, true);
} else { } else {
size_t trailsize; size_t trailsize;
/* Trim leading space. */ /* Trim leading space. */
chunk_dealloc(ret, alignment - offset); chunk_dealloc(ret, alignment - offset, true);
ret = (void *)((uintptr_t)ret + (alignment - offset)); ret = (void *)((uintptr_t)ret + (alignment - offset));
@@ -124,7 +124,7 @@ huge_palloc(size_t size, size_t alignment, bool zero)
/* Trim trailing space. */ /* Trim trailing space. */
assert(trailsize < alloc_size); assert(trailsize < alloc_size);
chunk_dealloc((void *)((uintptr_t)ret + chunk_size), chunk_dealloc((void *)((uintptr_t)ret + chunk_size),
trailsize); trailsize, true);
} }
} }
@@ -234,6 +234,13 @@ huge_ralloc(void *ptr, size_t oldsize, size_t size, size_t extra,
) { ) {
size_t newsize = huge_salloc(ret); size_t newsize = huge_salloc(ret);
/*
* Remove ptr from the tree of huge allocations before
* performing the remap operation, in order to avoid the
* possibility of another thread acquiring that mapping before
* this one removes it from the tree.
*/
huge_dalloc(ptr, false);
if (mremap(ptr, oldsize, newsize, MREMAP_MAYMOVE|MREMAP_FIXED, if (mremap(ptr, oldsize, newsize, MREMAP_MAYMOVE|MREMAP_FIXED,
ret) == MAP_FAILED) { ret) == MAP_FAILED) {
/* /*
@@ -253,9 +260,8 @@ huge_ralloc(void *ptr, size_t oldsize, size_t size, size_t extra,
if (opt_abort) if (opt_abort)
abort(); abort();
memcpy(ret, ptr, copysize); memcpy(ret, ptr, copysize);
idalloc(ptr); chunk_dealloc_mmap(ptr, oldsize);
} else }
huge_dalloc(ptr, false);
} else } else
#endif #endif
{ {
@@ -295,9 +301,10 @@ huge_dalloc(void *ptr, bool unmap)
memset(node->addr, 0x5a, node->size); memset(node->addr, 0x5a, node->size);
#endif #endif
#endif #endif
chunk_dealloc(node->addr, node->size);
} }
chunk_dealloc(node->addr, node->size, unmap);
base_node_dealloc(node); base_node_dealloc(node);
} }

View File

@@ -689,7 +689,7 @@ malloc_init_hard(void)
result = sysconf(_SC_PAGESIZE); result = sysconf(_SC_PAGESIZE);
assert(result != -1); assert(result != -1);
pagesize = (unsigned)result; pagesize = (size_t)result;
/* /*
* We assume that pagesize is a power of 2 when calculating * We assume that pagesize is a power of 2 when calculating
@@ -769,6 +769,14 @@ malloc_init_hard(void)
} }
#endif #endif
if (malloc_mutex_init(&arenas_lock))
return (true);
if (pthread_key_create(&arenas_tsd, arenas_cleanup) != 0) {
malloc_mutex_unlock(&init_lock);
return (true);
}
/* /*
* Create enough scaffolding to allow recursive allocation in * Create enough scaffolding to allow recursive allocation in
* malloc_ncpus(). * malloc_ncpus().
@@ -795,14 +803,6 @@ malloc_init_hard(void)
ARENA_SET(arenas[0]); ARENA_SET(arenas[0]);
arenas[0]->nthreads++; arenas[0]->nthreads++;
if (malloc_mutex_init(&arenas_lock))
return (true);
if (pthread_key_create(&arenas_tsd, arenas_cleanup) != 0) {
malloc_mutex_unlock(&init_lock);
return (true);
}
#ifdef JEMALLOC_PROF #ifdef JEMALLOC_PROF
if (prof_boot2()) { if (prof_boot2()) {
malloc_mutex_unlock(&init_lock); malloc_mutex_unlock(&init_lock);

View File

@@ -748,7 +748,7 @@ stats_print(void (*write_cb)(void *, const char *), void *cbopaque,
ninitialized++; ninitialized++;
} }
if (ninitialized > 1) { if (ninitialized > 1 || unmerged == false) {
/* Print merged arena stats. */ /* Print merged arena stats. */
malloc_cprintf(write_cb, cbopaque, malloc_cprintf(write_cb, cbopaque,
"\nMerged arenas stats:\n"); "\nMerged arenas stats:\n");

View File

@@ -1,6 +1,8 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <unistd.h>
#include <string.h> #include <string.h>
#include <assert.h>
#define JEMALLOC_MANGLE #define JEMALLOC_MANGLE
#include "jemalloc_test.h" #include "jemalloc_test.h"
@@ -8,12 +10,20 @@
int int
main(void) main(void)
{ {
size_t pagesize;
void *p, *q; void *p, *q;
size_t sz, tsz; size_t sz, tsz;
int r; int r;
fprintf(stderr, "Test begin\n"); fprintf(stderr, "Test begin\n");
/* Get page size. */
{
long result = sysconf(_SC_PAGESIZE);
assert(result != -1);
pagesize = (size_t)result;
}
r = JEMALLOC_P(allocm)(&p, &sz, 42, 0); r = JEMALLOC_P(allocm)(&p, &sz, 42, 0);
if (r != ALLOCM_SUCCESS) { if (r != ALLOCM_SUCCESS) {
fprintf(stderr, "Unexpected allocm() error\n"); fprintf(stderr, "Unexpected allocm() error\n");
@@ -66,7 +76,7 @@ main(void)
p = q; p = q;
sz = tsz; sz = tsz;
r = JEMALLOC_P(rallocm)(&q, &tsz, 8192, 0, 0); r = JEMALLOC_P(rallocm)(&q, &tsz, pagesize*2, 0, 0);
if (r != ALLOCM_SUCCESS) if (r != ALLOCM_SUCCESS)
fprintf(stderr, "Unexpected rallocm() error\n"); fprintf(stderr, "Unexpected rallocm() error\n");
if (q == p) if (q == p)
@@ -78,7 +88,7 @@ main(void)
p = q; p = q;
sz = tsz; sz = tsz;
r = JEMALLOC_P(rallocm)(&q, &tsz, 16384, 0, 0); r = JEMALLOC_P(rallocm)(&q, &tsz, pagesize*4, 0, 0);
if (r != ALLOCM_SUCCESS) if (r != ALLOCM_SUCCESS)
fprintf(stderr, "Unexpected rallocm() error\n"); fprintf(stderr, "Unexpected rallocm() error\n");
if (tsz == sz) { if (tsz == sz) {
@@ -88,7 +98,7 @@ main(void)
p = q; p = q;
sz = tsz; sz = tsz;
r = JEMALLOC_P(rallocm)(&q, &tsz, 8192, 0, ALLOCM_NO_MOVE); r = JEMALLOC_P(rallocm)(&q, &tsz, pagesize*2, 0, ALLOCM_NO_MOVE);
if (r != ALLOCM_SUCCESS) if (r != ALLOCM_SUCCESS)
fprintf(stderr, "Unexpected rallocm() error\n"); fprintf(stderr, "Unexpected rallocm() error\n");
if (q != p) if (q != p)
@@ -99,7 +109,7 @@ main(void)
} }
sz = tsz; sz = tsz;
r = JEMALLOC_P(rallocm)(&q, &tsz, 16384, 0, ALLOCM_NO_MOVE); r = JEMALLOC_P(rallocm)(&q, &tsz, pagesize*4, 0, ALLOCM_NO_MOVE);
if (r != ALLOCM_SUCCESS) if (r != ALLOCM_SUCCESS)
fprintf(stderr, "Unexpected rallocm() error\n"); fprintf(stderr, "Unexpected rallocm() error\n");
if (q != p) if (q != p)