yann@1819
|
1 |
From fa476d01f1c1990a92ee49d1f1c557b83805d0e9 Mon Sep 17 00:00:00 2001
|
yann@1819
|
2 |
From: Freeman Wang <xwang@ubicom.com>
|
yann@1819
|
3 |
Date: Sat, 19 Dec 2009 13:43:00 -0800
|
yann@1819
|
4 |
Subject: [PATCH 09/15] malloc: fix race condition and other bugs in the no-mmu malloc
|
yann@1819
|
5 |
|
yann@1819
|
6 |
Fixes multiple race conditions on mmb list. This was done by
|
yann@1819
|
7 |
making the mmb_heap_lock into a recursive lock and making the
|
yann@1819
|
8 |
regular heap_lock extend to cover the mmb heap handling.
|
yann@1819
|
9 |
|
yann@1819
|
10 |
Also move the new_mmb allocation up to before the mmb list is
|
yann@1819
|
11 |
iterated through to find the insertion point. When the mmb_heap
|
yann@1819
|
12 |
also runs out and needs to be extended when the regular heap is
|
yann@1819
|
13 |
just extended, the mmb list could be messed up.
|
yann@1819
|
14 |
|
yann@1819
|
15 |
Signed-off-by: Freeman Wang <xwang@ubicom.com>
|
yann@1819
|
16 |
Signed-off-by: Austin Foxley <austinf@cetoncorp.com>
|
yann@1819
|
17 |
---
|
yann@1819
|
18 |
libc/stdlib/malloc/free.c | 6 +++---
|
yann@1819
|
19 |
libc/stdlib/malloc/malloc.c | 7 ++++---
|
yann@1819
|
20 |
2 files changed, 7 insertions(+), 6 deletions(-)
|
yann@1819
|
21 |
|
yann@1819
|
22 |
diff --git a/libc/stdlib/malloc/free.c b/libc/stdlib/malloc/free.c
|
yann@1819
|
23 |
index 90e18f4..741248a 100644
|
yann@1819
|
24 |
--- a/libc/stdlib/malloc/free.c
|
yann@1819
|
25 |
+++ b/libc/stdlib/malloc/free.c
|
yann@1819
|
26 |
@@ -179,14 +179,14 @@ __free_to_heap (void *mem, struct heap_free_area **heap
|
yann@1819
|
27 |
/* Start searching again from the end of this block. */
|
yann@1819
|
28 |
start = mmb_end;
|
yann@1819
|
29 |
|
yann@1819
|
30 |
+ /* Release the descriptor block we used. */
|
yann@1819
|
31 |
+ free_to_heap (mmb, &__malloc_mmb_heap, &__malloc_mmb_heap_lock);
|
yann@1819
|
32 |
+
|
yann@1819
|
33 |
/* We have to unlock the heap before we recurse to free the mmb
|
yann@1819
|
34 |
descriptor, because we might be unmapping from the mmb
|
yann@1819
|
35 |
heap. */
|
yann@1819
|
36 |
__heap_unlock (heap_lock);
|
yann@1819
|
37 |
|
yann@1819
|
38 |
- /* Release the descriptor block we used. */
|
yann@1819
|
39 |
- free_to_heap (mmb, &__malloc_mmb_heap, &__malloc_mmb_heap_lock);
|
yann@1819
|
40 |
-
|
yann@1819
|
41 |
/* Do the actual munmap. */
|
yann@1819
|
42 |
munmap ((void *)mmb_start, mmb_end - mmb_start);
|
yann@1819
|
43 |
|
yann@1819
|
44 |
diff --git a/libc/stdlib/malloc/malloc.c b/libc/stdlib/malloc/malloc.c
|
yann@1819
|
45 |
index 71f9e58..84a6acd 100644
|
yann@1819
|
46 |
--- a/libc/stdlib/malloc/malloc.c
|
yann@1819
|
47 |
+++ b/libc/stdlib/malloc/malloc.c
|
yann@1819
|
48 |
@@ -48,7 +48,7 @@ struct malloc_mmb *__malloc_mmapped_blocks = 0;
|
yann@1819
|
49 |
HEAP_DECLARE_STATIC_FREE_AREA (initial_mmb_fa, 48); /* enough for 3 mmbs */
|
yann@1819
|
50 |
struct heap_free_area *__malloc_mmb_heap = HEAP_INIT_WITH_FA (initial_mmb_fa);
|
yann@1819
|
51 |
#ifdef HEAP_USE_LOCKING
|
yann@1819
|
52 |
-pthread_mutex_t __malloc_mmb_heap_lock = PTHREAD_MUTEX_INITIALIZER;
|
yann@1819
|
53 |
+pthread_mutex_t __malloc_mmb_heap_lock = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
|
yann@1819
|
54 |
#endif
|
yann@1819
|
55 |
#endif /* __UCLIBC_UCLINUX_BROKEN_MUNMAP__ */
|
yann@1819
|
56 |
|
yann@1819
|
57 |
@@ -151,19 +151,19 @@ __malloc_from_heap (size_t size, struct heap_free_area **heap
|
yann@1819
|
58 |
/* Try again to allocate. */
|
yann@1819
|
59 |
mem = __heap_alloc (heap, &size);
|
yann@1819
|
60 |
|
yann@1819
|
61 |
- __heap_unlock (heap_lock);
|
yann@1819
|
62 |
|
yann@1819
|
63 |
#if !defined(MALLOC_USE_SBRK) && defined(__UCLIBC_UCLINUX_BROKEN_MUNMAP__)
|
yann@1819
|
64 |
/* Insert a record of BLOCK in sorted order into the
|
yann@1819
|
65 |
__malloc_mmapped_blocks list. */
|
yann@1819
|
66 |
|
yann@1819
|
67 |
+ new_mmb = malloc_from_heap (sizeof *new_mmb, &__malloc_mmb_heap, &__malloc_mmb_heap_lock);
|
yann@1819
|
68 |
+
|
yann@1819
|
69 |
for (prev_mmb = 0, mmb = __malloc_mmapped_blocks;
|
yann@1819
|
70 |
mmb;
|
yann@1819
|
71 |
prev_mmb = mmb, mmb = mmb->next)
|
yann@1819
|
72 |
if (block < mmb->mem)
|
yann@1819
|
73 |
break;
|
yann@1819
|
74 |
|
yann@1819
|
75 |
- new_mmb = malloc_from_heap (sizeof *new_mmb, &__malloc_mmb_heap, &__malloc_mmb_heap_lock);
|
yann@1819
|
76 |
new_mmb->next = mmb;
|
yann@1819
|
77 |
new_mmb->mem = block;
|
yann@1819
|
78 |
new_mmb->size = block_size;
|
yann@1819
|
79 |
@@ -177,6 +177,7 @@ __malloc_from_heap (size_t size, struct heap_free_area **heap
|
yann@1819
|
80 |
(unsigned)new_mmb,
|
yann@1819
|
81 |
(unsigned)new_mmb->mem, block_size);
|
yann@1819
|
82 |
#endif /* !MALLOC_USE_SBRK && __UCLIBC_UCLINUX_BROKEN_MUNMAP__ */
|
yann@1819
|
83 |
+ __heap_unlock (heap_lock);
|
yann@1819
|
84 |
}
|
yann@1819
|
85 |
}
|
yann@1819
|
86 |
|
yann@1819
|
87 |
--
|
yann@1819
|
88 |
1.6.6.1
|
yann@1819
|
89 |
|