yann@1819: From fa476d01f1c1990a92ee49d1f1c557b83805d0e9 Mon Sep 17 00:00:00 2001 yann@1819: From: Freeman Wang yann@1819: Date: Sat, 19 Dec 2009 13:43:00 -0800 yann@1819: Subject: [PATCH 09/15] malloc: fix race condition and other bugs in the no-mmu malloc yann@1819: yann@1819: Fixes multiple race conditions on mmb list. This was done by yann@1819: making the mmb_heap_lock into a recursive lock and making the yann@1819: regular heap_lock extend to cover the mmb heap handling. yann@1819: yann@1819: Also move the new_mmb allocation up to before the mmb list is yann@1819: iterated through to find the insertion point. When the mmb_heap yann@1819: also runs out and needs to be extended when the regular heap is yann@1819: just extended, the mmb list could be messed up. yann@1819: yann@1819: Signed-off-by: Freeman Wang yann@1819: Signed-off-by: Austin Foxley yann@1819: --- yann@1819: libc/stdlib/malloc/free.c | 6 +++--- yann@1819: libc/stdlib/malloc/malloc.c | 7 ++++--- yann@1819: 2 files changed, 7 insertions(+), 6 deletions(-) yann@1819: yann@1819: diff --git a/libc/stdlib/malloc/free.c b/libc/stdlib/malloc/free.c yann@1819: index 90e18f4..741248a 100644 yann@1819: --- a/libc/stdlib/malloc/free.c yann@1819: +++ b/libc/stdlib/malloc/free.c yann@1819: @@ -179,14 +179,14 @@ __free_to_heap (void *mem, struct heap_free_area **heap yann@1819: /* Start searching again from the end of this block. */ yann@1819: start = mmb_end; yann@1819: yann@1819: + /* Release the descriptor block we used. */ yann@1819: + free_to_heap (mmb, &__malloc_mmb_heap, &__malloc_mmb_heap_lock); yann@1819: + yann@1819: /* We have to unlock the heap before we recurse to free the mmb yann@1819: descriptor, because we might be unmapping from the mmb yann@1819: heap. */ yann@1819: __heap_unlock (heap_lock); yann@1819: yann@1819: - /* Release the descriptor block we used. */ yann@1819: - free_to_heap (mmb, &__malloc_mmb_heap, &__malloc_mmb_heap_lock); yann@1819: - yann@1819: /* Do the actual munmap. */ yann@1819: munmap ((void *)mmb_start, mmb_end - mmb_start); yann@1819: yann@1819: diff --git a/libc/stdlib/malloc/malloc.c b/libc/stdlib/malloc/malloc.c yann@1819: index 71f9e58..84a6acd 100644 yann@1819: --- a/libc/stdlib/malloc/malloc.c yann@1819: +++ b/libc/stdlib/malloc/malloc.c yann@1819: @@ -48,7 +48,7 @@ struct malloc_mmb *__malloc_mmapped_blocks = 0; yann@1819: HEAP_DECLARE_STATIC_FREE_AREA (initial_mmb_fa, 48); /* enough for 3 mmbs */ yann@1819: struct heap_free_area *__malloc_mmb_heap = HEAP_INIT_WITH_FA (initial_mmb_fa); yann@1819: #ifdef HEAP_USE_LOCKING yann@1819: -pthread_mutex_t __malloc_mmb_heap_lock = PTHREAD_MUTEX_INITIALIZER; yann@1819: +pthread_mutex_t __malloc_mmb_heap_lock = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP; yann@1819: #endif yann@1819: #endif /* __UCLIBC_UCLINUX_BROKEN_MUNMAP__ */ yann@1819: yann@1819: @@ -151,19 +151,19 @@ __malloc_from_heap (size_t size, struct heap_free_area **heap yann@1819: /* Try again to allocate. */ yann@1819: mem = __heap_alloc (heap, &size); yann@1819: yann@1819: - __heap_unlock (heap_lock); yann@1819: yann@1819: #if !defined(MALLOC_USE_SBRK) && defined(__UCLIBC_UCLINUX_BROKEN_MUNMAP__) yann@1819: /* Insert a record of BLOCK in sorted order into the yann@1819: __malloc_mmapped_blocks list. */ yann@1819: yann@1819: + new_mmb = malloc_from_heap (sizeof *new_mmb, &__malloc_mmb_heap, &__malloc_mmb_heap_lock); yann@1819: + yann@1819: for (prev_mmb = 0, mmb = __malloc_mmapped_blocks; yann@1819: mmb; yann@1819: prev_mmb = mmb, mmb = mmb->next) yann@1819: if (block < mmb->mem) yann@1819: break; yann@1819: yann@1819: - new_mmb = malloc_from_heap (sizeof *new_mmb, &__malloc_mmb_heap, &__malloc_mmb_heap_lock); yann@1819: new_mmb->next = mmb; yann@1819: new_mmb->mem = block; yann@1819: new_mmb->size = block_size; yann@1819: @@ -177,6 +177,7 @@ __malloc_from_heap (size_t size, struct heap_free_area **heap yann@1819: (unsigned)new_mmb, yann@1819: (unsigned)new_mmb->mem, block_size); yann@1819: #endif /* !MALLOC_USE_SBRK && __UCLIBC_UCLINUX_BROKEN_MUNMAP__ */ yann@1819: + __heap_unlock (heap_lock); yann@1819: } yann@1819: } yann@1819: yann@1819: -- yann@1819: 1.6.6.1 yann@1819: